Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在内部联接上使用if语句创建存储过程_Sql Server_Stored Procedures_Join - Fatal编程技术网

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

Sql server 在内部联接上使用if语句创建存储过程,sql-server,stored-procedures,join,Sql Server,Stored Procedures,Join,我正在尝试创建一个存储过程,该过程将基于参数值执行内部联接代码块。然而,我不断地发现“@reSourceID”附近的语法不正确。” 你知道是什么导致了这个错误吗?你的语法错误是因为你还没有真正加入FlightTrip t。在编译后的SQL中,您无法执行您试图执行的操作。您必须创建一个充满语句的varchar变量,然后使用EXEC SP_EXECUTESQL(@statement)运行它 declare @statement nvarchar(4000) select @statement =

我正在尝试创建一个存储过程,该过程将基于参数值执行
内部联接
代码块。然而,我不断地发现“@reSourceID”附近的语法不正确。”


你知道是什么导致了这个错误吗?

你的语法错误是因为你还没有真正加入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

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

如果您参数化对sp_executeSQL的调用,您将避免转义引号的问题,但它将允许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的详细信息,

您不能在T-SQL语句中使用变量作为表名和列名。它们不会被识别-如果您真的必须这样做,您需要求助于动态SQL您的连接没有意义:FlightCap的连接条件仅取决于FormCap中的列,这意味着如果FormCap行匹配,FlightTrip的每一行都将被连接。是的,我尝试过这样做,但是@UserID是一个唯一的标识符,引号往往有点乱,就像我的答案一样,用重复的单引号把它们括起来。应该可以。我仍然收到相同的错误(“在'@reSourceID'附近的语法不正确”)。If语句会有什么问题?在连接字符串时,需要将数字字段转换为字符串类型。与您的UniqueIdentifier相同。错误消息仍然存在。在If语句之间是否需要一个“Begin”和“End”?case语句帮助消除了对If语句的需要,这是导致错误的原因。谢谢。只是出于好奇,如果调用存储过程时对代码进行了参数化,那么在存储过程中进行参数化查询是否是多余的(为了防止SQL注入)?如果您连接字符串和参数,则很可能存在SQL注入漏洞。在您的例子中,可能没有一个字符串,因为您只生成了字符串,其余的是int和uniqueidentifier,但这仍然是一个好习惯。另外,通过参数化的动态sql查询,您还可以获得计划重用的额外好处。
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)
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