5

此过程具有三个参数。但是当我尝试通过传递参数来执行时,它会显示一个错误。请帮我。

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'

错误 :

Msg 1087, Level 15, State 2, Line 1 必须声明表变量“@Tabname”。

4

2 回答 2

15

这是一个更安全的选择:

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 注入,但也避免必须对字符串参数执行各种转义分隔符)。
于 2012-07-26T12:44:55.107 回答
-3

为什么将对象名称作为参数传递?

如果您将字符串值传递给@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

于 2012-07-26T12:53:14.883 回答