簡體   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