繁体   English   中英

通过WHERE子句传递SQL存储过程的整体

[英]Passing SQL stored procedure entirety of WHERE clause

我有一个形式的SQL存储过程

SELECT [fields] FROM [table] WHERE @whereSql

我想向过程传递一个参数(@whereSql),该参数指定整个WHERE子句,但返回以下错误:

An expression of non-boolean type specified in a context where a condition is expected

能做到吗?

简短的答案是您不能这样做-SQL Server将变量的内容视为VALUE。 它不会动态构建要执行的字符串(这就是为什么这是避免SQL注入攻击的正确方法)的原因。

您应该尽一切努力避免动态的WHERE,主要是因为这个原因,也是为了提高效率。 相反,请尝试建立WHERE子句,以便根据情况使具有很多OR的块短路。

如果没有办法解决,您仍然可以根据命令片段构建自己组装的字符串,然后执行它。

因此,您可以这样做:

DECLARE @mywhere VARCHAR(500)
DECLARE @mystmt VARCHAR(1000)
SET @mywhere = ' WHERE MfgPartNumber LIKE ''a%'' '
SELECT @mystmt = 'SELECT TOP 100 * FROM Products.Product AS p ' + @mywhere + ';'
EXEC( @mystmt )

但我建议您这样做:

SELECT TOP 100 * 
    FROM Products.Product AS p 
    WHERE 
        ( MfgPartNumber LIKE 'a%' AND ModeMfrPartNumStartsWith=1)
    OR  ( CategoryID = 123 AND ModeCategory=1 )

我相信可以使用动态SQL来完成。 见下文:

CREATE PROCEDURE [dbo].[myProc]
@whereSql nvarchar(256)

AS
    EXEC('SELECT [fields] FROM [table] WHERE ' + @whereSql)
GO

也就是说,在实际使用动态SQL之前,应该对其进行认真的研究。 快速搜索后,我遇到了一些链接:

确保您已阅读完整

www.sommarskog.se/dynamic_sql.html

某些“答案”中列出的动态SQL绝对是一种解决方案。 但是,如果需要避免使用动态SQL,我更喜欢的解决方案之一是利用表变量(或临时表)在WHERE子句中存储用于比较的参数值。

这是存储过程实现的示例。

CREATE PROCEDURE [dbo].[myStoredProc]
@parameter1 varchar(50)
AS

declare  @myTempTableVar Table(param1 varchar(50))
insert into @myTempTableVar values(@parameter1)

select * from MyTable where MyColumn in (select param1 from @myTempTableVar)

GO

如果要传递多个值,则可以将逗号分隔的值存储为表变量中的行,并以相同的方式用于比较。

CREATE PROCEDURE [dbo].[myStoredProc]
@parameter1 varchar(50)
AS

--Code Block to Convert Comma Seperated Parameter into Values of a Temporary Table Variable
declare  @myTempTableVar Table(param1 varchar(50))
declare @index int =0, @tempString varchar(10)

if charindex(',',@parameter1) > 0
begin
 set @index = charindex(',',@parameter1)
 while @index > 0
  begin
    set @tempString = SubString(@parameter1,1,@index-1)
    insert into @myTempTableVar values (@tempString)
    set @parameter1 = SubString(@parameter1,@index+1,len(@parameter1)-@index)
    set @index = charindex(',',@parameter1)
  end

  set @tempString = @parameter1
  insert into @myTempTableVar values (@tempString)
end
else
insert into @myTempTableVar values (@parameter1)

select * from MyTable where MyColumn in (select param1 from @myTempTableVar)

GO

http://sqlmag.com/t-sql/passing-multivalued-variables-stored-procedure

试试这个,它的工作原理!

CHARINDEX (',' + ColumnName + ',', ',' +
REPLACE(@Parameter, ' ', '') + ',') > 0

执行语法设置@ Parameter ='nc1,nc2'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM