2016-01-02 2 views
0

Я пытался найти решение очень простой проблемы, но я просто не могу понять, как это сделать. У меня есть две таблицы Transactions и Credit_Card.SQL Server триггеры для проверки баланса кредитной карты

Сделки

transid (PK), ccid (FK: to credit_card > ccid), amount, timestamp 

CREDIT_CARD

ccid (PK), Balance, creditlimit 

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

"EDIT" Следующий код сосредоточил свой вопрос, большое спасибо Dan Guzman за вклад!

CREATE TRIGGER TR_transactions 
ON transactions FOR INSERT, UPDATE 
AS 
IF EXISTS(
SELECT 1 
FROM (
    SELECT t.ccid, SUM(t.amount) AS amount 
    FROM inserted AS t 
    GROUP BY t.ccid) AS t 
JOIN Credit_Card AS cc ON 
    cc.ccid = t.ccid 
WHERE cc.creditlimit <= (t.amount + cc.balance) 
) 
BEGIN 
RAISERROR('Credit limit exceeded', 16, 1); 
ROLLBACK; 
END; 
+0

, пожалуйста, отредактируйте сообщение с тем, что вы пробовали до сих пор. –

+0

Просьба указать проблему - вы получаете сообщение об ошибке или не работает должным образом? У вас есть тестовый скрипт для воспроизведения проблемы? –

+1

Одна очевидная проблема заключается в том, что, например, таблица 'transaction' будет иметь много записей, но вы попытаетесь загрузить один (случайный) код в' @ ccid'. Это не имеет логического смысла (и, вероятно, дает вам ошибку - ** post it **). Вероятно, вы хотите «вставлен» вместо «транзакций». Делайте что-то по одному за раз, проверяйте каждый шаг, затем переходите к следующему шагу. Также учтите, что триггеры запускаются для ~ всех ~ вставленных строк. У вас может быть 10 строк, вставленных для 10 разных кредитных карт, но только один из них переходит на баланс. Ваш триггер может остановить только ** все ** 10 вставленных записей. –

ответ

-1

вы можете попробовать это.

ALTER триггер [DBO]. [TrigerOnInsertPonches] На [DBO]. [CheckInOut] После вставки Как НАЧАТЬ DECLARE @ccid Int , @ сумма денег

вы должны сказать, что SQL триггер имеет встроенную вставку, , тогда вы можете объявить переменную using. declare

select @ccid=o.ccid from inserted o; 

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

Я надеюсь, что это может быть полезно

+0

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

2

Если я правильно понимаю, вы просто должны проверить кредитный лимит в отношении вновь введенных/обновленных транзакций. Имейте в виду, что триггер SQL Server срабатывает один раз за оператор, и оператор может влиять на несколько строк. На виртуальном inserted будут отображаться изображения затронутых строк. Вы можете использовать это, чтобы ограничить кредитную проверку только кредитными картами, затронутыми связанными транзакциями.

CREATE TRIGGER TR_transactions 
ON transactions FOR INSERT, UPDATE 
AS 
IF EXISTS(
    SELECT 1 
    FROM (
     SELECT inserted.ccid, SUM(inserted.amount) AS amount 
     FROM inserted 
     GROUP BY inserted.ccid) AS t 
    JOIN Credit_Card AS cc ON 
     cc.ccid = t.ccid 
    WHERE cc.creditlimit <= (t.amount + cc.balance) 
    ) 
BEGIN 
    RAISERROR('Credit limit exceeded', 16, 1); 
    ROLLBACK; 
END; 

РЕДАКТИРОВАТЬ я удалил t псевдоним из вставленной таблицы и квалифицированы столбцы с inserted вместо того, чтобы лучше указать источник данных. Как правило, хорошей практикой является определение имен столбцов с именем таблицы или псевдонимом в многозадачных запросах, чтобы избежать двусмысленности.

Целые числа 16 и 1 в операторе RAISERROR указывают степень и состояние поднятой ошибки. См. Ссылку SQL Server Books Online для получения дополнительной информации. Уровень важности 11 и выше вызывает ошибку, с серьезностью в диапазоне от 11 до 16, что указывает на ошибку, исправляемую пользователем.

+0

Большое спасибо, ваш код упростил понимание, хотя я попытался запустить триггер, возвращаемый с помощью «Msg 1011, уровень 16, состояние 1, процедура TR_transactions, строка 4 Имя корреляции« cc »указано несколько раз в предложении FROM». Спасибо за вашу помощь! – Epic117

+0

@ Epic117, я исправил производный псевдоним таблицы. Это должно быть 't', а не' cc'. –

+0

Большое спасибо, все работает по назначению, спасибо, что не торопитесь, помогая мне! – Epic117

Смежные вопросы