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

Откуда: Недалекое заМКАДье
Сообщений: 355
Делаю UpdateTrigger. В теле триггера делаю так:

	DECLARE Record_Cursor CURSOR FOR
		SELECT * FROM inserted;

	SELECT @IDFile = [ID Файла] FROM inserted ;

	SELECT [AA_TMI].[dbo].[Файл_TEMP].[ID Файла]  FROM [AA_TMI].[dbo].[Файл_TEMP] 
		WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile;

	IF @@ROWCOUNT = 1 
	BEGIN 
		OPEN Record_Cursor;
		FETCH NEXT FROM Record_Cursor
			INTO @IDFile, @DT, @MinTime, @MaxTime, @About;

		WHILE @@FETCH_STATUS = 0
		BEGIN
			UPDATE [AA_TMI].[dbo].[Файл_TEMP]
				SET [Дата создания] = @DT
					,[Min время] = @MinTime
					,[Max время] = @MaxTime
					,[Описание] = @About
				WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile

			FETCH NEXT FROM Record_Cursor;
		END;

		CLOSE Record_Cursor;
		DEALLOCATE Record_Cursor;
	END
	ELSE
	BEGIN 

		OPEN Record_Cursor;
		FETCH NEXT FROM Record_Cursor
			INTO @IDFile, @DT, @MinTime, @MaxTime, @About;

		WHILE @@FETCH_STATUS = 0
		BEGIN
			INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
				([ID Файла]
				,[Дата создания]
				,[Min время]
				,[Max время]
				,[Описание])
			VALUES
				(@IDFile
				,@DT
				,@MinTime
				,@MaxTime
				,@About)

			FETCH NEXT FROM Record_Cursor
				INTO @IDFile, @DT, @MinTime, @MaxTime, @About;
		END;

		CLOSE Record_Cursor;
		DEALLOCATE Record_Cursor;
	END 

В процессе обновления таблицы появляется ошибка
error
The data in row 1 was not committed.
Error Source: .Net SqlClient Data Provider
Error Message: Cursorfetch: The number of variables declared in the INTO list must match that of selected columns

Т.к. в таблице TEMP записи такой нет, то rowcount = 0 всегда. Следовательно ошибку получаю в строке FETCH NEXT FROM Record_Cursor INTO @IDFile, @DT, @MinTime, @MaxTime, @About;
Но не могу понять почему? Ведь
	SELECT @IDFile = [ID Файла] FROM inserted ;
	SELECT @DT = [Дата создания] FROM inserted ;
выполняется всегда нормально.

Как же тогда скопировать эту обновленную строку целиком? Объявлять каждое поле отдельно через свой select?

Правило сроков выполнения проекта (90 на 90). Первые 90% работы отнимают 10% времени, а последние 10% - оставшиеся 90% времени.
15 июл 09, 15:46    [7419595]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
akf
Но не могу понять почему?
Когда перестанете использовать wildcard ("*") в объявлении курсора - такие вопросы отпадут за ненадобностью.

ЗЫ. Курсоры здесь не сплющились ни в одно из мест.
15 июл 09, 15:54    [7419663]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
а структуру таблицы [AA_TMI] то хоть приведите, ведь на структуру и ругается

для спящего время бодрствования равносильно сну
15 июл 09, 15:55    [7419665]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
Если же делаю просто:
INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
([ID Файла]...)
VALUES
(inserted.[ID Файла]...)
получаю
Msg 128, Level 15, State 1, Procedure Файл_UpdateTrigger, Line 66
The name "inserted.ID Файла" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
15 июл 09, 15:56    [7419675]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
[ID Файла]	int		Unchecked
[Дата создания] datetime Unchecked
[Min время] real Unchecked
[Max время] real Unchecked
Описание nchar(100) Checked
15 июл 09, 15:58    [7419686]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

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

У вас на какой таблице триггер этот определен?
15 июл 09, 15:59    [7419687]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
проходящий.
Guest
akf
Если же делаю просто:
INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
([ID Файла]...)
VALUES
(inserted.[ID Файла]...)
получаю
Msg 128, Level 15, State 1, Procedure Файл_UpdateTrigger, Line 66
The name "inserted.ID Файла" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
Мда...
INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
([ID Файла]...)
SELECT [ID Файла]... from inserted
15 июл 09, 15:59    [7419693]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
vino
Member

Откуда:
Сообщений: 1191
есть малопонятные селекты - там же может быть больше одной записи, а у вас не понятно, какое из значений выбирается
	SELECT @IDFile = [ID Файла] FROM inserted ;
	SELECT @DT = [Дата создания] FROM inserted ;
А ошибка вполне конкретная - список переменных для получения значений полей из курсора некорректный
error
Cursorfetch: The number of variables declared in the INTO list must match that of selected columns

Советую в объявлении курсора
	DECLARE Record_Cursor CURSOR FOR
		SELECT * FROM inserted;
указать каждое поле, которое нужно, в правильном порядке
15 июл 09, 16:03    [7419714]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
Senya_L, проходящий. Курсоры было первое, что пришло в голову. Насчёт wildcard спасибо!
15 июл 09, 16:03    [7419718]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
if exists (SELECT [AA_TMI].[dbo].[Файл_TEMP].[ID Файла]  FROM [AA_TMI].[dbo].[Файл_TEMP] t join inserted i on t.[ID Файла] = i.[ID Файла]) begin
  UPDATE [AA_TMI].[dbo].[Файл_TEMP]
				SET [Дата создания] = i.[Дата создания]
					,[Min время] = i.[Min время]
					,[Max время] = i.[Max время]
					,[Описание] = i.[Описание]
   FROM [AA_TMI].[dbo].[Файл_TEMP] t join inserted i on t.[ID Файла] = i.[ID Файла]
end else begin
 INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
 ([ID Файла], [Дата создания],[Min время],[Max время],[Описание])
  SELECT [ID Файла], [Дата создания],[Min время],[Max время],[Описание] from inserted
end

для спящего время бодрствования равносильно сну
15 июл 09, 16:05    [7419735]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Мдя... вгляделся в текст триггера. Фигею все больше и больше.

автор
SELECT @IDFile = [ID Файла] FROM inserted ;
Если это работает, то это не означает, что правильно.
автор
	SELECT [AA_TMI].[dbo].[Файл_TEMP].[ID Файла]  FROM [AA_TMI].[dbo].[Файл_TEMP] 
		WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile;
Это просто изюмительно: делать селект в триггере. Непонятно только: зачем?
15 июл 09, 16:06    [7419738]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
vino
есть малопонятные селекты - там же может быть больше одной записи, а у вас не понятно, какое из значений выбирается
	SELECT @IDFile = [ID Файла] FROM inserted ;
	SELECT @DT = [Дата создания] FROM inserted ;

Я думал, что т.к. триггер на update, то и в таблице inserted будет 1 строка? не так?
15 июл 09, 16:06    [7419741]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
если update всегда по одной записи, то так. а если просто
update tablett set col1 = 1 from tablett
то все все записи попадут в триггер.

для спящего время бодрствования равносильно сну
15 июл 09, 16:07    [7419749]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
Senya_L, проверить существование такой записи в таблице TEMP. Т.к. может такой записи в таблице ещё не было, она создалась уже после добавления данных в нормальную таблицу
15 июл 09, 16:08    [7419761]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
akf
Senya_L, проходящий. Курсоры было первое, что пришло в голову. Насчёт wildcard спасибо!
Вы хоть целиком триггер покажите.
А делать по принципу "первым в голову пришло" = "делать через одно место". Потом появляются вопросы: где голова, а где ж...а
15 июл 09, 16:08    [7419763]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
akf
Senya_L, проверить существование такой записи в таблице TEMP. Т.к. может такой записи в таблице ещё не было, она создалась уже после добавления данных в нормальную таблицу
Заменить
	SELECT [AA_TMI].[dbo].[Файл_TEMP].[ID Файла]  FROM [AA_TMI].[dbo].[Файл_TEMP] 
		WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile;

	IF @@ROWCOUNT = 1 
на
	if exists (
	SELECT * FROM [AA_TMI].[dbo].[Файл_TEMP] 
		WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile;
	)
15 июл 09, 16:11    [7419781]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
Senya_L, это и есть собственно весь триггер.
Да, об множественно обновлении я не подумал.. Как же тогда отследить создание\обновление записей в TEMP?
Так?
		DECLARE @count as int;
		OPEN Record_Cursor;
		FETCH NEXT FROM Record_Cursor
			INTO @IDFile, @DT, @MinTime, @MaxTime, @About;

		WHILE @@FETCH_STATUS = 0
		BEGIN
			SELECT @count = count(*) FROM [AA_TMI].[dbo].[Файл_TEMP] WHERE [ID Файла]=@IDFile;
			IF @count=1
			BEGIN
			UPDATE [AA_TMI].[dbo].[Файл_TEMP]
				SET [Дата создания] = @DT
					,[Min время] = @MinTime
					,[Max время] = @MaxTime
					,[Описание] = @About
				WHERE [AA_TMI].[dbo].[Файл_TEMP].[ID Файла] = @IDFile

			FETCH NEXT FROM Record_Cursor;
			END;
			ELSE
			BEGIN
			INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
				([ID Файла]
				,[Дата создания]
				,[Min время]
				,[Max время]
				,[Описание])
			SELECT [ID Файла]
				,[Дата создания]
				,[Min время]
				,[Max время]
				,[Описание] from inserted WHERE inserted.[ID Файла] = @IDFile;
			END;
		END;

		CLOSE Record_Cursor;
		DEALLOCATE Record_Cursor;
15 июл 09, 16:15    [7419803]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
2akf
если не читать всех сообщений в топике, то можете и так.

для спящего время бодрствования равносильно сну
15 июл 09, 16:17    [7419825]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
с заменой @@rowcount на exists соответственно
15 июл 09, 16:18    [7419829]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
akf
Senya_L, это и есть собственно весь триггер.
Не весь. Меня болше заголовок триггера интересует. На какую таблицу навешен этот триггер?
15 июл 09, 16:19    [7419843]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
ALTER TRIGGER [Файл_UpdateTrigger] 
    ON [dbo].[Файл] 
    AFTER UPDATE 
15 июл 09, 16:20    [7419851]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
vino
Member

Откуда:
Сообщений: 1191
...собственно весь триггер
UPDATE t SET
	 [Дата создания] = i.[Дата создания]
	,[Min время] = [Min время]
	,[Max время] = [Max время]
	,[Описание] = [Описание]
	FROM [AA_TMI].[dbo].[Файл_TEMP] t join inserted i on t.[ID Файла] = i.[ID Файла]
INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
	([ID Файла]
	,[Дата создания]
	,[Min время]
	,[Max время]
	,[Описание])
	SELECT [ID Файла]
		,[Дата создания]
		,[Min время]
		,[Max время]
		,[Описание]
		FROM inserted i
	WHERE not exists(SELECT * FROM [AA_TMI].[dbo].[Файл_TEMP] t WHERE t.[ID Файла] = i.[ID Файла])
15 июл 09, 16:33    [7419957]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
ALTER TRIGGER [Файл_UpdateTrigger] 
    ON [dbo].[Файл] 
    AFTER UPDATE 
as
IF @@ROWCOUNT > 0 
BEGIN
	SET NOCOUNT ON;

	UPDATE [AA_TMI].[dbo].[Файл_TEMP] SET
		[Дата создания] = @DT
		,[Min время] = @MinTime
		,[Max время] = @MaxTime
		,[Описание] = @About
	FROM [AA_TMI].[dbo].[Файл_TEMP] F
		join inserted i on F.[ID Файла] = i.[ID Файла]

	INSERT INTO [AA_TMI].[dbo].[Файл_TEMP]
		([ID Файла]
		,[Дата создания]
		,[Min время]
		,[Max время]
		,[Описание])
	SELECT [ID Файла]
		,[Дата создания]
		,[Min время]
		,[Max время]
		,[Описание] 
	from inserted i
	WHERE not exists (select * from [AA_TMI].[dbo].[Файл_TEMP] F where f.[ID Файла] = i.[ID Файла]
END
Вот и весь триггер
15 июл 09, 16:34    [7419969]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
Senya_L
Member

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

опередил
15 июл 09, 16:34    [7419981]     Ответить | Цитировать Сообщить модератору
 Re: Поля таблицы inserted  [new]
akf
Member

Откуда: Недалекое заМКАДье
Сообщений: 355
Senya_L, vino, спасибо!
15 июл 09, 16:37    [7420000]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить