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

Откуда:
Сообщений: 92
Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) Oct 14 2005 00:33:37 Copyright (c) 1988-2005 Microsoft Corporation Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

Таблица:
USE [Test]
GO
/****** Object:  Table [dbo].[SC838_HIDE]    Script Date: 09/30/2009 10:01:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SC838_HIDE](
	[ROW_ID] [int] IDENTITY(1,1) NOT NULL,
	[ID] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[PARENTID] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[code] [char](16) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[DESCR] [char](48) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[ISFOLDER] [tinyint] NOT NULL,
	[ISMARK] [bit] NOT NULL,
	[VERSTAMP] [int] NOT NULL,
	[SP840] [char](14) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP841] [char](14) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP842] [datetime] NOT NULL,
	[SP843] [char](56) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP1533] [char](128) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP1811] [numeric](1, 0) NOT NULL,
	[SP2012] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP2081] [datetime] NOT NULL,
	[SP2159] [char](50) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP2516] [numeric](15, 0) NOT NULL,
	[SP2813] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP2814] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP3222] [numeric](2, 0) NOT NULL,
	[SP3477] [numeric](1, 0) NOT NULL,
	[SP4225] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP4490] [numeric](1, 0) NOT NULL,
	[SP4507] [numeric](1, 0) NOT NULL,
	[SP4931] [numeric](3, 0) NOT NULL,
	[SP4932] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP4963] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP4964] [numeric](1, 0) NOT NULL,
	[SP5011] [numeric](1, 0) NOT NULL,
	[SP5003] [datetime] NOT NULL,
	[SP5454] [numeric](1, 0) NOT NULL,
	[SP6247] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP6542] [numeric](9, 2) NOT NULL,
	[SP6543] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP6750] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP7105] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP7205] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP7404] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP8056] [char](50) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP8520] [numeric](1, 0) NOT NULL,
	[SP9093] [char](25) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP9181] [char](25) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP10261] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP10262] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP10263] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[SP10386] [char](9) COLLATE Cyrillic_General_CI_AS NOT NULL,
 CONSTRAINT [PK_SC838] PRIMARY KEY CLUSTERED 
(
	[ROW_ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

Представление к ней:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [dbo].[SC838] WITH SCHEMABINDING
AS
SELECT ROW_ID,ID, PARENTID, CODE, DESCR, ISFOLDER, ISMARK, VERSTAMP, SP840, SP841, SP842, SP843, CAST('' AS CHAR(128)) AS SP1533, SP1811, SP2012, SP2081, SP2159, SP2516, 
       SP2813, SP2814, SP3222, SP3477, SP4225, SP4490, SP4507, SP4931, SP4932, SP4963, SP4964, SP5011, SP5003, SP5454, SP6247, SP6543, 
       SP6542, SP6750, SP7105, SP7205, SP7404, SP8056, SP8520, SP9093, SP9181, SP10261, SP10262, SP10263, SP10386
FROM dbo.SC838_HIDE
GO

SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO

Триггер к представлению:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON

GO

ALTER TRIGGER [RLS_ SC838_INSERT]
   ON  [dbo].[SC838]
   INSTEAD OF INSERT
AS 
BEGIN
	SET NOCOUNT ON;
	ROLLBACK TRAN; -- оценить сработает ли триггер

END

GO


Клиентское приложение обновляет таблицу через представление.
Сорри, не получилось картинку вставить, приведу так:
exec sp_executesql N'Insert into SC838 values(
@P1,@P2,@P3,@P4,@P5,@P6,@P7,@P8,@P9,@P10,@P11,@P12,@P13,@P14,@P15,@P16,@P17,@P18,@P19,@P20,@P21,@P22,@P23,@P24,@P25,@P26,@P27,@P28,@P29,@P30,@P31,@P32,@P33,@P34,@P35,@P36,@P37,@P38,@P39,@P40,@P41,@P42,@P43,@P44,@P45,@P46)',N'@P1
varchar(9),@P2 varchar(9),@P3 varchar(16),@P4 varchar(48),@P5 tinyint,@P6 bit,@P7 int,@P8 varchar(14),@P9 varchar(14),@P10 datetime,@P11 varchar(56),@P12 varchar(128),@P13
numeric(1,0),@P14 varchar(9),@P15 datetime,@P16 varchar(50),@P17 numeric(15,0),@P18 varchar(9),@P19 varchar(9),@P20 numeric(2,0),@P21 numeric(1,0),@P22 varchar(9),@P23
numeric(1,0),@P24 numeric(1,0),@P25 numeric(3,0),@P26 varchar(9),@P27 varchar(9),@P28 numeric(1,0),@P29 numeric(1,0),@P30 datetime,@P31 numeric(1,0),@P32 varchar(9),@P33
numeric(9,2),@P34 varchar(9),@P35 varchar(9),@P36 varchar(9),@P37 varchar(9),@P38 varchar(9),@P39 varchar(50),@P40 numeric(1,0),@P41 varchar(25),@P42 varchar(25),@P43
varchar(9),@P44 varchar(9),@P45 varchar(9),@P46 varchar(9)',' 43 ',' 0 ','546','hrttyj',1,0,0,' ',' ','Jan 1 1753
12:00:00:000AM','
',' ',0,' 0 ','Jan 1 1753
12:00:00:000AM',' ',0,' 0 ',' 0 ',0,0,' 0 ',0,0,0,' 0 ',' 0 ',0,0,'Jan 1 1753
12:00:00:000AM',0,' 0 ',0.00,' 0 ',' 0 ',' 0 ',' 0 ',' 0 ',' ',0,'
','

При вставке получаю сообщение об ошибке:
"Insert Error: Column name or number of supplied values does not match table definition."

Понимаю, что причина в поле ROW_ID, которое IDENTITY и не должно присутствовать в списке вставляемых колонок, кроме случая установки опиции IDENTITY_INSERT.
Проблема в том, что код клиентского приложения я поменять не могу.
Напрашивается простое решение: ну так убери это поле из VIEW вовсе. Тогда затык происходит в другом месте вызова(очевидно, что после запроса типа
SELECT *
FROM SC838
WHERE CODE='111'
приложение запрашивает значение этого ROW_ID и сворачивается в коврик)

Эта ошибка времени выполнения, насколько понимаю. И проверяется до старта триггера INSTEAD OFF :(
Вопрос: может ли проверка выполнения инструкции по вставке не выполняться?
30 сен 09, 11:36    [7723700]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
А может я вообще пошел неверным путем и можно организовать представление иначе?
30 сен 09, 11:37    [7723711]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Glory
Member

Откуда:
Сообщений: 104760
Georgie

Понимаю, что причина в поле ROW_ID, которое IDENTITY и не должно присутствовать в списке вставляемых колонок, кроме случая установки опиции IDENTITY_INSERT.

Это касается таблиц, а не представлений. Тем более представлений с триггером INSTEAD OF
Для таких представлений команда INSERT должна содержать значения для всех полей NOT NULL
30 сен 09, 11:41    [7723734]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Glory
Тем более представлений с триггером INSTEAD OF
Для таких представлений команда INSERT должна содержать значения для всех полей NOT NULL
А какой-нибудь простейший пример, в котором 2005-й сервер
ругался бы на попытку вставить NULL в поле NOT NULL можно посмотреть?
Я имею в виду не INSERT в таблицу внутри триггера INSTEAD OF INSERT, а именно INSERT в представление.
30 сен 09, 11:53    [7723800]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Glory
Member

Откуда:
Сообщений: 104760
Все перепутал. Все гораздо проще
Если вы не перечисляете для insert в представление с таким триггером список полей, то получаете ошибку
30 сен 09, 12:13    [7723916]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
Скажите, а можно ли сделать проигнорировать выполнение инструкции по вставке? Нет ли инструмента, который будет работать перед вставкой. Сумбурно..
Мой триггер INSTED OF не срабатывает - проверка синтаксиса идет раньше.(
30 сен 09, 12:22    [7723987]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Glory
Member

Откуда:
Сообщений: 104760
Georgie
Скажите, а можно ли сделать проигнорировать выполнение инструкции по вставке? Нет ли инструмента, который будет работать перед вставкой. Сумбурно..
Мой триггер INSTED OF не срабатывает - проверка синтаксиса идет раньше.(

Перед вставкой работает ваше приложение. А дальше сервер. Вы хотите перехватывать запросы при их передаче от первого второму ?
30 сен 09, 12:24    [7724002]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
Glory
Georgie
Скажите, а можно ли сделать проигнорировать выполнение инструкции по вставке? Нет ли инструмента, который будет работать перед вставкой. Сумбурно..
Мой триггер INSTED OF не срабатывает - проверка синтаксиса идет раньше.(

Перед вставкой работает ваше приложение. А дальше сервер. Вы хотите перехватывать запросы при их передаче от первого второму ?

Допустим, как вариант
30 сен 09, 12:26    [7724015]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Glory
Member

Откуда:
Сообщений: 104760
Georgie
Glory
Georgie
Скажите, а можно ли сделать проигнорировать выполнение инструкции по вставке? Нет ли инструмента, который будет работать перед вставкой. Сумбурно..
Мой триггер INSTED OF не срабатывает - проверка синтаксиса идет раньше.(

Перед вставкой работает ваше приложение. А дальше сервер. Вы хотите перехватывать запросы при их передаче от первого второму ?

Допустим, как вариант

Для этого придется писать промежуточный слой. Ведь вы собрались еще и подменять запросы
30 сен 09, 12:28    [7724029]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
Glory
Georgie
Glory
Georgie
Скажите, а можно ли сделать проигнорировать выполнение инструкции по вставке? Нет ли инструмента, который будет работать перед вставкой. Сумбурно..
Мой триггер INSTED OF не срабатывает - проверка синтаксиса идет раньше.(

Перед вставкой работает ваше приложение. А дальше сервер. Вы хотите перехватывать запросы при их передаче от первого второму ?

Допустим, как вариант

Для этого придется писать промежуточный слой. Ведь вы собрались еще и подменять запросы

Хорошо, зайдем с другой стороны. Синтаксис инструкции по вставке проверяется раньше старта триггера instead of. Это задекларированное поведение сервера? Можно ли наоборот: триггер вместо вставки выполняется независимо от того, какой код пришел от приложения(синтаксически вернй или нет)?
30 сен 09, 13:05    [7724311]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
Я так понимаю, что задал тривиальный вопрос? Или это все же недокументированная особенность поведения триггеров instead of на view?
30 сен 09, 13:20    [7724421]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Glory
Member

Откуда:
Сообщений: 104760
Georgie
Я так понимаю, что задал тривиальный вопрос? Или это все же недокументированная особенность поведения триггеров instead of на view?


BOL - INSTEAD OF INSERT Triggers

An INSERT statement that is referencing a view that has an INSTEAD OF INSERT trigger must supply values for every view column that does not allow nulls. This includes view columns that reference columns in the base table for which input values cannot be specified, such as:

- Computed columns in the base table.
- Identity columns in the base table for which IDENTITY INSERT is OFF.
- Base table columns with the timestamp data type.
30 сен 09, 13:28    [7724490]     Ответить | Цитировать Сообщить модератору
 Re: INSERT через view + Триггер INSTEAD OF  [new]
Georgie
Member

Откуда:
Сообщений: 92
Glory
Georgie
Я так понимаю, что задал тривиальный вопрос? Или это все же недокументированная особенность поведения триггеров instead of на view?


BOL - INSTEAD OF INSERT Triggers

An INSERT statement that is referencing a view that has an INSTEAD OF INSERT trigger must supply values for every view column that does not allow nulls. This includes view columns that reference columns in the base table for which input values cannot be specified, such as:

- Computed columns in the base table.
- Identity columns in the base table for which IDENTITY INSERT is OFF.
- Base table columns with the timestamp data type.


Упустил.
Спасибо.
30 сен 09, 13:40    [7724570]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить