I have 3 variables in my SQL stored procedure and want to add a join only if the 3rd variable is not null.
This is how i am trying to do it but it doesn't work. It gives the following error on the line pointed out:
Incorrect syntax near '{'
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)
Couldn't you just use an and
on the join? The join will be attempted but if @three is null then no joins to synonym would occur.... or do you really need to ignore the join for performance reasons? if so Dynamic SQL is the only way I could see to make it work...
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)
This is not correct syntax, but you could do achieve this in few ways, the dumbest way to do is add the Boolean check on the top.
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
Or you could use case..when
to control, it does the same thing as multiple if
You need to give that condition while joining itself.
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)
You can achieve this by building dynamic query like following
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)
What about:
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)
replace IF @three with this :
LEFT JOIN (select * from dbo.Synonym where @three IS NOT NULL) as synm ON cinfo.ID = synm.ID
and verify ALTER procedure syntax and LIKE syntax.
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)
Try to write Like 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 '%'+@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)
end else 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}
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
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.