使用参数执行存储过程

时间:2017-05-14 12:01:18

标签: sql-server sql-server-2008

考虑以下库存过程:

    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 '+@Table1+'.id = '+@Table2+'.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)

4 个答案:

答案 0 :(得分: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 :(得分:1)

尝试:

        DECLARE @sSQL nvarchar(500);

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

        EXEC sp_executesql @sSQL;

    END

答案 2 :(得分:1)

我建议你:

  • QUOTENAME与表名一起使用(如果您在表名中有一些特殊字符,如空格等,则会有所帮助,并且应该有助于SQL注入)
  • aliases(以下示例中为ab
  • 如果您想避免错误,请
  • GO添加到存储过程的末尾(有关详细信息,请参阅此answer):
  

超出最大存储过程,函数,触发器或视图嵌套级别(限制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

而且,也许你需要传递列名。

答案 3 :(得分:0)

我会尝试的方法:

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

   DECLARE @TableOne NVARCHAR(100) = @Table1
   DECLARE @TableTwo NVARCHAR(100) = @Table2
   SET NOCOUNT ON;
   DECLARE @sSQL nvarchar(500);

   SELECT @sSQL = N'SELECT * FROM ' + @TableOne + ' JOIN '+ @TableTwo
   + ' ON '+ @TableOne+'.id = '+ @TableTwo+ '.id_dept';

   EXEC sp_executesql @sSQL;

END

然后当然:

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

我知道的是,在这种情况下,传递数据时对名称进行一些更改始终是一个更好的主意。