SQL Server 2000多个IF语句

时间:2010-12-29 14:42:39

标签: sql sql-server sql-server-2000

当我尝试使用多个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

3 个答案:

答案 0 :(得分:4)

我在这里看到了很多问题。

  1. 您的参数类型为nvarchar,未声明大小。发生这种情况时,SQL Server默认为1个字符,这可能不是您想要的。我鼓励你指定尺寸。

  2. 您的函数返回一个nvarchar,但您没有声明大小。

  3. 您已声明了nvarchar类型的局部变量,但未声明其大小。

  4. 您在不使用设置关键字的情况下分配变量。 SET @ReturnValue ='Y'

  5. 修改

    1. 您将@inIndicatorMode作为整数传入,但随后将其与nvarchar变量进行比较。这将导致SQL Server在比较之前进行类型转换。类型转换通常非常快,但最好尽可能避免它们。

    2. 您似乎只是为了比较而硬编码值。每个声明和变量赋值将花费少量时间来执行。我看到这种方法的唯一优势是自我记录代码。我建议您将比较更改为硬编码值,然后在代码中使用注释,而不是声明变量,分配变量,然后比较这些变量。

    3. 
      IF (@inIndicatorMode = 1) --Alcohol Indicator
       BEGIN
        --select statment   
        IF (@@ROWCOUNT > 0)
        BEGIN
         SET @ReturnValue = 'Y'
        END
       END
      
      1. 好像这个程序只有2个有效回报,'N'或'Y'。我建议您将返回数据类型更改为一点。这允许您编写其他代码,将此函数的输出视为布尔值而不是字符串。

      2. 在您的帖子中,您将显示3个代码块。在代码中,您有“select statement”的注释。我假设每个select语句都不同。之后您似乎也在检查@@ RowCount,如果行计数大于0,则将函​​数的输出设置为“Y”。相反,我鼓励您使用Exists功能。使用exists时会有轻微的性能提升,因为只要SQL找到满足查询的单行,它就会返回true。例如:

      3. 
        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