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

Откуда:
Сообщений: 1086
На уже существующую логику клента нужно повесить свою. Кратко, dbo.base_objects содержит счетчики для id таблиц. Необходимо заменить на свою. Смущают скалярные переменные, но как без них обойтись?
CREATE TRIGGER dbo.NewCode ON dbo.proc_pos AFTER INSERT AS
  IF EXISTS (SELECT dimension1
             FROM
               INSERTED
             WHERE
               dimension1 IS NULL)
  BEGIN
    SET NOCOUNT ON

    DECLARE @count INT,  @plen  INT
    DECLARE @prefix NVARCHAR(10)

    SELECT @count = lastnumber + 1
         , @prefix = prefix
         , @plen = len(pattern)
    FROM
      dbo.base_objects bo WITH (UPDLOCK, ROWLOCK)
    WHERE
      tablename = 'po'

    SET @prefix = @prefix + replicate('0', @plen - len(cast(@count AS NVARCHAR(10)))) + cast(@count AS NVARCHAR(10))

    UPDATE base_objects
    SET   lastnumber = @count
    WHERE   tablename = 'po'

    UPDATE proc_pos
    SET    dimension1 = 1
           , code = @prefix
    FROM
      proc_pos pp
      JOIN INSERTED i
        ON i.po = pp.po
  END
GO
7 дек 12, 16:15    [13595753]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
aleks2
Guest
waszkiewicz
Смущают скалярные переменные, но как без них обойтись?

Стисняюсь спросить: а нафега оне там?
7 дек 12, 16:35    [13595955]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
waszkiewicz,

вот этот кусок задает произвольные значения переменным,
      UPDATE base_objects
    SET   lastnumber = (select top 1 lastnumber + 1 from base WHERE   tablename = 'po')
    WHERE   tablename = 'po'

    UPDATE proc_pos
    SET    dimension1 = 1
           , code =  (select top 1 prefix from base WHERE   tablename = 'po')
    FROM
      proc_pos pp
      JOIN INSERTED i
        ON i.po = pp.po
7 дек 12, 16:37    [13595973]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
WarAnt,

забыл кусок с префиксом вставить:)

   UPDATE proc_pos
    SET    dimension1 = 1
           , code =  (select top 1 prefix + replicate('0', len(pattern) - len(cast(lastnumber AS NVARCHAR(10)))) + cast(lastnumber AS NVARCHAR(10))
                          from base WHERE   tablename = 'po')
    FROM
      proc_pos pp
      JOIN INSERTED i
        ON i.po = pp.po
7 дек 12, 16:40    [13595988]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
В триггере на UPDLOCK и ROWLOCK можно забить?
7 дек 12, 16:45    [13596021]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
aleks2
Guest
WarAnt
waszkiewicz,

вот этот кусок задает произвольные значения переменным,
      UPDATE base_objects
    SET   lastnumber = (select top 1 lastnumber + 1 from base WHERE   tablename = 'po')
    WHERE   tablename = 'po'


Тут конкурс на самый заковыристый апдейт?

    UPDATE base_objects
    SET   lastnumber = lastnumber + 1 
    WHERE   tablename = 'po'
7 дек 12, 16:46    [13596028]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
invm
Member

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

Ничего, что будет один code на все вставляемые записи?
7 дек 12, 16:59    [13596112]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Записей будет одна - клиент это гарантирует
7 дек 12, 17:03    [13596126]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
waszkiewicz
Записей будет одна - клиент это гарантирует
Мамой клянется?

Сообщение было отредактировано: 7 дек 12, 17:06
7 дек 12, 17:06    [13596141]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
waszkiewicz
Записей будет одна - клиент это гарантирует
А потом кто-то поковыряется в клиенте шаловливыми ручками...

Вот как-то так примерно (допилить на свой вкус):
create trigger dbo.trNewCode
on dbo.proc_pos
for insert
as
begin
 set nocount on;
 
 declare @t table (n int, prefix varchar(10));
 
 with s as
 (
  select count(*) as n, 'po' as tablename, 'p' as prefix from inserted where dimension1 is null
 )
 merge into dbo.base_objects t
 using s on s.tablename = t.tablename
 when matched then
  update set lastnumber += n
 when not matched and s.n > 0 then
  insert (tablename, lastnumber) values (s.tablename, s.prefix, s.n)
 output
  inserted.lastnumber - isnull(deleted.lastnumber, 0), inserted.prefix into @t (n, prefix);
 
 if @@rowcount = 0
  return;
  
 with x as
 (
  select
   po, row_number() over (order by po) - 1 as c
  from
   inserted
 )
 update p
  set
   dimension1 = 1,
   code = t.prefix + right(replicate('0', len(t.prefix)) + cast(x.c + t.n), len(t.prefix))
 from
  x cross join
  @t t join
  dbo.proc_pos p on p.po = x.po
  
end;
7 дек 12, 17:37    [13596314]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Тьху... Вот так:
create trigger dbo.trNewCode
on dbo.proc_pos
for insert
as
begin
 set nocount on;
 
 declare @t table (n int, prefix varchar(10));
 
 with s as
 (
  select count(*) as n, 'po' as tablename, 'p' as prefix from inserted where dimension1 is null
 )
 merge into dbo.base_objects t
 using s on s.tablename = t.tablename
 when matched then
  update set lastnumber += n
 when not matched and s.n > 0 then
  insert (tablename, lastnumber) values (s.tablename, s.prefix, s.n)
 output
  isnull(deleted.lastnumber, 1), inserted.prefix into @t (n, prefix);
 
 if @@rowcount = 0
  return;
  
 with x as
 (
  select
   po, row_number() over (order by po) - 1 as c
  from
   inserted
 )
 update p
  set
   dimension1 = 1,
   code = t.prefix + right(replicate('0', len(t.prefix)) + cast(x.c + t.n), len(t.prefix))
 from
  x cross join
  @t t join
  dbo.proc_pos p on p.po = x.po
  
end;
7 дек 12, 17:50    [13596391]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Если не сложно вот это
select
   po, row_number() over (order by po) - 1 as c

можно пояснить?
7 дек 12, 17:57    [13596427]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
invm
Member

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

http://msdn.microsoft.com/en-us/library/ms186734(v=sql.105).aspx
7 дек 12, 18:02    [13596452]     Ответить | Цитировать Сообщить модератору
 Re: Скалярные переменные в триггере AFTER INSERT  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
aleks2
WarAnt
waszkiewicz,

вот этот кусок задает произвольные значения переменным,
      UPDATE base_objects
    SET   lastnumber = (select top 1 lastnumber + 1 from base WHERE   tablename = 'po')
    WHERE   tablename = 'po'


Тут конкурс на самый заковыристый апдейт?

    UPDATE base_objects
    SET   lastnumber = lastnumber + 1 
    WHERE   tablename = 'po'


Пятница же, думать совсем влом, просто поменял переменные на их значения:)
7 дек 12, 18:08    [13596479]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить