Переключение на Главную Страницу Страницы: [1] 2 3  ОтправитьПечать
Очень популярная тема (более 25 ответов) Триггер на Insert с обновлением некоторых колонок вставляемых данных? (число прочтений - 6691 )
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Триггер на Insert с обновлением некоторых колонок вставляемых данных?
01. Декабря 2011 :: 13:03
Печать  
Есть таблица 1SJOURN, в нее добавил поля (колонки): IDDOC13, и IDDOC23. 1С естественно при записи нового документа не устанавливает, хотелось бы их заполнить триггером. Но 1С -ка вылетает с ошибкой базы "Подключение занято до получения результатов для другого hstmt".

Привожу пример с обновлением полей IDDOC13, и IDDOC23.

Пишу такой триггер:
Код
Выбрать все
CREATE TRIGGER [dbo].[_1SJOURN_OnInsert] ON [dbo].[_1SJOURN]
AFTER INSERT, UPDATE
AS
BEGIN
	UPDATE
		_1SJOURN
	SET
		IDDOC13 = CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC,
		IDDOC23 = 'O1'+CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC + '	  '
	WHERE IDDOC IN (SELECT Ins.IDDOC FROM Inserted AS Ins)
END
 



При этом сам SQL выполняет нормально вставку:
Код
Выбрать все
exec sp_executesql N'Insert into _1SJOURN values( @P1 int,@P2 varchar(9),@P3 int,@P4 smallint,@P5 varchar(23),@P6 varchar(18),@P7 varchar(11),@P8 tinyint,@P9 bit,@P10 int,@P11 int,@P12 bit,@P13 bit,@P14 bit,@P15 bit,@P16 bit,@P17 bit,@P18 bit,@P19 bit,@P20 bit,@P21 bit,@P22 bit,@P23 varchar(9),@P24 varchar(9),@P25 varchar(9),@P26 numeric(1,0),@P27 varchar(1),@P28 varchar(9),@P29 varchar(9),@P30 tinyint,@P31 tinyint,@P32 varchar(13),@P33 varchar(23)',2452,'  UOLH   ',2198,0,'201112017ZGXQ8  UOLH   ','	21982011    ','ПШ-0005242',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'     0   ','    4R   ','    13ZG ',0,' ','     0   ','     0   ',0,0,'		 ','			     ' 

  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #1 - 01. Декабря 2011 :: 13:13
Печать  
Вот последние секунды жизни 1С по профайлеру:
Код
Выбрать все
set implicit_transactions on
exec _1sp__1SJOURN_TLockX
declare @p1 int
set @p1=1073741830
declare @p2 int
set @p2=180150019
declare @p5 int
set @p5=2
declare @p6 int
set @p6=1
declare @p7 int
set @p7=-1
exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(18),@P2 varchar(11)',N'Select * from _1SJOURN WITH (NOLOCK) where DNPREFIX=@P1 and DOCNO=@P2 order by DNPREFIX, DOCNO, ROW_ID',@p5 output,@p6 output,@p7 output,'	21982011    ','ПШ-0005242 '
select @p1, @p2, @p5, @p6, @p7
exec sp_cursorfetch 180150019,1,0,1
declare @p2 char(9)
set @p2='  UOLG   '
exec _1sp__1SUIDCTL_GetMaxID 0,@p2 output
select @p2	1CV7
declare @p1 varchar(9)
set @p1='  UOLG   '
exec _1sp__1SJOURN_MaxID @p1 output
select @p1	1CV7
exec sp_executesql N'Insert into _1SJOURN values( @P1 int,@P2 varchar(9),@P3 int,@P4 smallint,@P5 varchar(23),@P6 varchar(18),@P7 varchar(11),@P8 tinyint,@P9 bit,@P10 int,@P11 int,@P12 bit,@P13 bit,@P14 bit,@P15 bit,@P16 bit,@P17 bit,@P18 bit,@P19 bit,@P20 bit,@P21 bit,@P22 bit,@P23 varchar(9),@P24 varchar(9),@P25 varchar(9),@P26 numeric(1,0),@P27 varchar(1),@P28 varchar(9),@P29 varchar(9),@P30 tinyint,@P31 tinyint,@P32 varchar(13),@P33 varchar(23)',2452,'  UOLH   ',2198,0,'201112017ZGXQ8  UOLH   ','	21982011    ','ПШ-0005242',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'     0   ','    4R   ','    13ZG ',0,' ','     0   ','     0   ',0,0,'		 ','			     '
IF @@TRANCOUNT > 0 ROLLBACK TRAN
IF @@TRANCOUNT > 0 ROLLBACK TRAN
set implicit_transactions off
set implicit_transactions off
exec sp_executesql N'Delete from _1SDNLOCK where  DNPREFIX=@P1 and DOCNO=@P2',N'@P1 varchar(28),@P2 varchar(24)','	21982011    ','ПШ-0005242 '
exec sp_cursorclose 180150015
exec sp_cursorunprepare 1073741829
declare @p2 int
set @p2=180150021
declare @p3 int
set @p3=2
declare @p4 int
set @p4=2
declare @p5 int
set @p5=-1
exec sp_cursorexecute 1073741825,@p2 output,@p3 output,@p4 output,@p5 output
select @p2, @p3, @p4, @p5
exec sp_cursorfetch 180150021,2,0,1
exec sp_cursor 180150021,1,1,N'',@USRSCNT=0,@NETCHGCN=1
exec sp_cursorclose 180150021
exec sp_cursorunprepare 1073741825

 

  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #2 - 01. Декабря 2011 :: 13:36
Печать  
Сделал триггер на вставку в другую таблицу - результат тот же:
Код
Выбрать все
IF OBJECT_ID ('_1SJOURN_OnInsert','TR') IS NOT NULL
   DROP TRIGGER _1SJOURN_OnInsert;
GO

CREATE TRIGGER [dbo].[_1SJOURN_OnInsert] ON [dbo].[_1SJOURN]
AFTER INSERT, UPDATE
AS
BEGIN
	INSERT INTO [dbo].[tbl_JOURN]
	     ([ROW_ID]
	     ,[IDDOC]
	     ,[IDDOC13]
	     ,[IDDOC23])
     SELECT
		[ROW_ID],
	  [IDDOC],
	  CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC AS IDDOC13,
	  'O1'+CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC + '	  ' AS IDDOC23
	FROM Inserted

	/*	_1SJOURN
	SET
		IDDOC13 = CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC,
		IDDOC23 = 'O1'+CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC + '	  '
	WHERE IDDOC IN (SELECT Ins.IDDOC FROM Inserted AS Ins)
	*/
END
 



Похоже что 1С-у не нравятся триггеры на таблицу _1SJOURN
  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #3 - 01. Декабря 2011 :: 13:41
Печать  
Недавно боролся с тригерами, но не на _журн:
Может чего подскажет.
Код
Выбрать все
// обновитьТригерыНаТаблицахСРеквДатаОбновления() © trdm 2011
Процедура обновитьТригерыНаТаблицахСРеквДатаОбновления()
	Если (МонопольныйРежим() = 0) ИЛИ (глЭтоСкуль = 0)  Тогда
		Возврат;
	КонецЕсли;
	вРекордСет = СоздатьОбъект("ODBCRecordset");

	//вРекордСет.УстановитьТекстовыйПараметр("ВыбФирма",ВыбФирма);
	//вРекордСет.УложитьСписокОбъектов(ВыбТовар,"#ВыбТовар");
	ТекстЗапроса = "
	|--Получение даты и времени с сервера в формате ГГГГММДДЧЧММ
	|--drop function calcDateOfUpdeteV
	|-- select dbo.calcDateOfUpdeteV(getdate())
	|CREATE function calcDateOfUpdeteV(@FromDate datetime)
	|returns char(12)
	|AS
	|BEGIN
	|declare @Ret char(12)
	|declare @RetYY char(4)
	|declare @RetMO char(2)
	|declare @RetDD char(2)
	|declare @RetHH char(2)
	|declare @RetMM char(2)
	|declare @dt datetime
	|declare @dtch int
	|set @dt=@FromDate
	|select @RetYY = CAST( DATEPART(year, @dt) as char(4) )
	|set @dtch=DATEPART(month, @dt)
	|IF @dtch <10
	|(
	|	select  @RetMO = '0' +CAST( @dtch as char(2) )
	|)
	|ELSE
	|(
	|	select  @RetMO = CAST( @dtch as char(2) )
	|)
	|set @dtch=DATEPART(day, @dt)
	|IF @dtch <10
	|(
	|	select  @RetDD = '0' +CAST( @dtch as char(2) )
	|)
	|ELSE
	|(
	|	select @RetDD = CAST( @dtch as char(2) )
	|)
	|set @dtch=DATEPART(hour, @dt)
	|IF @dtch <10
	|(
	|	select  @RetHH = '0' +CAST( @dtch as char(2) )
	|)
	|ELSE
	|(
	|	select  @RetHH = CAST( @dtch as char(2) )
	|)
	|set @dtch=DATEPART(minute, @dt)
	|IF @dtch <10
	|(
	|	select  @RetMM = '0' +CAST( @dtch as char(2) )
	|)
	|ELSE
	|(
	|	select  @RetMM = CAST( @dtch as char(2) )
	|)
	|set @Ret = @RetYY + @RetMO + @RetDD  + @RetHH + @RetMM
	|return @Ret
	|END
	|";

	вТаблаЗнач = СоздатьОбъект("ТаблицаЗначений");
	Попытка
		вТаблаЗнач = вРекордСет.ВыполнитьИнструкцию(ТекстЗапроса);

	Исключение
		вОписание = "There is already an object named 'calcDateOfUpdeteV";
		вОписаниеО = ОписаниеОшибки();
		Если Найти(вОписаниеО,вОписание) = 0 Тогда
			Сообщить(вОписаниеО+"[201111212027]");
		КонецЕсли;
	КонецПопытки;

	вИмяЛогаТригеров = "trigersupdatelog";
	глЗарегистрироватьЛог(вИмяЛогаТригеров,"Лог обновления тригеров на запись элементов справочника с рекв 'ДатаОбновления'");
	СЦ = 0;
	Для СЦ = 1 По Метаданные.Справочник() Цикл
		вМетаСпр = Метаданные.Справочник(СЦ);
		Если глЕстьРеквизитСправочника("ДатаОбновления",вМетаСпр.Идентификатор) = Нет Тогда
			Продолжить;
		КонецЕсли;
		вВидСпр = вМетаСпр.Идентификатор;
		вИдРеквизита = глMetaDataWork.ИДРеквизитаСправочника(вВидСпр,"ДатаОбновления");
		вИмяТригера = вВидСпр+"_AFTER_UPDATE";
		ТекстЗапросаДТ = "DROP TRIGGER " + вИмяТригера;

		ТекстЗапросаКТ = "
		|-- DROP TRIGGER " + вИмяТригера +"
		|CREATE TRIGGER "+вИмяТригера+"
		|ON $Справочник."+вВидСпр+"
		|AFTER UPDATE
		|AS
		|BEGIN
		|SET NOCOUNT ON;
		|begin
		|UPDATE $Справочник."+вВидСпр+" set sp"+вИдРеквизита+" = dbo.calcDateOfUpdeteV(getdate())
		|FROM inserted i
		|INNER JOIN $Справочник."+вВидСпр+" as спр ON i.ID = спр.ID
		|END
		|END
		|";
		Попытка
			вРекордСет.ВыполнитьИнструкцию(ТекстЗапросаДТ);
		Исключение
		КонецПопытки;
		Попытка
			вРекордСет.ВыполнитьИнструкцию(ТекстЗапросаКТ);
			вСтрокаСообщить = "Создали тригер '"+вИмяТригера+"' на запись для справочника: '" + глСинонимМетаданного(вМетаСпр)+"'";
			глЗаписатьВЛогФайлУпрощенно(вИмяЛогаТригеров, вСтрокаСообщить);
			//Сообщить(вСтрокаСообщить);
		Исключение
			вСтрокаСообщить = ОписаниеОшибки()+"[201111212321]";
			Сообщить(вСтрокаСообщить);
			глЗаписатьВЛогФайлУпрощенно(вИмяЛогаТригеров, вСтрокаСообщить);
		КонецПопытки;
	КонецЦикла;

