仅当条件为真时才进行SQL JOIN

时间:2017-04-18 13:08:05

标签: sql sql-server stored-procedures

我的SQL存储过程中有3个变量,并且只有在第3个变量不为空时才想添加连接。

这就是我尝试这样做的方法,但它不起作用。它在指出的行上给出了以下错误:

  

'{'

附近的语法不正确
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 '%'+@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' OR)

7 个答案:

答案 0 :(得分: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 '%'+@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' OR)

答案 1 :(得分: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

相同

答案 2 :(得分: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 '%'+@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' OR)

答案 3 :(得分: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)

答案 4 :(得分: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 '%'+@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' OR)

答案 5 :(得分:0)

用这个代替IF @three:

$questions

并验证ALTER过程语法和LIKE语法。

答案 6 :(得分:-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 '%'+@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' OR)

尝试写作 喜欢  如果@three IS NOT NULL  更改程序[dbo]。[搜索]     @one NVARCHAR(50),@两个NVARCHAR(50),@ 3rd 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 '%'+@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' OR)

端 其他  更改程序[dbo]。[搜索]     @one NVARCHAR(50),@两个NVARCHAR(50),@ 3rd 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 '%'+@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' OR).. rest code