Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Подскажите с синтаксисом триггера  [new]
javaprog
Member

Откуда:
Сообщений: 102
У Кена Хендерсона в книге откат в триггере:
CREATE TRIGGER tr_sales ON dbo.sales
    FOR INSERT, UPDATE
AS
    IF @@ROWCOUNT = 0 
        RETURN
 
    IF ( UPDATE(qty)
         AND ( SELECT   MIN(qty)
               FROM     INSERTED
             ) < 10
       ) 
        BEGIN
            RAISERROR('Minimum order is 10 units', 16, 10)
            ROLLBACK TRAN -- зачем эти строка?
            RETURN -- зачем эти строка?
        END
Должно же хватать RAISERROR?
20 окт 11, 20:35    [11475396]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с синтаксисом триггера  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
javaprog,

RAISERROR работает не так как throw, если у вас не установлен xact_abort.
20 окт 11, 20:46    [11475431]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с синтаксисом триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
javaprog,

1. функция UPDATE() не имеет смысла
2. вместо вычисления минимума лучше
IF EXISTS(SELECT * FROM inserted WHERE qty<10) ...
3. в случае MERGE (SQL2008) @@ROWCOUNT может не быть равным
количеству вставленных или изменённых записей.
Он равен общему количеству записей, затронутых MERGE в целом.
Поэтому универсальнее проверять COUNT(*) FROM inserted
4. RETURN не имеет смысла, если и так достигнут конец триггера.
20 окт 11, 21:38    [11475567]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с синтаксисом триггера  [new]
step_ks
Member

Откуда:
Сообщений: 936
javaprog, raiserror не вызывает прерывания батча или отката.
20 окт 11, 21:43    [11475578]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите с синтаксисом триггера  [new]
javaprog
Member

Откуда:
Сообщений: 102
Спасибо. Разобрался.
20 окт 11, 21:52    [11475620]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Подскажите с синтаксисом триггера  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
SomewhereSomehow
RAISERROR работает не так как throw, если у вас не установлен xact_abort.
Очень важно другое, даже тут 14684798 не было чётко оговорена очень важная часть.
Гость333
Вот честно, не понимаю, что такого можно сделать при помощи THROW, чего нельзя было бы сделать при помощи RAISERROR.
Важная отличительная особенность THROW состоит в том что он прерывает батч при XACT_ABORT в отличие от RAISERROR. Т.е. он полноценная системная ошибка.

Вот всяком случае так говорится в документации.

Но в данном случае, в треггерах это не проблема. Т.к. после выхода из триггера батч то прервётся и без THROW.

Т.е. если лень делать постоянные проверки (при вызове своих процедур) на проброса ошибки наверх (а только в этом случае и надо проверять), то можно выкрутится примерно таким кривым трюком:
+ Код эмуляции Throw для версии ниже 2012
USE tempdb
GO
CREATE TABLE [dbo].[ThrowError] (
	[ID]		BigInt	IDENTITY		CONSTRAINT [PK_ThrowError]	PRIMARY KEY
,	[Message]	NVarChar(4000)	NOT NULL
--,	[Raised]	DateTime	NOT NULL	CONSTRAINT [DF_Raised]		DEFAULT GetDate()
--,	[WithLog]	Bit		NOT NULL	CONSTRAINT [DF_WithLog]		DEFAULT 0
)
GO
CREATE TRIGGER [trThrowError] ON [dbo].[ThrowError]
INSTEAD OF INSERT AS BEGIN
	SET NOCOUNT ON;

	IF (@@Options & 16384 > 0)
	AND(@@TranCount > 0)
		ROLLBACK;

	DECLARE	@Error		NVarChar(4000)
--	,	@WithLog	Bit
	SELECT	@Error	= [Message]
--	,	@WithLog= WithLog
	FROM	inserted

--	IF (@WithLog = 1)
--		INSERT	dbo.ThrowError	([Message],[WithLog])
--		VALUES			(@Error,1)

	RAISERROR('%s',16,1,@Error)
END
GO
SET XACT_ABORT ON;
BEGIN TRAN ThrowError;
--BEGIN TRY
INSERT ThrowError VALUES('TestMessage1')
INSERT ThrowError VALUES('TestMessage2')
-- INSERT ThrowError([Message]) VALUES('TestMessage2')
--END TRY BEGIN CATCH PRINT Error_Message(); END CATCH
GO
-- SELECT * FROM dbo.ThrowError
PRINT @@TranCount; IF (@@TranCount > 0) ROLLBACK;
DROP TABLE [dbo].[ThrowError]
С такой фигнёй вы получаете лишнее сообщение 3609, но которые (ещё для процедур не помню какон) палюбэ надо вырезать из потока ошибок, и встречается фсегда.

PS: Ссори за некроманство.
PPS: Если что-то не так - поправляйте.
PPPS: Может и боян
28 окт 13, 12:16    [15040450]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить