这个过程有三个参数。 但是,当我试图通过传递参数来执行它显示我的错误。 请帮我。
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”。
这是一个更安全的替代方案:
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';
我是怎么改变?
- 始终使用
dbo
创建/引用对象时的前缀。 - 表名和列名是
NVARCHAR
并且可以长于150个字符。 更安全,允许参数以适应表有人可能会在未来增加。 - 加入
SET NOCOUNT ON
作为对网络开销保护和潜在发送错误的结果集到客户端。 -
@sql
应始终NVARCHAR
。 - 使用
QUOTENAME
围绕实体的名称,如表或列,以帮助阻止SQL注入,也谨防选择不当的名称(例如关键字)。 - 使用适当的参数在可能的情况(再次帮助阻止SQL注入也避免了不得不做的字符串参数的分隔符逃逸的各种)。
你为什么要传递对象名作为参数?
如果您传递字符串值@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