КонецПроцедуры // обновитьТригерыНаТаблицахСРеквДатаОбновления()
 

  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #4 - 01. Декабря 2011 :: 13:46
Печать  
pvase писал(а) 01. Декабря 2011 :: 13:03:
Пишу такой триггер:

Напиши set nocount on перед update.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #5 - 01. Декабря 2011 :: 13:50
Печать  
Меня кстати выматерили на счет писанины типа:
Код
Выбрать все
select  @RetMO = '0' +CAST( @dtch as char(2) )
 


велели курить функцию CONVERT, но не вкурил.
А может ли она сделать аналогичное вверху написанному?
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #6 - 01. Декабря 2011 :: 14:24
Печать  
berezdetsky писал(а) 01. Декабря 2011 :: 13:46:
pvase писал(а) 01. Декабря 2011 :: 13:03:
Пишу такой триггер:

Напиши set nocount on перед update.


Спасибо, таки помогло. А я вместо Nocount написал был SET QUOTED_IDENTIFIER ON. Еще раз спасибо.
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #7 - 01. Декабря 2011 :: 14:25
Печать  
Вот рабочий вариант если вдруг кому надо:
Код
Выбрать все
CREATE TRIGGER [dbo].[_1SJOURN_OnInsert] ON [dbo].[_1SJOURN]
AFTER INSERT, UPDATE
AS
BEGIN
	set nocount on
	UPDATE
		_1SJOURN
	SET
		IDDOC13 = CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC,
		IDDOC23 = 'O1'+CASE WHEN IDDOCDEF < 46656 THEN ' '+RTRIM(dbo.Convert10To36(IDDOCDEF)) ELSE RTRIM(dbo.Convert10To36(IDDOCDEF)) END + IDDOC + '	  '
	WHERE IDDOC IN (SELECT Ins.IDDOC FROM Inserted AS Ins)
END
 

  
Наверх
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #8 - 01. Декабря 2011 :: 16:47
Печать  
И..Зачем тебе эти лишние поля в табличке ?
Типизацию проще лепить, или что ?
  
Наверх
 
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #9 - 01. Декабря 2011 :: 18:16
Печать  
Есть регистры, в которых поля Неопределенного вида. Чтобы получить документы по ним, приходиться делать RIGHT, что приводит к замедлению выборки. Также в документах есть реквизиты с неопределенными видами документов, по ним то индекс можно добавить, но использование этого индекса с RIGHT не происходит.
  
Наверх
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #10 - 01. Декабря 2011 :: 20:24
Печать  
pvase писал(а) 01. Декабря 2011 :: 18:16:
Есть регистры, в которых поля Неопределенного вида. Чтобы получить документы по ним, приходиться делать RIGHT, что приводит к замедлению выборки. Также в документах есть реквизиты с неопределенными видами документов, по ним то индекс можно добавить, но использование этого индекса с RIGHT не происходит.


тихий ужас
Улыбка

Ну а какое отношение это всё имеет к 1sjourn ? , че то не догоняю.

  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #11 - 02. Декабря 2011 :: 06:55
Печать  
Eprst писал(а) 01. Декабря 2011 :: 20:24:
Ну а какое отношение это всё имеет к 1sjourn ? , че то не догоняю.


На счет идДок23 не скажу, а вот идДок13 - это офигенно полезный реквизит, когда он общий реквизит документов с индексацией.

Ибо тогда, например, конструкции вида
Код
Выбрать все
FROM
	_1SJourn жМонтаж (nolock)
	LEFT JOIN _1SJourn жЗаявка (nolock) on жЗаявка.$ОбщийРеквизит.идДок13 = жМонтаж.$ОбщийРеквизит.ДокументОснование 


получаются
а) очень естественны
и б) работают заметно быстрее, чем выборка через таблицу кроссдоков.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #12 - 02. Декабря 2011 :: 07:05
Печать  
Документ основание общий реквизит ?!

Всё равно не догоняю, в чем преимущество.
Покажите пример реальных данных.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #13 - 02. Декабря 2011 :: 07:29
Печать  
Да, документ основание - тоже общий реквизит.
И тоже с индексацией.

А показать пример на реальных данных - это разве что базу в общий доступ выложить Смех

Мое личное мнение есть таково, что таблица кроссдоков - вселенское зло.
Ибо спихать в одну таблицу перекрестные ссылки и отборы по журналам - это чем надо было думать?

А вообще - большинство бизнесспроцессов, как-раз, легко строится в четкой иерархии 1 документ родитель - несколько документов-оснований.
Банальное:
Заказ поставщику -> счет (один или несколько) -> поступление по счету (опять же - одно или несколько по каждому счету).
Или вот например (уже родное):
Заявка покупателя, к ней в подчинении документы -> СрокПроизводства, СрокДоставки, СрокМонтажа, Реализация.
к Сроку производства - цепочка: Выпуск -> поступление на СГП -> списание с СГП.
К Сроку монтажа -> Акт монтажа.


Цитата:
Мое личное мнение есть таково, что таблица кроссдоков - вселенское зло.

Причем, даже если выкинуть из нее в другие таблицы отборы по журналам и графам отбора - роль у нее более статистическая.
Т.е. достаточно быстро и удобно построить дерево документов - в принципе, сойдет.
Собирать данные по бизнесс-процессам - тут уж увольте, мне надежнее пройтись от акта монтажа на 2 шага вверх + спустится через ветвь производства, ежели мне нужна какая-то информация оттуда, чем плодить лишнюю кросс-ссылку.
Кросс-ссылки между документами бывают необходимы, не спорю - но злоупотреб##ть ими точно не стоит.
А искать перекрестные ссылки для критичных операций (типо поиск ссылок на удаляемые объекты) - так вообще, большими и нудными запросами по всем таблицам.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Триггер на Insert с обновлением некоторых колонок вставляемых данных?
Ответ #14 - 02. Декабря 2011 :: 07:38
Печать  
Ну и ? Всё тоже самое есть в 1scrdoc.. смысл то в доп поле какой ?
И, не у всех есть общие реквизиты докОснования.

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 
ОтправитьПечать