使用内部联接上的if语句创建存储过程

时间:2013-07-01 20:46:31

标签: sql-server stored-procedures join

我正在尝试创建一个存储过程,该过程将根据参数值执行INNER JOIN代码块。但是,我不断收到“@reSourceID'附近的语法错误。”

if (@VendorID = 11)
    @reSourceID = 't.reSourceID'
if (@VendorID = 5)
    @reSourceID = 't.SourceID'

SELECT      t.ID, fsg.SigCap, fsg.VendorId
FROM        FormCap fsg
    INNER JOIN FlightTrip t
        ON fsg.SourceId = @reSourceID
        AND fsg.VendorId = @VendorID
    INNER JOIN ContractProvider cpu 
        ON t.Id = cpu.VendorId 
WHERE       (t.ID = @FinTransID)
AND     (cpu.userID = @UserID)

任何想法会导致错误?

3 个答案:

答案 0 :(得分:4)

您的语法错误是因为您尚未加入FlightTrip t。您无法在编译的SQL中执行您要执行的操作。您必须创建一个完整的语句varchar变量,然后使用EXEC SP_EXECUTESQL(@Statement)来运行它。

declare @statement nvarchar(4000)

select @statement = '
           SELECT      t.ID, 
                       fsg.SigCap, 
                       fsg.VendorId
           FROM        FormCap fsg
           INNER JOIN  FlightTrip t
           ON          fsg.SourceId = '+convert(nvarchar(100),@reSourceID)+'
           AND         fsg.VendorId = '+convert(nvarchar(100),@VendorID)+'
           INNER JOIN  ContractProvider cpu 
           ON          t.Id = cpu.VendorId 
           WHERE      t.ID = '+convert(nvarchar(100),@FinTransID)+'
           AND       cpu.userID = '''+convert(nvarchar(100),@UserID)+''''

exec sp_executesql @statement

答案 1 :(得分:2)

SELECT      t.ID, fsg.SigCap, fsg.VendorId
FROM        FormCap fsg
    INNER JOIN FlightTrip t
        ON fsg.SourceId = CASE @VendorID
                              WHEN 11 THEN t.reSourceID
                              WHEN  5 THEN t.SourceID
                          END
        AND fsg.VendorId = @VendorID
    INNER JOIN ContractProvider cpu 
        ON t.Id = cpu.VendorId 
WHERE       (t.ID = @FinTransID)
AND     (cpu.userID = @UserID)

答案 2 :(得分:2)

正如Bill回答的那样,optimim解决方案可能会涉及动态SQL,尽管我建议在性能和安全性方面稍微进一步。

如果您对sp_executeSQL的调用进行参数化,那么您将避免转义引号和potential SQL injection problems的问题,但它将允许SQL重用该计划,因为查询文本不会发生变化。

这就是看起来的样子:

if (@VendorID = 11)
    @reSourceID = 't.reSourceID'
if (@VendorID = 5)
    @reSourceID = 't.SourceID'

DECLARE @sql NVARCHAR(MAX)
DECLARE @params NVARCHAR(500)    

SET @sql ='SELECT t.ID, 
                  fsg.SigCap, 
                  fsg.VendorId
           FROM FormCap fsg
               INNER JOIN FlightTrip t
                   ON fsg.SourceId = '+CONVERT(NVARCHAR(MAX),@reSourceID)+'
                       AND fsg.VendorId = @VendorID
               INNER JOIN ContractProvider cpu 
                   ON t.Id = cpu.VendorId 
           WHERE t.ID = @FinTransID
               AND       cpu.userID = @userID'

SET @params = N'@VendorID INT, @FinTransID INT, @userID UNIQUEIDENTIFIER' 

EXECUTE sp_executesql @sql, @params, @venderID = @venderID, @finTransID=@finTransID, @userID = @userID

以上是解决方案的要点,我不完全了解您的类型和输入。此外,没有架构,我无法测试我的代码,但它应该让你继续前进。

有关sp_executesql的更多信息,请msnd is a great resource.