2017-11-17 7 views
0

私は2つのパラメータを取る以下のストアドプロシージャを持っています。 @Classパラメーターは11の値のいずれか1つを持つことができます。値に応じて、where句は別の列を参照します。sqlストアドプロシージャ条件文節エラーを返す節

プロシージャをコンパイルすると、印刷して新しいクエリーウィンドウに貼り付けても問題なく実行されますが、プロシージャを実行すると、「Bristol」の近くに不正な構文エラーメッセージが表示されますが、ここや他のウェブページを見ていても修正する必要があります。すべてのヘルプははるかに

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 
+2

生成されたクエリは、ストアドプロシージャのコードと一致しません。 'EM.EmployeeMasterLeft'はどこから来たのですか?' FrequencyDesc'?、 'EDL.ExpiryDate> = {ts '2007-01-01 00:00:00'}'? –

+0

適切なソフトウェア(MySQL、Oracle、DB2など)とバージョンの両方でデータベースの質問にタグを付けると便利です。 'sql-server-2014'です。構文と機能の相違は、しばしば答えに影響します。 'tsql'は選択肢を絞り込みますが、データベースは指定しないことに注意してください。 – HABO

+0

元のコードを編集しました –

答えて

1

クエリ変数にパラメータ値を埋め込むしているので、あなたがのparamsを追加する必要はありませんsp_executesqlを呼び出しに、これは動作するはずです:

EXEC sp_executesql @sSQL 

の代わりに:

を210

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' 
+0

影響を与えません。 –

+0

@Max Szczurekありがとうございました –