0

我正在尝试创建一个存储过程,它将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)

有什么想法会导致错误吗?

4

3 回答 3

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
于 2013-07-01T20:50:04.213 回答
2

正如比尔回答的那样,最佳解决方案可能会涉及动态 SQL,尽管我建议在性能和安全性方面走得更远一些。

如果您参数化您对 sp_executeSQL 的调用,您将避免转义引号问题和潜在的 SQL 注入问题,但由于查询文本不会更改,它将允许 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 是一个很好的资源。

于 2013-07-01T22:03:42.423 回答
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)
于 2013-07-01T21:50:00.863 回答