SQL存储过程参数作为参数为动态查询(sql stored procedure argument a

2019-09-20 06:37发布

这个过程有三个参数。 但是,当我试图通过传递参数来执行它显示我的错误。 请帮我。

create procedure queryfunctions @Tabname varchar(150),@colname varchar(150),@valuesname varchar(150)
as
begin
declare @sql varchar(4000)
select @sql='select * from @Tabname where @colname=@valuesname'
exec(@sql)
end

exec queryfunctions 'education','eduChildName','Revathi'

错误:

消息1087,级别15,状态2,行1必须声明表变量“@tabname”。

Answer 1:

这是一个更安全的替代方案:

ALTER PROCEDURE dbo.queryfunctions 
  @Tabname NVARCHAR(511),
  @colname NVARCHAR(128),
  @valuesname VARCHAR(150)
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @sql NVARCHAR(MAX);

  SET @sql = 'SELECT * FROM ' + @Tabname 
           + ' WHERE ' + QUOTENAME(@colname) + ' = @v';

  EXEC sp_executesql @sql, N'@v VARCHAR(150)', @valuesname;
END
GO

EXEC dbo.queryfunctions N'dbo.education', N'eduChildName', 'Revathi';

我是怎么改变?

  1. 始终使用dbo创建/引用对象时的前缀。
  2. 表名和列名是NVARCHAR并且可以长于150个字符。 更安全,允许参数以适应表有人可能会在未来增加。
  3. 加入SET NOCOUNT ON作为对网络开销保护和潜在发送错误的结果集到客户端。
  4. @sql应始终NVARCHAR
  5. 使用QUOTENAME围绕实体的名称,如表或列,以帮助阻止SQL注入,也谨防选择不当的名称(例如关键字)。
  6. 使用适当的参数在可能的情况(再次帮助阻止SQL注入也避免了不得不做的字符串参数的分隔符逃逸的各种)。


Answer 2:

你为什么要传递对象名作为参数?

如果您传递字符串值@valuesname,你的代码应该是

create procedure queryfunctions 
(
@Tabname varchar(150),@colname varchar(150),@valuesname varchar(150) 
)
as 
begin 
declare @sql varchar(4000) 
select @sql='select * from '+@Tabname+' where '+@colname+'='''+@valuesname+'''' 
exec(@sql) 
end 

不知道如何在动态SQL使用单引号? 请参阅本http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx



文章来源: sql stored procedure argument as parameter for dynamic query