2017-04-18 33 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语法。

相关问题