2017-05-14 104 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