Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Триггер не тот  [new]
werp
Guest
Задание звучит: при занесении в таблицу сведений о новом магазине проверим, есть ли сведения о нём в таблице. Если нет, то добавляем, если есть то выдаём ошибку и не добавляем.
CREATE TRIGGER Sorts_Ins_Upd
ON  магазины
FOR INSERT
AS
BEGIN TRANSACTION
  DECLARE  @магазины_название nvarchar(255)
  DECLARE  @магазины_адрес nvarchar(255)
  DECLARE  @веб_сайт nvarchar(255)
 IF exists(SELECT название,адрес,[веб-сайт]
          FROM  магазины 
          WHERE (магазины.название = @магазины_название))
        BEGIN 
        ROLLBACK TRANSACTION
        PRINT 'такое имя уже есть в таблице'
       END
  ELSE
      BEGIN
       COMMIT  TRANSACTION
        PRINT  'вставка завершена успешно'
     END

Добавлять то добавляет, а вот при сравнении одинаковых выдаёт ошибку :
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'aaaaaмагазины_PK'. Cannot insert duplicate key in object 'dbo.магазины'.
The statement has been terminated.
2 окт 11, 14:07    [11369665]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
срочно читайте справку. там всё очень доступно написано.

З.Ы.
какое значение, во-вашему, у переменной @магазины_название ?
2 окт 11, 14:12    [11369671]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
ё
Guest
werp
Задание звучит: при занесении в таблицу сведений о новом магазине проверим, есть ли сведения о нём в таблице. Если нет, то добавляем, если есть то выдаём ошибку и не добавляем.
CREATE TRIGGER Sorts_Ins_Upd
ON  магазины
FOR INSERT
AS
BEGIN TRANSACTION
  DECLARE  @магазины_название nvarchar(255)
  DECLARE  @магазины_адрес nvarchar(255)
  DECLARE  @веб_сайт nvarchar(255)
 IF exists(SELECT название,адрес,[веб-сайт]
          FROM  магазины 
          WHERE (магазины.название = @магазины_название))
        BEGIN 
        ROLLBACK TRANSACTION
        PRINT 'такое имя уже есть в таблице'
       END
  ELSE
      BEGIN
       COMMIT  TRANSACTION
        PRINT  'вставка завершена успешно'
     END

Добавлять то добавляет, а вот при сравнении одинаковых выдаёт ошибку :
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'aaaaaмагазины_PK'. Cannot insert duplicate key in object 'dbo.магазины'.
The statement has been terminated.

BEGIN TRANSACTION - не нужен
COMMIT TRANSACTION - тоже

с чем вы тут сравниваете
          WHERE (магазины.название = @магазины_название))
если @магазины_название - ничего не присвоенно ?

...даа и вообще, триггер тут не нужен
достаточно было бы уник.констрейнта на "название"
2 окт 11, 14:15    [11369675]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
Glory
Member

Откуда:
Сообщений: 104751
werp
Добавлять то добавляет, а вот при сравнении одинаковых выдаёт ошибку :
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'aaaaaмагазины_PK'. Cannot insert duplicate key in object 'dbo.магазины'.
The statement has been terminated.

Это ошибка вообще то проверки констрейнта ДО срабатывания триггера
2 окт 11, 14:19    [11369682]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
werp
Guest
Зайцев Фёдор
ё
BEGIN TRANSACTION - не нужен
COMMIT TRANSACTION - тоже

с чем вы тут сравниваете
          WHERE (магазины.название = @магазины_название))
если @магазины_название - ничего не присвоенно ?

...даа и вообще, триггер тут не нужен
достаточно было бы уник.констрейнта на "название"


Необходимо реализовать именно через триггер.
Потом же отдельно добавляю строкой :
INSERT INTO магазины(название,адрес,[веб-сайт])
VALUES ('Гоглаярррр', 'ул.Гербса 274','www.uyрer.ru')

Glory А как избежать то этой ошибки?
2 окт 11, 14:54    [11369741]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
Glory
Member

Откуда:
Сообщений: 104751
werp
Glory А как избежать то этой ошибки?

Зачем вам триггер, если вы уже создали ПК, который делают эту же проверку ?
И наоборот, если "Необходимо реализовать именно через триггер", то почему создан ПК, который уже делают эту же проверку ?
2 окт 11, 15:02    [11369758]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8880
Триггер instead и, если проверка пройдена успешно (т.е. магазина нет такого) - то вставлять запись в триггере.
2 окт 11, 15:15    [11369788]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
SIMPLicity_
Триггер instead и, если проверка пройдена успешно (т.е. магазина нет такого) - то вставлять запись в триггере.
werp не знает даже что такое "инициализация переменной"
и избегает ответа на вопрос "чему же равно @магазины_название?"
Какой уж тут INSTEAD OF INSERT...

werp, маленький совет: забудьте в триггере о существовании переменных
и узнайте о псевотаблицах inserted и deleted!

И начните с чтения документации о триггерах:
http://msdn.microsoft.com/ru-ru/library/ms189799(v=SQL.100).aspx
http://msdn.microsoft.com/ru-ru/library/ms191300(v=SQL.100).aspx
2 окт 11, 15:59    [11369862]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
werp
Guest
[/quot]werp не знает даже что такое "инициализация переменной"
и избегает ответа на вопрос "чему же равно @магазины_название?"
Какой уж тут INSTEAD OF INSERT...

werp, маленький совет: забудьте в триггере о существовании переменных
и узнайте о псевотаблицах inserted и deleted![/quot]
Сделал через INSTEAD OF, но получилась каша какая-то. Странно что вообще работает.
Теперь, как эту кашу привести в нормальный и короткий вид? :D
CREATE TRIGGER Sorts_Ins_Upd
ON  магазины
INSTEAD OF INSERT
AS
BEGIN TRANSACTION
  DECLARE  @магазины_название nvarchar(255)
  DECLARE  @магазины_адрес nvarchar(255)
  DECLARE  @магазины_вебсайт nvarchar(255)
SELECT  @магазины_название = i.название 
     FROM  inserted i
SELECT  @магазины_адрес = i.адрес
     FROM  inserted i
SELECT  @магазины_вебсайт = i.вебсайт
     FROM  inserted i
 IF exists(SELECT название
        FROM  магазины 
        WHERE (магазины.название = @магазины_название))
       BEGIN 
        ROLLBACK TRANSACTION BEGIN TRANSACTION
        PRINT 'такое имя уже есть в таблице'
       END
  ELSE
      BEGIN
       PRINT  'вставка завершена успешно'
       INSERT INTO магазины
       VALUES (@магазины_название,@магазины_адрес,@магазины_вебсайт)
       COMMIT TRAN
     END

И при удачном добавлении записи дублируется (1 row(s) affected), как избежать этого?
2 окт 11, 21:59    [11370793]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

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

В триггере убери инсерт, тогда дублироваться не будут.
2 окт 11, 22:58    [11371030]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
SELECT  @магазины_название = i.название 
     FROM  inserted i
SELECT  @магазины_адрес = i.адрес
     FROM  inserted i
SELECT  @магазины_вебсайт = i.вебсайт
     FROM  inserted i

можно так
SELECT  @магазины_название = i.название,  @магазины_адрес = i.адрес, @магазины_вебсайт = i.вебсайт
FROM  inserted i
2 окт 11, 23:13    [11371110]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iljy
Member

Откуда:
Сообщений: 8711
werp
Теперь, как эту кашу привести в нормальный и короткий вид? :D

Стереть ее к чертовой матери, после чего открыть учебник и прочитать про то, что inserted - это таблица, которая может содержать произвольное количество записей, что в списке SELECT может быть больше одного выражения, что существует форма INSERT ... SELECT, ну и прочие интересные вещи.
2 окт 11, 23:14    [11371113]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
werp
Guest
trew
werp,

В триггере убери инсерт, тогда дублироваться не будут.


Благодарю. Реально, оказался лишний кусок кода.
2 окт 11, 23:19    [11371130]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

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

подскажи, а в триггере (в самом начале) пишется
SET NOCOUNT ON
или нет?

А то я прочитал, что нужно добавлять в процедуры, для быстродействия (чтобы такие строки не возвращал сервер
1 row(s) affected)
2 окт 11, 23:40    [11371197]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iljy
Member

Откуда:
Сообщений: 8711
werp
trew
werp,

В триггере убери инсерт, тогда дублироваться не будут.


Благодарю. Реально, оказался лишний кусок кода.

Т.е. вы хотите сказать, что в триггере INSTEAD OF INSERT собственно код вставки записи в таблицу оказался лишним?? Круто!
2 окт 11, 23:51    [11371225]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iljy
Member

