在SQL Server存储过程中创建动态where子句

时间:2012-08-23 14:21:29

标签: sql-server-2008

我正在尝试创建一个将接受两个值,列名和值的存储。然后,它将检查传入的列名是否存在传入值的记录。我试过以下

CREATE PROCEDURE p_HasActiveReference
     @pi_colName varchar(100)
    ,@pi_colValue varchar(100)
AS
BEGIN
SET NOCOUNT ON      
    declare @sql varchar(1000)

    set @sql = 'IF EXISTS(SELECT TOP 1 p.PaymentId
                FROM Payments p
                WHERE ' + @pi_colName + ' = ' + @pi_colValue +     'AND Active = 1)

                    SELECT ''True'' AS RETVAL
                ELSE
                    SELECT ''False'' AS RETVAL'
    exec(@sql)  
 END

但是,我总是得到这个错误

  将varchar值'InternalOr'转换为数据类型int时,

转换失败。

当我使用以下

调用该过程时
p_HasActiveReference 'InternalOrgCode', '10110'

internalOrgCode列的值为varchar(10)

我不是SQL专家,所以我甚至不确定使用该技术我是否需要实现的目标!

谢谢!

1 个答案:

答案 0 :(得分:2)

至少有一个问题:你应该用单引号包围你的字符串值,并且为了逃避字符串中的那些你需要加倍它们:

WHERE ' + @pi_colName + ' = ''' + @pi_colValue + ''' AND ...

您也可能希望将@sql变量声明为大于100个字符的内容!看起来你的字符串被截断了。

如果@pi_colName的可能值是有限的,那么数据类型总是字符串,并且列是collat​​ion兼容的,你可以做这样的事情并避免使用动态SQL:

SELECT ...
WHERE CASE @pi_colName 
  WHEN 'col1' THEN col1
  WHEN 'col2' THEN col2
END = @pi_ColValue;