Триггер MSSQL: не удалось связать идентификатор из нескольких частей «i.charged_amount» - PullRequest
2 голосов
/ 06 декабря 2010

хорошо, я пытаюсь написать триггер, когда клиент пытается что-то купить, но если он превысит лимит своих кредитных карт, транзакция должна быть отменена.

мои таблицы:
клиенты (имя, ssn, код ),
учетные записи (customer_code, acc_number , баланс, ставка),
кредитная карта (выпущено, срок действия, лимит, баланс, cc_number),
транзакции (дата, cc_number, charge_amount, ** conf_numb ** er, shop_code)

и я написал

create trigger check_balance on transactions
for insert
as
Declare @balance int,
        @limit int
SELECT @balance = balance, @limit = limit
FROM creditcard INNER JOIN inserted i ON creditcard.cc_number = i.cc_number

IF (@balance + i.charged_amount > @limit)
BEGIN

    ROLLBACK TRANSACTION
END

Но я получаю

Сообщение 4104, уровень 16, состояние 1, процедура check_balance, строка 10 Не удалось связать многоэлементный идентификатор «i.charged_amount».где строка 10 - IF (@balance + i.charged_amount> @limit) я знаю, что маска означает, что я не могу использовать i. *, потому что область ее действия только в select..from.я попытался использовать ссылку на новую строку как я, но я получил синтаксическую ошибку около ссылки.Я использую MSSQL server 2005. Я не слишком знаком с триггерами в SQL, поэтому не могли бы вы мне помочь?

Ответы [ 3 ]

5 голосов
/ 06 декабря 2010

Ваше присвоение скалярным переменным не будет работать с многорядными вставками.inserted - таблица, которая может содержать любое количество строк.

insert может даже содержать несколько разных строк для одной и той же кредитной карты, которые по отдельности в порядке, но в совокупности превысят лимит учетной записи.

Логика должна быть примерно такой ...

IF EXISTS
(
SELECT c.cc_number
FROM creditcard c
INNER JOIN inserted i ON c.cc_number = i.cc_number
GROUP BY c.cc_number, c.limit, c.balance
HAVING c.balance + SUM(i.charged_amount) > c.limit
)

ROLLBACK...
3 голосов
/ 06 декабря 2010

попробуйте это:

create trigger check_balance on transactions

for insert
as

IF EXISTS (SELECT 1 
           FROM creditcard 
               INNER JOIN inserted i ON creditcard.cc_number = i.cc_number 
           GROUP BY c.cc_number
           HAVING MIN(creditcard.balance)+SUM(i.charged_amount)>MIN(creditcard.limit)
          )
BEGIN
    raiserror ('bad limit found',16,1)
    ROLLBACK TRANSACTION
    return
END
0 голосов
/ 06 декабря 2010

Я думаю, что проблема в том, что вы пытаетесь использовать псевдоним i, когда он находится только в области действия для запроса, в котором вы его добавили. Пожалуйста, измените ссылку в операторе IF на вставленный вместо i.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...