SQL Server 2000 Несколько операторов IF - PullRequest
0 голосов
/ 29 декабря 2010

Я получаю ошибку, когда пытаюсь использовать несколько операторов IF.Это ошибка ...

"Сообщение 156, уровень 15, состояние 1, процедура fnTNAccidentIndicator, строка 81 Неверный синтаксис рядом с ключевым словом" 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 ]

4 голосов
/ 29 декабря 2010

Здесь я вижу довольно много проблем.

  1. У вас есть параметр типа nvarchar без объявленного размера.Когда это происходит, по умолчанию в SQL Server используется 1 символ, что, вероятно, не то, что вам нужно.Я рекомендую вам указать размер.

  2. Ваша функция возвращает nvarchar, но вы не объявили размер.

  3. Вы объявили localпеременные типа nvarchar без объявления размера.

  4. Вы назначаете переменные без использования заданного ключевого слова.SET @ReturnValue = 'Y'

РЕДАКТИРОВАТЬ

  1. Вы передаете @inIndicatorMode как целое число, но затем высравните его с переменной nvarchar.Это заставит SQL Server выполнить преобразование типа перед сравнением.Преобразования типов, как правило, выполняются довольно быстро, но лучше избегать их, когда вы можете.

  2. Кажется, вы жестко кодируете значения только для сравнения.Каждое объявление и присвоение переменной занимают небольшое количество времени для выполнения.Единственное преимущество этого метода - самодокументируемый код.Вместо того, чтобы объявлять переменные, назначать переменные и затем сравнивать эти переменные, я бы предложил изменить сравнение на жестко закодированное значение, а затем использовать комментарии в коде.


IF (@inIndicatorMode = 1) --Alcohol Indicator
 BEGIN
  --select statment   
  IF (@@ROWCOUNT > 0)
  BEGIN
   SET @ReturnValue = 'Y'
  END
 END
  1. Похоже, что из этой процедуры есть только 2 действительных возврата: «N» или «Y».Я бы посоветовал вам немного изменить тип возвращаемых данных.Это позволяет вам писать другой код, который обрабатывает вывод этой функции как логическое значение вместо строки.

  2. В вашем посте вы показываете 3 блока кода.В коде у вас есть комментарий «выберите заявление».Я предполагаю, что каждое утверждение выбора отличается.Вы также, кажется, проверяете @@ RowCount впоследствии, и если количество строк больше 0, вы устанавливаете выход функции на «Y».Вместо этого я бы посоветовал вам использовать функцию Exists.При использовании существует небольшой выигрыш в производительности, поскольку он возвращает значение true, как только SQL находит единственную строку, удовлетворяющую запросу.Например:


IF (@inIndicatorMode = 1) -- Alcohol Indicator
 BEGIN
  If Exists(-- Your select statement Here)
  BEGIN
   SET @ReturnValue = 'Y'
  END
 END
2 голосов
/ 29 декабря 2010

После вашего редактирования. Вы не можете иметь пустой блок begin..end. Он должен содержать что-то, даже если это просто оператор печати или избыточное присвоение.

1 голос
/ 29 декабря 2010

Просто глядя на вашу функцию, я не думаю, что проблема в множественных операторах if.Похоже, проблема в том, что вы делаете @ReturnValue = 'Y' внутри каждого оператора if (забывая SET).Это должно быть:

IF (@@ROWCOUNT > 0)     
BEGIN         
   SET @ReturnValue = 'Y'     
END 

Кроме того, похоже, что вы делаете одно и то же внутри каждого оператора if, вы можете объединить операторы if в один оператор if с OR.

IF (@inIndicatorMode = @AlcoholInd OR @inIndicatorMode = @DrugInd OR @inIndicatorMode = @SpeedInd) 
BEGIN     --select statment        
  IF (@@ROWCOUNT > 0)     
   BEGIN         
     SET @ReturnValue = 'Y'     
   END
END 
...