2017-04-18 60 views
0

我在我的SQL存儲過程中有3個變量,並且只有在第三個變量不爲空時纔想添加連接。只有在條件爲真時SQL JOIN

這就是我如何去做,但它不工作。它給就行了以下錯誤指出:

附近有語法錯誤 '{'

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
IF @three IS NOT NULL{    **<---------------------** 
LEFT JOIN dbo.Synonym AS synm 
    ON cinfo.ID = synm.ID} 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 
+0

你不能在'TSQL'中這樣做。但是,我們可以編寫查詢以在兩種情況下都得到結果 –

回答

2

實現這一點,你需要給這個條件同時加入。

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
     LEFT JOIN dbo.Synonym AS synm 
    ON (cinfo.ID = synm.ID and @three is not null) **<---------------------** 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 
-3
You cannot use { for if condition just remove '{' 

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
**IF @three IS NOT NULL**   Remove this line 
LEFT JOIN dbo.Synonym AS synm 
    ON cinfo.ID = synm.ID} 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 

嘗試寫 像 IF @three IS NOT NULL ALTER PROCEDURE [dbo]。[Search] @one NVARCHAR(50),@two NVARCHAR(50),@three NVARCHAR(50)

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 

端 別的 ALTER PROCEDURE [DBO]。[搜索] @One NVARCHAR(50),@two NVARCHAR(50),@three NVARCHAR(50)

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
LEFT JOIN dbo.Synonym AS synm 
    ON cinfo.ID = synm.ID} 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR).. rest code 

+0

仍然無效。說:同一行關鍵字'LEFT'附近的語法不正確 – ilmenite

+0

IF語句用於控制流,你不能只是把它放在這樣的查詢中。 –

+0

您不能在當前情況下在中間查詢IF條件。 IF狀態必須包含查詢。例如。如果條件那麼你的聲明 – NEO

2

這是不正確的語法,但是你可以通過幾種方法來實現,最笨的方法是在頂部添加布爾檢查。

IF @three IS NOT NULL 
BEGIN 
--FULL QUERY that JOIN dbo.Synonym 
END 

IF @Three IS NULL 
BEGIN 
--FULL QUERY that does not JOIN dbo.Synonym 
END 

或者你可以使用case..when來控制,它做同樣的事情,多if

0

您可以通過構建動態查詢像下面

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

DECLARE @query varchar(2000)=' SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo Inner JOIN dbo.values AS cval ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc ON (cval.sID = sc.sID AND sc.Accept = ''A'')' 

IF @three IS NOT NULL 
BEGIN 
    SET @query = @query + ' LEFT JOIN dbo.Synonym AS synm ON cinfo.ID = synm.ID ' 
END 

SET @query = @query + 'where (cinfo.NAM LIKE ''%' + @one + '%'' OR cinfo.CAS LIKE ''%' + @two + '%'' OR 
    synm.SynonymID LIKE ''%' + @three + '%'') AND 
    (cval.PropID = ''1'' OR 
    cval.PropID = ''2'' OR 
    cval.PropID = ''3'' OR 
    cval.PropID = ''4'')' 

EXEC(@query) 
+0

這現在已經將這個過程暴露給sql注入。如果這是解決方案,您需要參數化該動態SQL。 –

+0

這已經參數化:) –

+0

不,它不是!這些參數是入站的過程,但是你正在建立一個字符串並執行它。這是一個很常見的誤解。但是如果某個值的值是「'x'',那麼會發生什麼; drop database master; - 」。這段代碼已經打開了這個程序,直到sql注入。 –

4

難道你只是在連接上使用and?連接將被嘗試,但是如果@three爲null,則不會發生與同義詞的連接....或者出於性能原因,您是否真的需要忽略連接?如果是動態SQL是我看得出,使其工作的唯一途徑...

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
LEFT JOIN dbo.Synonym AS synm 
    ON cinfo.ID = synm.ID 
    and @three IS NOT NULL    **<---------------------** 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 
0

什麼:

ALTER PROCEDURE [dbo].[Search] 
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 

SELECT cinfo.ID, 
    cinfo.Nam, 
    cinfo.INAM, 
    cinfo.CA, 
    cinfo.Form, 
    cinfo.Std, 
    cval.Prop, 
    cval.Cons, 
    sc.Accep 

From dbo.Info AS cinfo 
Inner JOIN dbo.values AS cval 
    ON cinfo.ID = cval.ID 
INNER JOIN dbo.Sources AS sc 
    ON (cval.sID = sc.sID AND sc.Accept = 'A') 
LEFT JOIN dbo.Synonym AS synm 
    ON (cinfo.ID = synm.ID AND @three IS NOT NULL) 

where (cinfo.NAM LIKE '%'[email protected]+'%' OR cinfo.CAS LIKE '%'[email protected]+'%' OR 
    synm.SynonymID LIKE '%'[email protected]+'%') AND 
    (cval.PropID = '1' OR 
    cval.PropID = '2' OR 
    cval.PropID = '3' OR 
    cval.PropID = '4' OR) 
0

這種替換如果@three:

LEFT JOIN (select * from dbo.Synonym where @three IS NOT NULL) as synm ON cinfo.ID = synm.ID 

和驗證ALTER過程語法和LIKE語法。

相關問題