2012-03-26 2 views
1

Я пытаюсь создать хранимую процедуру, которая указывает повышение зарплаты для двух типов сотрудников. Те, у кого выше среднего зарплаты, и те, у кого средняя зарплата ниже средней. И fnHeadCount, и fnAverageSalary - это функции, которые я создал, которые работают и работали в прошлом. Я получаю ошибку со второй частью. В нем указан неправильный синтаксис для знака равенства и 1.4075.«Некорректный синтаксис рядом ...» SQL Stored Proc

Вот код. Я сделал ошибки смелые:

CREATE PROC RAISEA9 
BEGIN 
UPDATE tblEmployeeA9 
SET AnnualSalary=ROUND(1.025*AnnualSalary,2) 
SELECT dbo.fnHeadCount(JobTitle) 
FROM dbo.tblEmployeeA9 
WHERE Active='Y' 
HAVING (dbo.fnHeadCount(JobTitle)-1 >=2) AND (AnnualSalary > dbo.fnAverageSalary(JobTitle)) 
END 

BEGIN 
SET AnnualSalary=ROUND(1.0475*AnnualSalary,2) 
SELECT dbo.fnHeadCount(JobTitle) 
FROM dbo.tblEmployeeA9 
WHERE Active='Y' 
HAVING (dbo.fnHeadCount(JobTitle)-1 >=2) AND (AnnualSalary <= dbo.fnAverageSalary(JobTitle)) 
END 
+0

Я предполагаю, что это SQL-сервер в 'dbo.', но было бы лучше, если бы вы добавили тег с СУБД вы используете (и конкретную версию). –

+0

Я использую Microsoft SQL Server Management Studio. 2000, я считаю. Я не получаю сообщение об ошибке для первой части, но вторая часть на SET, ошибка с равными знаками говорит «Неверный синтаксис рядом с« = », а в 1.0475« Неверный синтаксис рядом с «1.0475». Ожидая SELECT или '(' « – Kendall

ответ

2
CREATE PROC RAISEA9 
BEGIN 

    UPDATE tblEmployeeA9 
    SET AnnualSalary=ROUND(1.025*AnnualSalary,2) 
    -- SELECT HAS TO GO, otherwise Sql Server will update ALL records 
    --SELECT dbo.fnHeadCount(JobTitle) 
    --FROM dbo.tblEmployeeA9 
    WHERE Active='Y' 
    --THERE ARE NO aggregate functions, so HAVING is replaced with AND 
    --HAVING 
    and (dbo.fnHeadCount(JobTitle)-1 >=2) 
    AND (AnnualSalary > dbo.fnAverageSalary(JobTitle)) 
    -- not yet time for END 
    -- END 
    -- And no need for BEGIN either 
    -- BEGIN 
    -- There is UPDATE statement needed 
    UPDATE tblEmployeeA9 
    SET AnnualSalary = ROUND (1.0475 * AnnualSalary,2) 
    -- Again select has no place in UPDATE statement 
    --SELECT dbo.fnHeadCount(JobTitle) 
    --FROM dbo.tblEmployeeA9 
    WHERE Active='Y' 
    -- And HAVING gives place to AND 
    --HAVING 
    AND (dbo.fnHeadCount(JobTitle)-1 >=2) 
    AND (AnnualSalary <= dbo.fnAverageSalary(JobTitle)) 

END 

UPDATE:

Кроме того, в то время как мы находимся на той же странице, как вы стремитесь, чтобы ликвидировать разрыв между богатыми и не очень богатыми, обратите внимание, что первое обновление будет повышать среднюю зарплату за секунду Обновить. Только порядок операций (AnnualSalary>, AnnualSalary < =) избавляет вас от того, чтобы дать кому-то два рейза. два обновления, по существу, то же самое и может быть переписан легко:

SET AnnualSalary = ROUND(AnnualSalary * 
        CASE WHEN AnnualSalary > dbo.fnAverageSalary(JobTitle) 
         THEN 1.025 
         ELSE 1.0475 
         END 
        ,2) 

Конечно, И (AnnualSalary < = dbo.fnAverageSalary (JobTitle)) и И (AnnualSalary < = dbo.fnAverageSalary (JobTitle)) будет удален.

+0

Это имеет смысл :) Большое вам спасибо! – Kendall

1

Похоже, вы забыли UPDATE tablename ...

+0

Кроме того, я думаю, что есть дополнительные' END'/'BEGIN' там – diaho

1

кажется, что вам не хватает оператора UPDATE на втором блоке.

1

В дополнение к ответу @ Nicola вы должны заметить, что ваша процедура выполняет 2 утверждения обновления. В зависимости от того, как и что именно вычисляются dbo.fnAverageSalary(JobTitle) и dbo.fnHeadCount(JobTitle) (независимо от того, используется ли в вычислениях AnnualSalary или нет, и влияют ли изменения, которые выполняет первый оператор обновления, на вычисления второго обновления), у вас могут быть некоторые строки, обновленные обоими или ни один из них. Если вы хотите такого поведения, отлично. Если нет, то вы должны попытаться сделать изменения в одном операторе Update, с чем-то вроде этого:

CREATE PROC RAISEA9 
BEGIN 

    UPDATE dbo.tblEmployeeA9 
    SET AnnualSalary 
     = CASE WHEN (AnnualSalary > dbo.fnAverageSalary(JobTitle)) 
       THEN ROUND(1.025 * AnnualSalary, 2) 
       ELSE ROUND(1.0475 * AnnualSalary, 2) 
      END 
    WHERE Active='Y' 
     AND (dbo.fnHeadCount(JobTitle)-1 >=2) 

END