2017-05-14 132 views
2

考慮以下放養PROC:執行與參數的存儲過程

CREATE PROCEDURE Test (
    @Table1 NVARCHAR (100), @Table2 NVARCHAR(100)) 
    AS 
BEGIN 

    SET NOCOUNT ON; 
    DECLARE @sSQL nvarchar(500); 

    SELECT @sSQL = N'SELECT * FROM ' + @Table1+' '+ @Table2 
    + 'where '[email protected]+'.id = '[email protected]+'.id_dept'; 

    EXEC sp_executesql @sSQL 

END 

我曾嘗試使用下面的語法來執行它(但我得到一個錯誤):

exec Test @table1='dept', @table2='emp' 

編輯:

使用Gordon Linoff's答案:

alter PROCEDURE Test (
    @Table1 NVARCHAR (100), @Table2 NVARCHAR(100)) 
    AS 
BEGIN 

    SET NOCOUNT ON; 
    DECLARE @sSQL nvarchar(500); 

    SELECT @sSQL = N'SELECT * FROM ' + @Table1 + ' JOIN '+ @Table2 
+ ' ON '+ @Table1+'.id = '+ @Table2+ '.id_dept'; 

EXEC sp_executesql @sSQL; 


END 

,然後將下面給我一個錯誤:

exec Test @table1='dept', @table2='emp'; 

以下是錯誤:

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32) 
+0

您的查詢語法沒有意義。您的'FROM'子句缺少兩個表所需的'JOIN'。 –

+0

那麼,錯誤文本是什麼? –

+1

之前告訴我們的錯誤文本,試加逗號爲'@表1 + ' '+ @ Table2'取代'@表1 +'' + @ Table2'。 –

回答

1

我建議你:

  • 使用QUOTENAME與表名(它會幫助,如果你有在表名一些特殊字符,如空格等,應該幫助與SQL注射)
  • aliases(在下面樣品ab
  • 添加GO到您的存儲過程結束時,如果你想避免的錯誤(見本answer瞭解詳細信息):

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)

所以你的存儲過程批應該是這樣的:

CREATE PROCEDURE Test (
    @Table1 NVARCHAR(100), 
    @Table2 NVARCHAR(100), 
) 
AS 
BEGIN 

    SET NOCOUNT ON; 
    DECLARE @sSQL nvarchar(4000); 

    SET @sSQL = N'SELECT * ' + 
    'FROM ' + QUOTENAME(@Table1) + ' as a ' + 
    'INNER JOIN ' + QUOTENAME(@Table2) + ' as b ' + 
     'ON a.id_dept = b.id_dept'; 

    EXEC sp_executesql @sSQL 

END 
GO 

而且,也許你也需要傳遞列名稱。

1

想必,你想是這樣的:

DECLARE @table1 VARCHAR(255); 
DECLARE @table2 VARCHAR(255); 

SELECT @table1 = 'dept', @table2 = 'emp'; 

SELECT @sSQL = N'SELECT * FROM ' + @Table1 + ' JOIN '+ @Table2 
+ 'ON '+ @Table1+'.id_dept = '+ @Table2+ '.id_dept'; 

EXEC sp_executesql @sSQL; 

你不實際上不需要代碼中的參數定義。我只是把它們放進去,因爲你似乎想要超越傳入存儲過程的值。

你不能使用表(或列或模式或數據庫或功能或運營商名稱)的參數。但是,您可以使用正確,明確的JOIN語法。

+1

如果'QUOTENAME()'來對這些表名構建安全查詢時使用? – alroc

+0

謝謝。現在我得到了'超過了存儲過程,函數,觸發器或視圖的最大嵌套級別(限制32)。'(翻譯) – user7233170

+0

這裏例外的是法語:'消息217,級別16,狀態1,過程sp_executesql,行1 的存儲過程,函數,觸發器的最大嵌套級別,或者超過次(極限32 )。 ' – user7233170

1

嘗試:

 DECLARE @sSQL nvarchar(500); 

     SET @sSQL = N'SELECT * FROM ' + @Table1+' JOIN '+ @Table2 
     + ' ON '[email protected]+'.id_dept = '[email protected]+'.id_dept'; 

     EXEC sp_executesql @sSQL; 

    END