sql存储过程条件where子句返回语法错误

时间:2017-11-17 13:07:52

标签: sql-server tsql stored-procedures sql-server-2014

我有以下存储过程,它有2个参数。 @Class参数可以包含11个值中的任何一个。取决于where子句查看不同列的值。

该过程编译好,如果我复制打印并将其粘贴到新的查询窗口,它运行正常,但如果我执行该过程,我得到一个不正确的语法错误消息附近'布里斯托尔'但无论如何在这里和其他网页上查看,我都无法弄清楚我需要做些什么来修复。任何帮助将不胜感激

ALTER PROCEDURE [TTR_HazDriver]
@Depot nvarchar(50),
@Class nvarchar(1)

AS
BEGIN
DECLARE @Where nvarchar(1000)
DECLARE @sSql nvarchar(MAX)
DECLARE @Order nvarchar(1000)

SET @sSql = '
SELECT EM.EmployeeNumber
, EM.EmployeeSurname
, EM.EmployeeInitials
, D.Depot
, EDL.Class1
, EDL.Class2
, EDL.Class3
, EDL.Class4
, EDL.Class5
, EDL.Class6
, EDL.Class7
, EDL.Class8
, EDL.Class9
, CONVERT(VARCHAR(10),EDL.ExpiryDate, 103) ExpiryDate
, EDL.Tanks
, EDL.Package
FROM   EmployeeMaster EM 
LEFT OUTER JOIN PayrollFrequency PF ON EM.FrequencyDesc = PF.DescCode 
INNER JOIN EmployeeDrivingLicence EDL ON EM.EmpCode = EDL.EmpCode 
LEFT OUTER JOIN Depot D ON EM.Depot = D.DescCode'

SET @Where = '
WHERE (D.Depot = ''' + @Depot + ''' OR ''' + @Depot + ''' IS NULL)
AND EM.EmployeeLeft = ''N''
AND PF.FrequencyDesc = ''Weekly'''



SET @Order = '
    ORDER BY D.DepotDepotDescription
    , EDL.ExpiryDate'

IF @Class = '1' 
SET @Where = @Where + ' AND EDL.Class1 = ''Y'''
IF @Class = '2' 
SET @Where = @Where + ' AND EDL.Class2 = ''Y'''
IF @Class = '3' 
SET @Where = @Where + ' AND EDL.Class3 = ''Y'''
IF @Class = '4' 
SET @Where = @Where + ' AND EDL.Class4 = ''Y'''
IF @Class = '5' 
SET @Where = @Where + ' AND EDL.Class5 = ''Y'''
IF @Class = '6' 
SET @Where = @Where + ' AND EDL.Class6 = ''Y'''
IF @Class = '7' 
SET @Where = @Where + ' AND EDL.Class7 = ''Y'''
IF @Class = '8' 
SET @Where = @Where + ' AND EDL.Class8 = ''Y'''
IF @Class = '9' 
SET @Where = @Where + ' AND EDL.Class9 = ''Y'''
IF @Class = 'T' 
SET @Where = @Where + ' AND EDL.Tanks = ''Y'''
IF @Class = 'P' 
SET @Where = @Where + ' AND EDL.Package = ''Y'''


SET @sSql = @sSql + @Where + @Order
PRINT @sSql

EXEC sp_executesql @sSQL, @Depot, @Class
END

print语句产生以下查询:

SELECT EM.EmployeeNumber
 , EM.EmployeeSurname
 , EM.EmployeeInitials
 , D.Depot
 , EDL.Class1
 , EDL.Class2
 , EDL.Class3
 , EDL.Class4
 , EDL.Class5
 , EDL.Class6
 , EDL.Class7
 , EDL.Class8
 , EDL.Class9
 , CONVERT(VARCHAR(10),EDL.ExpiryDate, 103) ExpiryDate
 , EDL.Tanks
 , EDL.Package
 FROM   EmployeeMaster EM 
 LEFT OUTER JOIN PayrollFrequency PF ON EM.FrequencyDesc = PF.DescCode 
 INNER JOIN EmployeeDrivingLicence EDL ON EM.EmpCode = EDL.EmpCode 
 LEFT OUTER JOIN Depot D ON EM.DepotDepotDescription = D.DescCode
 WHERE (D.DepotDepotDescription = 'Bristol' OR 'Bristol' IS NULL)
 AND PF.FrequencyDesc = 'Weekly'
 AND EDL.Class3 = 'Y'
    ORDER BY D.Depot
    , EDL.ExpiryDate

1 个答案:

答案 0 :(得分:1)

由于您将参数值嵌入到查询变量中,因此无需将参数添加到sp_executesql调用中,因此这应该有效:

EXEC sp_executesql @sSQL

而不是:

EXEC sp_executesql @sSQL, @Depot, @Class

这是一个使用DDL语句的完整工作示例 - 用原始版本换掉最后一行,你会得到语法错误。

CREATE TABLE EmployeeMaster (EmployeeNumber INT, EmployeeSurname VARCHAR(25), EmployeeInitials VARCHAR(10), FrequencyDesc VARCHAR(25), EmpCode VARCHAR(25), Depot VARCHAR(25), EmployeeLeft VARCHAR(1))
CREATE TABLE PayrollFrequency (DescCode VARCHAR(25), FrequencyDesc VARCHAR(25))
CREATE TABLE EmployeeDrivingLicence (EmpCode VARCHAR(25), Class1 VARCHAR(1), Package VARCHAR(1), Tanks VARCHAR(1))
ALTER TABLE EmployeeDrivingLicence ADD ExpiryDate DATETIME
CREATE TABLE Depot (Depot VARCHAR(25), DescCode VARCHAR(25), DepotDepotDescription VARCHAR(25))

CREATE PROCEDURE [TTR_HazDriver]
@Depot nvarchar(50),
@Class nvarchar(1)

AS
BEGIN

...

EXEC sp_executesql @sSQL
END
GO

EXEC [TTR_HazDriver] 'test', 'P'
相关问题