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