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

Откуда: NY USA
Сообщений: 351
Иногда нужно передать переменную типа UserID или ModificationId из процедуры в тригер, что бы тригер вставил это а архивную таблицу вместе с изменённой запись. Напрямую это сделать нельзя, но вот через временную таблицу можно.
IF (OBJECT_ID('dbo.TestTbl') IS NOT NULL) 
BEGIN
       DROP TABLE dbo.TestTbl;
END
IF (OBJECT_ID('dbo.Foo') IS NOT NULL) 
BEGIN
       DROP PROCEDURE dbo.Foo;
END
GO
CREATE TABLE dbo.TestTbl (TestTblID INT, TestTblDate DATETIME);
GO
INSERT INTO dbo.TestTbl (TestTblID, TestTblDate) VALUES (1, CURRENT_TIMESTAMP);
GO
CREATE PROCEDURE dbo.Foo (@WebUserID INT)
AS
SET NOCOUNT ON;

CREATE TABLE #tbl (UserID INT);

INSERT INTO #tbl (UserID) VALUES (@WebUserID);

UPDATE dbo.TestTbl
   SET TestTblDate = CURRENT_TIMESTAMP
      WHERE TestTblID = 1;

DROP TABLE #tbl ;
GO

CREATE TRIGGER dbo.TR_TestTbl_IUD ON dbo.TestTbl
AFTER INSERT, UPDATE, DELETE 
AS
SET NOCOUNT ON;

IF (OBJECT_ID('tempdb..#tbl') IS NOT NULL)
BEGIN
       SELECT UserID FROM #tbl;
END

GO

EXEC dbo.Foo 123;

Раньше я считал, что прередать переменную в тригер никак нельзя, а вот тут на работе понадобилось...
17 июл 15, 02:33    [17902509]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Изобретаете велосипед?

CONTEXT_INFO
17 июл 15, 07:33    [17902637]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Почему не сделать сразу и потом куда угодно двигать юзера?

CREATE PROCEDURE dbo.Foo (@WebUserID INT)
AS
SET NOCOUNT ON;

[s]CREATE TABLE #tbl (UserID INT);[/s]

[s]INSERT INTO #tbl (UserID) VALUES (@WebUserID);[/s]

UPDATE dbo.TestTbl
   SET TestTblDate = CURRENT_TIMESTAMP, WebUserID = @WebUserID
      WHERE TestTblID = 1;

[s]DROP TABLE #tbl ;[/s]
GO
17 июл 15, 11:01    [17903354]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Владислав Колосов
Member

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

Вы привязываете триггер к контексту выполнения, а это большой баг. Пишите в архив той процедурой, который вы вносите записи в таблицу, в таком случае.
17 июл 15, 11:01    [17903355]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
iap
Изобретаете велосипед?

CONTEXT_INFO


Это не то. Совсем не то. CONTEXT_INFO - это некая строка, которую разные программисты в разных местах могут по разному изменять. В результате получится путаница.
22 июл 15, 02:43    [17919523]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Winnipuh
Почему не сделать сразу и потом куда угодно двигать юзера?

CREATE PROCEDURE dbo.Foo (@WebUserID INT)
AS
SET NOCOUNT ON;

[s]CREATE TABLE #tbl (UserID INT);[/s]

[s]INSERT INTO #tbl (UserID) VALUES (@WebUserID);[/s]

UPDATE dbo.TestTbl
   SET TestTblDate = CURRENT_TIMESTAMP, WebUserID = @WebUserID
      WHERE TestTblID = 1;

[s]DROP TABLE #tbl ;[/s]
GO

Потому, что в TestTbl нет поля WebUserID, но оно есть в TestTblHistory. Это если сильно упроостить. В реальности надо было передавать больше одной переменной.
22 июл 15, 02:47    [17919528]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Владислав Колосов
dburtsev1,

Вы привязываете триггер к контексту выполнения, а это большой баг. Пишите в архив той процедурой, который вы вносите записи в таблицу, в таком случае.


Это не баг, а требование заказчика. Если записи вносятся не через процедуру, надо делать откат. Это можно реализовать только через триггер.
22 июл 15, 02:49    [17919531]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
dburtsev1
Это не баг, а требование заказчика. Если записи вносятся не через процедуру, надо делать откат. Это можно реализовать только через триггер.
Это не баг. Это феерический идиотизм полагать, что наличие context_info гарантирует, что данные вводятся через процедуру.

Сообщение было отредактировано: 22 июл 15, 03:15
22 июл 15, 03:14    [17919543]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
dburtsev1
Это не баг, а требование заказчика. Если записи вносятся не через процедуру, надо делать откат. Это можно реализовать только через триггер.
Вот вы бы и начали с озвучивания требований заказчика.

Заказчик, наверное, имел в виду такой дополнительный уровень защиты? Такое можно сделать, например, разрешив пользователям менять данные только через процедуры.

А вы хотите обмануть заказчика, впарив ему какой то суррогат под названием "как передать переменную в триггер".
22 июл 15, 11:12    [17920329]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
o-o
Guest
и то правда: зачем делать откат?
ладно еще когда по 3 строки вносят,
а по 30 млн? это же офигительно ждать.

отобрать права на таблицы и выдать только на процедуры.
и никакого триггера не надо, пусть процедура и вставляет во все остальное тоже.
тем более что разные BULK-и вообще триггеры игнорят
22 июл 15, 11:21    [17920402]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Гавриленко Сергей Алексеевич
dburtsev1
Это не баг, а требование заказчика. Если записи вносятся не через процедуру, надо делать откат. Это можно реализовать только через триггер.
Это не баг. Это феерический идиотизм полагать, что наличие context_info гарантирует, что данные вводятся через процедуру.


Я где то утверждал, что "наличие context_info гарантирует, что данные вводятся через процедуру". Вы меня с кем то путаете.
22 июл 15, 14:56    [17921674]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
alexeyvg
dburtsev1
Это не баг, а требование заказчика. Если записи вносятся не через процедуру, надо делать откат. Это можно реализовать только через триггер.
Вот вы бы и начали с озвучивания требований заказчика.

Заказчик, наверное, имел в виду такой дополнительный уровень защиты? Такое можно сделать, например, разрешив пользователям менять данные только через процедуры.

А вы хотите обмануть заказчика, впарив ему какой то суррогат под названием "как передать переменную в триггер".


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

В компании принят "свободный стиль" программирования. Каждый программист сам решает, каким стилем писать. Кто то засовывает SELECT UPDATE DELETE INSERT прямо в код приложения. Кто то пишет процедуры. Вы абсолютно ничего не знаете про проект, а обвинения типа "обмануть заказчика, впарив ему какой то суррогат" у вас наготове.
22 июл 15, 15:03    [17921708]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
o-o
и то правда: зачем делать откат?
ладно еще когда по 3 строки вносят,
а по 30 млн? это же офигительно ждать.

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


В компании принят "свободный стиль" программирования. Каждый программист сам решает, каким стилем писать. Кто то засовывает SELECT UPDATE DELETE INSERT прямо в код приложения. Кто то пишет процедуры. Я не могу это изменить.

в данной таблице BULK нету.
22 июл 15, 15:05    [17921716]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Glory
Member

Откуда:
Сообщений: 104760
dburtsev1
Это довольно часто требуется, хотя и не в каждом проекте.

Доступ к таблицам регулируется через права доступа, а не через переменные.

dburtsev1
Вы абсолютно ничего не знаете про проект, а обвинения типа "обмануть заказчика, впарив ему какой то суррогат" у вас наготове.

Конечно, мы тут все отсталые, щи лаптем хлебаем до сих пор. В то время как в продвинутых странах параметры уже в триггеры передают .
22 июл 15, 15:07    [17921728]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
o-o
Guest
dburtsev1
в данной таблице BULK нету.

BULK не в таблице. это один из способов вставки.
при желании игнорирующий триггеры.
так что ваш триггер обойдут, а вы заметите только когда в таблице будет не то, что ожидалось.
еще и отгадывать станете, как же так.
а права надо отбирать. иначе и просто поотключать треггеры можно
22 июл 15, 15:09    [17921739]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
dburtsev1
Я где то утверждал, что "наличие context_info гарантирует, что данные вводятся через процедуру". Вы меня с кем то путаете.
Ну т.е. вы хотите решить задачу "если записи вносятся не через процедуру, надо делать откат", для этого вы каким-то образом что-то хотите передавать из процедуры в триггер, чтобы в триггере удостовериться, что данные меняются именно в процедуре, а не где-либо еще. При этом вы или наивно полагаете, что этого достаточно, чтобы решить задачу (именно это я и назвал идиотизмом), или сознательно делаете некачественное решение (что называется другим словом).
dburtsev1
В компании принят "свободный стиль" программирования. Каждый программист сам решает, каким стилем писать. Кто то засовывает SELECT UPDATE DELETE INSERT прямо в код приложения.
Иными словами, у вас обыкновенный бардак с разработкой, который вы пытаетесь автоматизировать. Удачи в его автоматизации.
22 июл 15, 15:56    [17922027]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Если Вы не хотите, чтобы триггер выполнял код в каких-то случаях, можно воспользоваться псевдо-переменными на базе глобального курсора, пользуясь тем, что такой курсор существует во время всей сессии.
22 июл 15, 17:44    [17922657]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
dburtsev1
Вы абсолютно ничего не знаете про проект, а обвинения типа "обмануть заказчика, впарив ему какой то суррогат" у вас наготове.
Ок, пусть я ошибся. Тогда всё таки озвучте задачу (а не способ решения).
Вы, очевидно, пока говорили про способ решения ("передать переменную в тригер"), почему то назвав его "Одна из задач". Как то было бы странно, если бы заказчик, наступая на жабу, выделял деньги на передачи переменныхз в триггеры?

"Передать в триггер" ничего нельзя, так как к этому объекты программист непосредственно не обращается, это объект, привязанный к таблице. Только через некие глобальные объекты, типа постоянной таблицы или строки контекста коннекта.

Это тоже нормальные варианты, для определённой ситуации, но не при вашем бардаке ("В компании принят "свободный стиль" программирования. Каждый программист сам решает, каким стилем писать. Кто то засовывает SELECT UPDATE DELETE INSERT прямо в код приложения. Кто то пишет процедуры.")
Обращения к глобальным объектам нужно согласовывать.
22 июл 15, 17:52    [17922691]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
Владислав Колосов
Если Вы не хотите, чтобы триггер выполнял код в каких-то случаях, можно воспользоваться псевдо-переменными на базе глобального курсора, пользуясь тем, что такой курсор существует во время всей сессии.
Да можно и временной таблицей пользоваться для таких случаев.
22 июл 15, 17:53    [17922695]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
dburtsev1
Winnipuh
Почему не сделать сразу и потом куда угодно двигать юзера?

CREATE PROCEDURE dbo.Foo (@WebUserID INT)
AS
SET NOCOUNT ON;

[s]CREATE TABLE #tbl (UserID INT);[/s]

[s]INSERT INTO #tbl (UserID) VALUES (@WebUserID);[/s]

UPDATE dbo.TestTbl
   SET TestTblDate = CURRENT_TIMESTAMP, WebUserID = @WebUserID
      WHERE TestTblID = 1;

[s]DROP TABLE #tbl ;[/s]
GO

Потому, что в TestTbl нет поля WebUserID, но оно есть в TestTblHistory. Это если сильно упроостить. В реальности надо было передавать больше одной переменной.


ну так почему бы не добавить эти поля и использовать именно для случаев передачи параметров?
сразу от многих головняков избавитесь.
22 июл 15, 18:26    [17922807]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Glory
dburtsev1
Это довольно часто требуется, хотя и не в каждом проекте.

Доступ к таблицам регулируется через права доступа, а не через переменные.

dburtsev1
Вы абсолютно ничего не знаете про проект, а обвинения типа "обмануть заказчика, впарив ему какой то суррогат" у вас наготове.

Конечно, мы тут все отсталые, щи лаптем хлебаем до сих пор. В то время как в продвинутых странах параметры уже в триггеры передают .


Я нигде не утверждал, что "Доступ к таблицам регулируется через права доступа, а не через переменные."
Это вы придумали и мне приписали.

"Конечно, мы тут все отсталые, щи лаптем хлебаем до сих пор. В то время как в продвинутых странах параметры уже в триггеры передают"
А что не так? Есть такая книга: “T-SQL Querying” © 2015. By Itzik Ben-Gan, Dejan Sarka, Adam Machanic, and Kevin Farlee. ISBN: 978-0-7356-8504-8

Chapter 9. p.584.

A local temporary table you create in one level in the call stack is visible throughout that level as vell as in all inner levels in the call stack. This means that if you create the temporary table before you issue your statement, it’s visible inside the trigger that fired as a result of that statement.

Разумеется, в SQL вы понимаете больше, чем все эти авторы вместе взятые. Там, в предисловии, есть рекомендация от Microsoft - сделать эту книгу своей настольной книгой. Но, вам же это не интересно.
23 июл 15, 02:39    [17924031]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
o-o
dburtsev1
в данной таблице BULK нету.

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


"BULK не в таблице. это один из способов вставки," который в данном приложении не используется совсем.
Про "права надо отбирать" - не ко мне. Я не руководитель проекта. Проект в продакшен уже несколько лет как. Надо работать с тем, что есть.
23 июл 15, 02:44    [17924034]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
alexeyvg
dburtsev1
Вы абсолютно ничего не знаете про проект, а обвинения типа "обмануть заказчика, впарив ему какой то суррогат" у вас наготове.
Ок, пусть я ошибся. Тогда всё таки озвучте задачу (а не способ решения).
Вы, очевидно, пока говорили про способ решения ("передать переменную в тригер"), почему то назвав его "Одна из задач". Как то было бы странно, если бы заказчик, наступая на жабу, выделял деньги на передачи переменныхз в триггеры?

Заказчик работает в этой компании много лет. Начинал он с SQL программиста. До сих пор в промышленной базе работают процедуры, им написанные. Почему то, я уверен, что в транзакциях он разбирается не хуже вас. Вы с ним не говорили, его код не видели, а обвинения у вас наготове. Воспитанный человек бы извинился...
23 июл 15, 02:51    [17924037]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Гавриленко Сергей Алексеевич
Ну т.е. вы хотите решить задачу "если записи вносятся не через процедуру, надо делать откат", для этого вы каким-то образом что-то хотите передавать из процедуры в триггер, чтобы в триггере удостовериться, что данные меняются именно в процедуре, а не где-либо еще. При этом вы или наивно полагаете, что этого достаточно, чтобы решить задачу (именно это я и назвал идиотизмом), или сознательно делаете некачественное решение (что называется другим словом).

Нет. Такой задачи нет. Если бы была, то я так бы и написал.
23 июл 15, 02:56    [17924038]     Ответить | Цитировать Сообщить модератору
 Re: Как передать переменную в тригер  [new]
dburtsev1
Member

Откуда: NY USA
Сообщений: 351
Владислав Колосов
Если Вы не хотите, чтобы триггер выполнял код в каких-то случаях, можно воспользоваться псевдо-переменными на базе глобального курсора, пользуясь тем, что такой курсор существует во время всей сессии.

Вздыхая,
СОБСТВЕННО, ЭТО Я И ПРЕДЛАГАЮ, ТОЛЬКО НЕ ЧЕРЕЗ ГЛОБАЛЬНЫЙ КУРСОР, А ЧЕРЕЗ ВРЕМЕННУЮ ТАБЛИЦУ.

Ну хоть кто то высказался по теме...
23 июл 15, 02:59    [17924039]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить