当我尝试使用多个IF语句时出错。这是错误...
“Msg 156,Level 15,State 1,Procedure 第81行的fnTNAccidentIndicator 关键字附近的语法不正确 'END'。“
这是我代码的结构......
USE SS_TNRecords_Accident
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION dbo.fnTNAccidentIndicator
(
@inAccidentNumber nvarchar(100),
@inIndicatorMode int
)
RETURNS nvarchar
AS
BEGIN
DECLARE @AlcoholInd nvarchar(1)
DECLARE @DrugInd nvarchar(1)
DECLARE @SpeedInd nvarchar(1)
DECLARE @ReturnValue nvarchar(1)
SET @AlcoholInd = '1'
SET @DrugInd = '2'
SET @SpeedInd = '3'
SET @ReturnValue = 'N'
IF (@inIndicatorMode = @AlcoholInd)
BEGIN
SELECT AccidentNumber, AlcoholTestResult FROM tblAccidentUnit
WHERE AccidentNumber = @inAccidentNumber AND AlcoholTestResult NOT IN('00', '95', '96', '97', '98', '99')
UNION
SELECT AccidentNumber, AlcoholTestResult FROM tblAccidentOccupant
WHERE AccidentNumber = @inAccidentNumber AND AlcoholTestResult NOT IN('00', '95', '96', '97', '98', '99')
UNION
SELECT AccidentNumber, AlcoholTestResult FROM tblAccidentNonMotorist
WHERE AccidentNumber = @inAccidentNumber AND AlcoholTestResult NOT IN('00', '95', '96', '97', '98', '99')
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
END
IF (@inIndicatorMode = @DrugInd)
BEGIN
SELECT a.AccidentNumber,'AccidentUnit' AS TableFound, c.PrimaryKey AS TableKeyValue
FROM tblAccident a INNER JOIN tblAccidentUnit b
ON a.AccidentNumber = b.AccidentNumber INNER JOIN tblAccidentUnitDrug c
ON b.PrimaryKey = c.ForeignKey
AND a.AccidentNumber = '001'
WHERE c.DrugTestResult IN('02', '03', '04', '05', '06', '07', '08', '97', '98')
UNION
SELECT a.AccidentNumber, 'AccidentOccupant' AS TableFound, c.PrimaryKey AS TableKeyValue
FROM tblAccident a INNER JOIN tblAccidentOccupant b
ON a.AccidentNumber = b.AccidentNumber INNER JOIN tblAccidentOccupantDrug c
ON b.PrimaryKey = c.ForeignKey
AND a.AccidentNumber = '001'
WHERE c.DrugTestResult IN('02', '03', '04', '05', '06', '07', '08', '97', '98')
UNION
SELECT a.AccidentNumber, 'AccidentNonMotorist' AS TableFound, c.PrimaryKey AS TableKeyValue
FROM tblAccident a INNER JOIN tblAccidentNonMotorist b
ON a.AccidentNumber = b.AccidentNumber INNER JOIN tblAccidentNonMotoristDrug c
ON b.PrimaryKey = c.ForeignKey
AND a.AccidentNumber = '001'
WHERE c.DrugTestResult IN('02', '03', '04', '05', '06', '07', '08', '97', '98')
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
END
IF (@inIndicatorMode = @SpeedInd)
BEGIN
SELECT a.AccidentNumber,'AccidentUnit' AS TableFound, c.PrimaryKey AS TableKeyValue
FROM tblAccident a INNER JOIN tblAccidentUnit b
ON a.AccidentNumber = b.AccidentNumber INNER JOIN tblAccidentUnitDriverAction c
ON b.PrimaryKey = c.ForeignKey
AND a.AccidentNumber = '001'
WHERE c.DriverAction IN('28', '29')
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
END
Return @ReturnValue
END
GO
答案 0 :(得分:4)
我在这里看到了很多问题。
您的参数类型为nvarchar,未声明大小。发生这种情况时,SQL Server默认为1个字符,这可能不是您想要的。我鼓励你指定尺寸。
您的函数返回一个nvarchar,但您没有声明大小。
您已声明了nvarchar类型的局部变量,但未声明其大小。
您在不使用设置关键字的情况下分配变量。 SET @ReturnValue ='Y'
修改强>
您将@inIndicatorMode作为整数传入,但随后将其与nvarchar变量进行比较。这将导致SQL Server在比较之前进行类型转换。类型转换通常非常快,但最好尽可能避免它们。
您似乎只是为了比较而硬编码值。每个声明和变量赋值将花费少量时间来执行。我看到这种方法的唯一优势是自我记录代码。我建议您将比较更改为硬编码值,然后在代码中使用注释,而不是声明变量,分配变量,然后比较这些变量。
IF (@inIndicatorMode = 1) --Alcohol Indicator
BEGIN
--select statment
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
END
好像这个程序只有2个有效回报,'N'或'Y'。我建议您将返回数据类型更改为一点。这允许您编写其他代码,将此函数的输出视为布尔值而不是字符串。
在您的帖子中,您将显示3个代码块。在代码中,您有“select statement”的注释。我假设每个select语句都不同。之后您似乎也在检查@@ RowCount,如果行计数大于0,则将函数的输出设置为“Y”。相反,我鼓励您使用Exists功能。使用exists时会有轻微的性能提升,因为只要SQL找到满足查询的单行,它就会返回true。例如:
IF (@inIndicatorMode = 1) -- Alcohol Indicator
BEGIN
If Exists(-- Your select statement Here)
BEGIN
SET @ReturnValue = 'Y'
END
END
答案 1 :(得分:2)
关注您的修改。您不能拥有空begin..end
块。即使只是打印语句或冗余分配,它也需要包含某些内容。
答案 2 :(得分:1)
只是看看你的函数,我认为问题不在于多个if语句。看起来问题是你在每个if语句中都在做@ReturnValue ='Y'(忘记SET)。它应该是:
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
此外,看起来你在每个内部做同样的事情,你可以把if语句组合成一个if if。
IF (@inIndicatorMode = @AlcoholInd OR @inIndicatorMode = @DrugInd OR @inIndicatorMode = @SpeedInd)
BEGIN --select statment
IF (@@ROWCOUNT > 0)
BEGIN
SET @ReturnValue = 'Y'
END
END