【问题标题】:sql stored procedure argument as parameter for dynamic querysql 存储过程参数作为动态查询的参数
【发布时间】:2012-07-26 12:31:04
【问题描述】:

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

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”。

【问题讨论】:

  • 您能否确认您正在查找education 表中eduChildName 列包含字符串值'Revathi' 的行,而不是eduChildName 列包含与Revathi 列相同的值?
  • 我删除了我的答案,因为它出于某种原因拉了太多反对票。对不起,baji,你得到的其他答案是你自己的,即使它们没有那么有帮助。

标签: sql-server sql-server-2005 stored-procedures


【解决方案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 注入,但也可以避免对字符串参数进行各种类型的分隔符转义)。

【讨论】:

  • Aaron,我确信 Quotename 将 100% 工作,除非对象名称超过 128 个字符(这种情况很少见)。我只想指出这一点:)
  • @Madhivanan 请告诉我如何创建名称 > 128 个字符的对象(我收到错误消息)。 QUOTENAME 被明确编写用于处理对象名称以及标识符不能超过 128 个字符的理解。
  • 你是对的。我误解了这一点。我看到人们在动态 sql 中使用 Quotename 不仅在对象名称上,而且在值上也使用单引号。就像 Quotename(@v,'''')。当我发布时,我牢记这一点,但错误地指定了对象名称
  • -1 您正在假设有关问题的事情,并否决其他答案,因为不要假设相同的事情。
  • 使用dbo 为对象添加前缀是个好主意,就像使用QUOTENAME 来分隔名称一样。但是,如果您将QUOTENAME 应用于这样的参数,则不应传递带有前缀或you'll end up with a wrong object name 的名称。
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 2015-11-12
    • 2020-07-13
    • 1970-01-01
    相关资源
    最近更新 更多