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

Откуда:
Сообщений: 47
Добрый день!

Подскажите, пожалуйста, как реализовать задуманное.
Есть процедура, которая добавляет строку в таблицу. Таблица содержит несколько столбцов (S1, S2, S3, S4, S5, S6) Процедура добавляет значения в столбец с 1-го по 5-ый. Мне же нужно сделать так, чтобы при insert 'е в шестой столбец записывалось бы значение из второго столбца (по плану оно должно быть немного видоизменено, но пока хоть как-то бы добавить).

Данную проблему сперва хотела решить с помощью триггера

ALTER TRIGGER [dbo].[mytrigger]

on [dbo].[CitizenInfo] after insert
AS

BEGIN
declare @f nvarchar(50)
set nocount on
Select @f = i.DocNum from inserted i;
insert into dbo.CitizenInfo (IdDoc) values (@f)
END

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

В связи с этим убедилась в том, что триггером мою задачу не решишь, ведь нужно же в эту строку значение добавить, так сказать, на этапе insert.
Добавить в процедуру еще один новый параметр и передавать в нем нужное значение не вариант.
21 ноя 12, 12:00    [13506003]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
_djХомяГ
Guest
1 вычисляемый столбец
2 выносить все в логику процедуры и не заморачиваться с триггером
21 ноя 12, 12:02    [13506021]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Eyere
Member

Откуда:
Сообщений: 47
_djХомяГ
1 вычисляемый столбец
2 выносить все в логику процедуры и не заморачиваться с триггером


вычисляемый столбец - это как? Насколько я понимаю, значения в таких столбцах может вычисляться из встроенных функциях, а как я ему свою впишу?
21 ноя 12, 12:06    [13506054]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
iap
Member

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

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

Зачем триггер - ума не приложу. Тем более, Вы его писать не умеете.
21 ноя 12, 12:06    [13506056]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Eyere
В связи с этим убедилась в том, что триггером мою задачу не решишь, ведь нужно же в эту строку значение добавить, так сказать, на этапе insert.

Триггером AFTER INSERT, действительно, не решишь. Но можно использовать триггер INSTEAD OF INSERT.
Либо, действительно, при помощи вычисляемого столбца или логики хранимой процедуры. Вычисляемый столбец проще, но его надо использовать, если вы точно уверены, что логика вычисления значения этого столбца не изменится со временем.
21 ноя 12, 12:09    [13506094]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
_djХомяГ
Guest
ну или update'ом таблицы вычисляя S6 через значения других столбцов
21 ноя 12, 12:13    [13506134]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Eyere
_djХомяГ
1 вычисляемый столбец
2 выносить все в логику процедуры и не заморачиваться с триггером


вычисляемый столбец - это как? Насколько я понимаю, значения в таких столбцах может вычисляться из встроенных функциях, а как я ему свою впишу?

А в чём проблема использования своей функции? Пример:

CREATE TABLE dbo.TEST_PERSON (ID INT, NAME VARCHAR(100));
INSERT dbo.TEST_PERSON VALUES (1, 'Вася');
INSERT dbo.TEST_PERSON VALUES (2, 'Маша');
GO
CREATE FUNCTION dbo.PersonName (@p INT) RETURNS VARCHAR(100) WITH SCHEMABINDING
AS
BEGIN
  RETURN (SELECT NAME FROM dbo.TEST_PERSON WHERE ID = @p);
END;
GO
CREATE FUNCTION dbo.DoubleString (@p VARCHAR(100)) RETURNS VARCHAR(200) WITH SCHEMABINDING
AS
BEGIN
  RETURN @p + @p;
END;
GO
CREATE TABLE dbo.FUNCTION_TEST (S1 INT, S2 VARCHAR(100), S6 AS dbo.DoubleString(S2), S7 AS dbo.PersonName(S1));
INSERT dbo.FUNCTION_TEST (S1, S2) VALUES (1, 'Строка 1');
INSERT dbo.FUNCTION_TEST (S1, S2) VALUES (2, 'Строка 2');
SELECT * FROM dbo.FUNCTION_TEST;
DROP TABLE dbo.FUNCTION_TEST;
DROP FUNCTION dbo.DoubleString;
DROP FUNCTION dbo.PersonName;
DROP TABLE dbo.TEST_PERSON;
GO


Только очень вас прошу, не используйте это решение, для вашей задачи оно плохое по многим причинам
21 ноя 12, 12:28    [13506289]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Тяп-ляп
Member

Откуда: Москва
Сообщений: 797
автор
В связи с этим убедилась в том, что триггером мою задачу не решишь, ведь нужно же в эту строку значение добавить, так сказать, на этапе insert.

Вывод неверный, в триггере можно сделать Update нужного столбца
Не забыть рекурсию триггеров отключить у БД.
Не забыть, что в Insert может быть более одной записи.
21 ноя 12, 12:29    [13506304]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Eyere
Member

Откуда:
Сообщений: 47
Тяп-ляп
автор
В связи с этим убедилась в том, что триггером мою задачу не решишь, ведь нужно же в эту строку значение добавить, так сказать, на этапе insert.

Вывод неверный, в триггере можно сделать Update нужного столбца
Не забыть рекурсию триггеров отключить у БД.
Не забыть, что в Insert может быть более одной записи.


О, спасибо! Исправила в своем триггере Insert на Update. Вроде бы получилось как задумала.
Рекурсия триггеров отключена.
Извините, пожалуйста, а что делать в случае, если в Insert может быть более одной записи?
21 ноя 12, 12:50    [13506539]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
PaulYoung
Member

Откуда: Москва
Сообщений: 2551
Eyere
Извините, пожалуйста, а что делать в случае, если в Insert может быть более одной записи?
Eyere, Вам - только так
21 ноя 12, 13:31    [13506967]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Eyere
Member

Откуда:
Сообщений: 47
Хотя рано радовалась... у меня апдейтятся столбцы во всех строках... Как указать триггеру, что апдейтить нужно только ту строку, которая добавилась?
21 ноя 12, 13:44    [13507108]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Тяп-ляп
Member

Откуда: Москва
Сообщений: 797
автор
апдейтить нужно только ту строку, которая добавилась

UPDATE t
. . .
FROM t
INNER JOIN inserted i ON t.PK = i.PK
21 ноя 12, 14:15    [13507376]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Eyere
Member

Откуда:
Сообщений: 47
Тяп-ляп
автор
апдейтить нужно только ту строку, которая добавилась

UPDATE t
. . .
FROM t
INNER JOIN inserted i ON t.PK = i.PK



Что-то все равно не получается. Может быть я неправильно поняла Ваши рекомендации?

ALTER TRIGGER [dbo].[mytrigger]

on [dbo].[CitizenInfo] after insert
AS

BEGIN
declare @f nvarchar(20)
set nocount on

select @f = i.DocNum from inserted i



update CitizenInfo
set CitizenInfo.IdDoc = right(@f,charindex('-',@f)+2)
from CitizenInfo inner join inserted i ON CitizenInfo.DocNum = i.DocNum

END

Аптейтит все строки, удовлетворяющие условию, а не только ту, которая была только что добавлена.
21 ноя 12, 16:03    [13508554]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Гость333
Member

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

Под PK имелся в виду Primary Key. Нужно джойнить по столбцу (набору столбцов), однозначно идентифицирующем строку в таблице. У вас DocNum может повторяться в таблице CitizenInfo?

Кроме того, надо выкинуть переменную:

update CitizenInfo 
set CitizenInfo.IdDoc = right(i.DocNum,charindex('-',i.DocNum)+2) 
from CitizenInfo inner join inserted i ON CitizenInfo.DocNum = i.DocNum
21 ноя 12, 16:19    [13508690]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
Eyere
Member

Откуда:
Сообщений: 47
Гость333
Eyere,

Под PK имелся в виду Primary Key. Нужно джойнить по столбцу (набору столбцов), однозначно идентифицирующем строку в таблице. У вас DocNum может повторяться в таблице CitizenInfo?

Кроме того, надо выкинуть переменную:

update CitizenInfo 
set CitizenInfo.IdDoc = right(i.DocNum,charindex('-',i.DocNum)+2) 
from CitizenInfo inner join inserted i ON CitizenInfo.DocNum = i.DocNum


Ааа, теперь ясно. По PK действительно получилось однозначно идентифицировать строку. Переменную выкинула. Строки в таблице могут быть одинаковые, т.к. браться они будут их разных источников. А проверки на существование строки нет.
21 ноя 12, 16:31    [13508814]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
kinglion
Member

Откуда:
Сообщений: 16
Add a new DEFAULT CONSTRAINT to the table
21 ноя 12, 21:23    [13510184]     Ответить | Цитировать Сообщить модератору
 Re: Trigger или что-то другое  [new]
kinglion
Member

Откуда:
Сообщений: 16
Maybe will help.
21 ноя 12, 21:33    [13510208]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить