2012-12-07 93 views
2

使用SQL Server我想將一個字符串注入基於if語句的SQL語句中,請注意,我試圖在存儲過程中完成此操作。SQL Server存儲過程如果語句注入字符串

我目前得到一個錯誤,此代碼:

Declare @topString varchar(240) 

IF @topRecords > 0 
SET @topString = 'top 500' 
ELSE 
SET @topString = '' 

SELECT @topString * FROM(//incorrect syntax near FROM 

SELECT top 500 c.Id as [Customer Id],.... 
    UNION 
    SELECT top 500 c.Id as [Customer Id],.... 
)as table1 
Order by 1 desc 

編輯

if somethingTrue 
@whereCondition = '1 = 1 ' 
else 
@whereCondition = branch = @branch 

select * from table 
where @whereCondition AND etc... 

正確

注射內部的if語句Jodrell
而去如果你需要一個動態的頂部然後按照Kaf的建議行事。
感謝雙方的幫助!

回答

3

您不能將語句部分注入爲這樣的變量,但是您可以更改參數的大部分值。

使存儲過程執行可能需要不同查詢計劃的操作(基於參數是一個壞主意),根據@topRecords參數的值,此SP的結果可能會變化很大。您需要使用RECOMPILE選項來警告查詢引擎,從而減輕SP的很多好處。你有沒有考慮過只有兩個存儲過程?

如果你想動態地做到這一點,你可以動態地構建整個語句,製作一個大字符串,然後執行它。

您應該調查使用sp_executesql執行string/VarChar。然後類似的查詢將從查詢計劃重用中受益。

以前Sommarskog是good reference


像這樣的事情

DECLARE @topString varchar(240); 
DECLARE @statement varchar(max); 

IF @topRecords > 0 
    SET @topString = 'TOP 500'; 
ELSE 
    SET @topString = ''; 

SET @statement = 'SELECT ' + @topString + ' * FROM 
    (
     SELECT TOP 500 c.Id as [Customer Id], .... 
     UNION 
     SELECT TOP 500 c.Id as [Customer Id], .... 
    ) table1 
    ORDER BY 1 DESC' 

/* Then execute @statement */ 
EXEC sp_executesql @statement 
+0

謝謝你的幫助,我很可能會跟你說什麼,但問題是SQL真的很大,所以現在我需要結束無數的單引號...... zzz – rtp

+0

@rtp我不能否認它的痛苦。我嘗試在客戶端執行我的動態SQL,如果您使用.Net,它主要是免費的。 – Jodrell

+0

@Jodrell +1用於閱讀頭腦,並回答原帖中未出現的內容。 – Kaf

4

如果你想decide number of top records depending on @topRecords,您可以在使用INTBIGINT取決於所需的記錄數做。

DECLARE @top INT --This is declared as an int here 

IF @topRecords > 0 
    SET @top = 500 
ELSE 
    SET @top = 5000000 --Make it more than records if you need all 
           --or make it 0 if no records needed. 
           [email protected] has to be >=0 

--How to use it 
SELECT TOP (@top) * FROM YourTable 

編輯:你的問題只有一個頂部注入開始。但是,如果你需要更多的注射(根據你最近的問題編輯),那麼我會建議使用動態查詢按照@Jordell's answer.

+2

+1'Top 0'將不起作用。這返回零行。可以傳遞的最大可能值是bigint'9223372036854775807'。如果這會改變計劃,也可以使用'OPTION(RECOMPILE)'來考慮'TOP'的實際值。 –

+0

@MartinSmith是的,0是沒有記錄。如果他不需要的話。 – Kaf

+0

它確實有效,但在我的SQL 2005測試中,字面值爲變量提供了優越的性能。 – Jodrell

相關問題