Откуда:
Сообщений: 8711
trew
iljy,

подскажи, а в триггере (в самом начале) пишется
SET NOCOUNT ON
или нет?

А то я прочитал, что нужно добавлять в процедуры, для быстродействия (чтобы такие строки не возвращал сервер
1 row(s) affected)

Быстродействия это добавляет не сильно, а вот лишнюю выдачу подавляет. Некоторые клиентские среды не особо адеватно реагируют на лишние рекордсеты. Так что писать это очень желательно.
2 окт 11, 23:53    [11371227]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
werp
Guest
iljy да то про select'ы было :))
Спасибо за объективную критику и советы.
3 окт 11, 00:13    [11371292]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
автор
Т.е. вы хотите сказать, что в триггере INSTEAD OF INSERT собственно код вставки записи в таблицу оказался лишним?? Круто!
Раз iljy критикует, значити какой-то косяк есть

CREATE TRIGGER Sorts_Ins_Upd
ON  магазины
INSTEAD OF INSERT
AS
if ... при занесении в таблицу сведений о новом магазине проверим, есть ли сведения о нём в таблице
begin
RAISERROR('такое имя уже есть в таблице',16,1)
return
end
Так верно будет? (с учетом замечаний 11204238)
3 окт 11, 00:31    [11371363]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iljy
Member

Откуда:
Сообщений: 8711
trew,

вы понимаете, что такое триггер INSTEAD OF INSERT?
3 окт 11, 09:29    [11371758]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

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

Не совсем понятно
автор
INSTEAD OF
Указывает, что триггер DML срабатывает вместо инструкции SQL, используемой триггером, переопределяя таким образом действия выполняемой инструкции триггера.

Ясно только, что он срабатывает до вставки в таблицу данных т.е. в нем можно проверить некое условие.

Если я написал триггер INSTEAD OF, значит инсерта в таблицу не будет, если внутри триггера нет инсерта. Верно?
3 окт 11, 09:58    [11371893]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
trew
iljy,

Не совсем понятно
автор
INSTEAD OF
Указывает, что триггер DML срабатывает вместо инструкции SQL, используемой триггером, переопределяя таким образом действия выполняемой инструкции триггера.

Ясно только, что он срабатывает до вставки в таблицу данных т.е. в нем можно проверить некое условие.

Если я написал триггер INSTEAD OF, значит инсерта в таблицу не будет, если внутри триггера нет инсерта. Верно?
Он выполняется ВМЕСТО ВСТАВКИ, УДАЛЕНИЯ, МОДИФИКАЦИИ данных (смотря что там после OF)
Само действие, запустившее триггер, не выполняется!
3 окт 11, 10:03    [11371908]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

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

Крупными буквами понятней! (хотя в хелпе тоже самое) Спасибо, начинаю понимать.
Значит в код, который я написал нужно добавить else insert в таблицу.
3 окт 11, 10:12    [11371951]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
trew
Member

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

а в каком случае здесь 11370793 записи могли дублироваться? (не понятно)
Только когда в inserted попадает несколько записей ?

Так уже такой код
SELECT  @магазины_название = i.название FROM  inserted i
должен показать ошибку т.к. переменной пытаются присвоить несколько значений.
3 окт 11, 10:20    [11371994]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
trew
iap,

Крупными буквами понятней! (хотя в хелпе тоже самое) Спасибо, начинаю понимать.
Значит в код, который я написал нужно добавить else insert в таблицу.
Вроде там у Вас и так RETURN.
Зачем же ELSE?

Но всё это коряво как-то выглядит.
Повторяю: от скалярных переменных в триггере почти всегда один вред!
3 окт 11, 10:21    [11372001]     Ответить | Цитировать Сообщить модератору
 Re: Триггер не тот  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
trew
Так уже такой код
SELECT  @магазины_название = i.название FROM  inserted i
должен показать ошибку т.к. переменной пытаются присвоить несколько значений.
Согласно документации переменной присвоится последнее значение, возвращённое SELECTом
без всяких сообщений.
Без ORDER BY это будет значение из какой-то произвольной строки.
Ошибку в случае нескольких строк в inserted вернёт такая конструкция:
SET @магазины_название=(SELECT название FROM inserted);
3 окт 11, 10:25    [11372019]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить