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

Откуда:
Сообщений: 16
Достопочтенные господа и не менее почтенные дамы!
вопрос! Сразу прошу прощения за нубский вопрос. Пользую SQL Express 2012. Триггер выполняется или полностью или не выполняется вообще? Ниже пример для расчета ключа банковского счета.
Таблица:

CREATE TABLE draft(
	draftaccount char(20) ,
	draftbic char(9) ,
	number int);

вот триггер:

create trigger draftaccount1 on draft
after insert
as
	begin 
		update draft
			set draftaccount = ltrim(rtrim(draftaccount))+replicate('0',12-len(cast((select count (*) from draft) as                 varchar(20))))+cast((select count (*) from draft) as varchar (20))
			where number is null;
		update draft
			set number = (7*(select cast(substring(draftbic,7,1) as int) from draft)%10
			+1*(select cast(substring(draftbic,8,1) as int) from draft)%10
			+3*(select cast(substring(draftbic,9,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,1,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,2,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,3,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,4,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,5,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,6,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,7,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,8,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,9,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,10,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,11,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,12,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,13,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,14,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,15,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,16,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,17,1) as int) from draft)%10
			+3*(select cast(substring(draftaccount,18,1) as int) from draft)%10
			+7*(select cast(substring(draftaccount,19,1) as int) from draft)%10
			+1*(select cast(substring(draftaccount,20,1) as int) from draft)%10)%10*3%10;
		update draft
			set draftaccount = substring(draftaccount,1,8) +cast(number as char(1))+substring(draftaccount,10,11);
		update draft
		set number = 1;
      end;


Сообщение было отредактировано: 6 авг 13, 00:29
6 авг 13, 00:17    [14666930]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Nasmork
Member

Откуда:
Сообщений: 16
закладывается такая логика, вводится номер счета+валюта = 8 знаков, БИК.
последние цифры - приравниваются к количеству строк в таблице, дополняется нулями, считается ключ, обновляется номер счета, ставится флажок в столбе number типа обработанная строка. без вспомогательного столбца не знаю как сделать
6 авг 13, 00:21    [14666939]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Триггер выполняется в то же транзакции, что и модифицируемая команда. Поэтому или полностью, или откатывается.
6 авг 13, 00:31    [14666958]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Nasmork
Member

Откуда:
Сообщений: 16
Гавриленко Сергей Алексеевич, огонь! Спасибо!
6 авг 13, 00:40    [14666978]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Зачем после каждого инсерта независимо от добавленных данных пересчитывать значения по всей таблице?
6 авг 13, 06:29    [14667168]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31964
Nasmork,

Вам нжно прочитать про триггеры, у вас написано непонятно что (подробнее не пишу, боюсь модераторов).

Триггер - это хранимая процедура, которая выполняется после выполнения оператора изменения данных в таблице, не более. Выполняется в транзакции.

Соответственно как минимум вы делаете все записи в таблице одинаковыми.
Ну и 24 раза выполнить сканирование таблицы draft во втором update - это нечто.
6 авг 13, 08:01    [14667238]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
west74
Member

Откуда: Челябинск
Сообщений: 76
На нубский вопрос , нубский ответ :) (без обид)
вот пример простой , должно стать понятно как сделать можно


-- создаем тест табличку
CREATE TABLE [dbo].[BI_1](
[id] [varchar](50) NULL,
[obor] [nvarchar](4000) NULL,
[name] [varchar](20) NULL,
[regdate] [date] NULL
)


-- проверим
select * from [PriceDB].[dbo].[BI_1]

-- вставим просто запись
insert into [PriceDB].[dbo].[BI_1] (id,obor) values (1,2)

-- проверим
select * from [PriceDB].[dbo].[BI_1]

-- созадим тригер
CREATE TRIGGER Insert_BI_1_TABLE on [PriceDB].[dbo].[BI_1]
after insert
as
declare @pkey int;

select @pkey=id from inserted;


update [PriceDB].[dbo].[BI_1]
set regdate=getdate(),
name = 'пример '+cast(obor as varchar(5))
where id=@pkey ;

-- еще раз вставим запись
insert into [PriceDB].[dbo].[BI_1] (id,obor) values (1,3)

--почуствуем разницу :)
select * from [PriceDB].[dbo].[BI_1]
6 авг 13, 08:19    [14667263]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
west74
На нубский вопрос , нубский ответ :) (без обид)
вот пример простой , должно стать понятно как сделать можно


-- создаем тест табличку
CREATE TABLE [dbo].[BI_1](
	[id] [varchar](50) NULL,
	[obor] [nvarchar](4000) NULL,
	[name] [varchar](20) NULL,
	[regdate] [date] NULL
) 


-- проверим
select * from  [PriceDB].[dbo].[BI_1] 

-- вставим просто запись
insert into [PriceDB].[dbo].[BI_1] (id,obor) values (1,2)

-- проверим
select * from  [PriceDB].[dbo].[BI_1] 

-- созадим тригер
CREATE TRIGGER Insert_BI_1_TABLE on [PriceDB].[dbo].[BI_1] 
after insert
as 
declare @pkey int;

select @pkey=id from inserted;


update [PriceDB].[dbo].[BI_1]  
 set regdate=getdate(),
     name = 'пример '+cast(obor as varchar(5))
 where id=@pkey ;
 
-- еще раз вставим запись
insert into [PriceDB].[dbo].[BI_1] (id,obor) values (1,3)

--почуствуем разницу :)
select * from  [PriceDB].[dbo].[BI_1]
За выделенную строчку надо расстреливать!
6 авг 13, 09:30    [14667475]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2415
west74
На нубский вопрос , нубский ответ :) (без обид)
вот пример простой , должно стать понятно как сделать можно

select @pkey=id from inserted;



таблица inserted может содержать более одной записи!!
6 авг 13, 09:38    [14667523]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
StarikNavy
west74
На нубский вопрос , нубский ответ :) (без обид)
вот пример простой , должно стать понятно как сделать можно

select @pkey=id from inserted;



таблица inserted может содержать более одной записи!!

Ну что вы ей богу. Человек же написал заранее.
Никто не гарантировал идеального решения
6 авг 13, 10:08    [14667669]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Сергей Викт.
StarikNavy
пропущено...


таблица inserted может содержать более одной записи!!

Ну что вы ей богу. Человек же написал заранее.
Никто не гарантировал идеального решения

В данном случае это вовсе не "неидеальное решение", но "неправильное решение". Если человеку не указать на ошибку, он и дальше будет полагать, что так "сделать можно".
6 авг 13, 10:33    [14667863]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Гость333
Сергей Викт.
пропущено...

Ну что вы ей богу. Человек же написал заранее.
Никто не гарантировал идеального решения

В данном случае это вовсе не "неидеальное решение", но "неправильное решение". Если человеку не указать на ошибку, он и дальше будет полагать, что так "сделать можно".

Ваша правда)
6 авг 13, 11:05    [14668040]     Ответить | Цитировать Сообщить модератору
 Re: вопрос нуба про триггер  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Nasmork, ник говорящий.
Главное чтобы не заразил остальных помоями кода. Надо соблюдать чистоту.
Оформляйте код, разделяйте всё по кусочкам. Не будете же Copy&Past-ить вычисление контрольной цифры?!
Вот для затравки (12-ти значное +1):
CREATE FUNCTION [dbo].[fnIDNControl] (
	@IDN	VarChar(36)
) RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT	 C.ControlNumber
	,CASE	WHEN SubString(@IDN,13,1) = Convert(VarChar(1),C.ControlNumber)
		THEN Convert(Bit,1)
		ELSE Convert(Bit,0)
		END	AS Valid
FROM	(SELECT CASE
WHEN	Len(@IDN) = 13 AND @IDN NOT LIKE '%[^0-9]%'
THEN	( Convert(TinyInt,SubString(@IDN,12,1))
	+ Convert(TinyInt,SubString(@IDN, 9,1))
	+ Convert(TinyInt,SubString(@IDN, 6,1))
	+ Convert(TinyInt,SubString(@IDN, 3,1))
	+ 3 * (40
	+ Convert(TinyInt,SubString(@IDN,11,1))
	+ Convert(TinyInt,SubString(@IDN, 8,1))
	+ Convert(TinyInt,SubString(@IDN, 5,1))
	+ Convert(TinyInt,SubString(@IDN, 2,1))
	- Convert(TinyInt,SubString(@IDN,10,1))
	- Convert(TinyInt,SubString(@IDN, 7,1))
	- Convert(TinyInt,SubString(@IDN, 4,1))
	- Convert(TinyInt,SubString(@IDN, 1,1))
	)) % 10	END	) C(ControlNumber)
И даже оптимально по количеству вычислений (даже только одно умножение).
А далее не будете разделать это на 100500 команд, а всё в одной, опять же - оптимально.

Более того, можете поставить это как вычисляемое поле на таблице, и не надо никаких триггеров вообще.
К тому же, в некоторых системах требуется номер без контрольной цифры.
6 авг 13, 12:14    [14668545]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить