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

Откуда: Кишинёв
Сообщений: 6723
Тестовый пример:
USE tempdb
-- SET Language Russian
GO
CREATE TABLE [dbo].[Master] (
	 ID		Int		Identity
	 CONSTRAINT [PK_Master]	PRIMARY KEY
	,[Count]	Int		NOT NULL
	 CONSTRAINT [DF_Master_Count]	DEFAULT 0
	,[Data]		VarChar(64)	NOT NULL
)
CREATE TABLE [dbo].[Slave] (
	 ID		Int	Identity
	 CONSTRAINT [PK_Slave]	PRIMARY KEY
	,[Master]	Int		NOT NULL
	 CONSTRAINT [FK_Slave]	REFERENCES [dbo].[Master] ([ID])
	,[Data]		VarChar(64)	NOT NULL
)
GO
CREATE VIEW [dbo].[vwData] AS
SELECT	 S.ID
	,S.[Master]
	,S.Data
	,M.Data		AS MasterData
	,M.[Count]	AS MasterCount
FROM	          dbo.Slave	S
	LEFT JOIN dbo.[Master]	M ON M.ID = S.[Master]
GO
-- Корень тупых абстакций
UPDATE	V
SET	MasterCount	+= 1
OUTPUT	 Inserted.MasterCount
--	,V.MasterData		-- The multi-part identifier "V.MasterData" could not be bound.
	,Inserted.MasterData
	,Inserted.Data		-- Ошибка: The column reference "inserted.Data" is not allowed because it refers to a base table that is not being modified in this statement.
	,V.Data			-- Ошибка: The multi-part identifier "V.Data" could not be bound.
FROM	dbo.vwData	V
WHERE	V.ID = 1
GO
UPDATE	M
SET	[Count]	+= 1
OUTPUT	 Inserted.[Count]
--	,M.[Data]		-- The multi-part identifier "M.Data" could not be bound.
	,Inserted.[Data]
	,S.Data			-- Работает
FROM	          dbo.Slave	S
	LEFT JOIN dbo.[Master]	M ON M.ID = S.[Master]
WHERE	S.ID = 1
GO
DROP VIEW [dbo].[vwData]
DROP TABLE [dbo].[Slave]
DROP TABLE [dbo].[Master]
Msg 404, Level 16, State 1, Line 6
Ссылка на столбец "inserted.Data" недопустима, поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции.
Msg 4104, Level 16, State 1, Line 7
Не удалось привязать составной идентификатор "V.Data".
Т.е. по сути запрос превосходно работает и компилится, но тупая проверка синтаксиса не даёт ему запустится.

На самом деле, должно работать именно вариант:
	,Inserted.Data --> Но в результате заменяется скулем самостоятельно на S.Data
Потому что логически и физически неважно сложный объект или нет. Если это таблица или представление с навешанными триггерами - оно работает. И если это представление без триггеров, оно должно также работать - компилятор/парсер сам вместо Inserted.Data должен подставить S.Data, для генерации плана.

Т.е. это просто недоработка со стороны разрабов. Типа ща пока оставим простую проверку, а потом уже допилим парсиг/компилятор (правильнее наверно компоновщик запроса).
18 апр 13, 19:59    [14200489]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
парсер тут совершенно ни причем, это не его ошибка
18 апр 13, 20:30    [14200561]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Crimean
Member

Откуда:
Сообщений: 13147
UPDATE	V
SET
	v.MasterCount	+= 1
	,v.Data		= v.Data

FROM	dbo.vwData	V
WHERE	V.ID = 1


Server: Msg 4405, Level 16, State 1, Line 1
View or function 'V' is not updatable because the modification affects multiple base tables.
18 апр 13, 20:39    [14200582]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
iap
Member

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

во VIEW есть поле Data из Slave и MasterData из Master.
UPDATEите MasterCount из Master, а в inserted выводите Data из Slave.
Сервер по-честному говорит: "Ссылка на столбец "inserted.Data" недопустима,
поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции."

В чём же он неправ?!
18 апр 13, 21:39    [14200713]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
locky
парсер тут совершенно ни причем, это не его ошибка
Mnior
парсиг/компилятор (правильнее наверно компоновщик запроса)
Да да, парсер тут скорее не причём, просто ещё тяжело определить его границы.
Семантический анализ (СА) относится к парсеру? И вы думаете это (проверки) делаются не на его (СА) уровне?

Crimean, вы к чему очевидные вещи приводите? Тут нужно глубже копать.

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

Поставьте перед собой два запроса, и ответьте себе на вопрос: Чем они отличаются?
Теперь улавливаете.
19 апр 13, 11:36    [14202490]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
во VIEW есть поле Data из Slave и MasterData из Master.
UPDATEите MasterCount из Master, а в inserted выводите Data из Slave.
Да. Именно. Имено это и нужно.
Что можно выводить в OUTPUT? Всё можно выводить, любые колонки.
Как надо указывать имена колонок? Как обычно с префиксом, кроме изменяемой сущности (таблицы), для неё есть только понятия до и после.

iap
Сервер по-честному говорит: "Ссылка на столбец "inserted.Data" недопустима,
поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции."

В чём же он неправ?!
Он не прав, в том что столбца "inserted.Data" не существует, он виртуален.
Это как сказать, горячее не на столько мягкое.

Я могу так долго приводить зеркальные такие же тупые аргументы:
А почему он нормально выводит столбец Inserted.MasterCount?
В таблице Master нет такого столбца как "MasterCount".

Inserted относится не к таблице Master, не надо путать логику языка, с физикой внутренних процессов.
Inserted не физический операнд, а логический, а то что Inserted.Data и Deleted.Data - это одно и тоже, это проблемы компилятора, а не языка.

Crimean закапитанил проблему реализации. Да, в SET, на текущей версии сервера нельзя указывать колонки из разных таблиц. Ок, не проблема, это физически решить сейчас невозможно.
Но указать в OUTPUT можно всё! (См. второй запрос). Физически нет никаких ограничений.
19 апр 13, 11:53    [14202639]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior
Crimean закапитанил проблему реализации. Да, в SET, на текущей версии сервера нельзя указывать колонки из разных таблиц. Ок, не проблема, это физически решить сейчас невозможно.
Но указать в OUTPUT можно всё! (См. второй запрос). Физически нет никаких ограничений.

все таки ,скорее всего наличие ошибки с OUTPUT ето следствие предидущей ошибки с view
19 апр 13, 12:03    [14202734]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
Сервер по-честному говорит: "Ссылка на столбец "inserted.Data" недопустима,
поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции."

В чём же он неправ?!
Посмотрите лекции Феймана, там как раз затрагивается тема теории и формализации.

Любое явление, на основании наблюдений, можно описать множественные способами, и по мере поступления новых наблюдений, некоторые формулировки отбрасываются - ибо ошибочны.

"inserted ссылается на базовую таблицу" - в общем виде не верно (см. MasterCount).

То что MS привёл некую формулировку, которая лишь выглядит правдоподобной.

И причём тут формулировка? Вы юристы? Вы Граманази?
Если я написал "логический баг", то мы должны доказать его формальность?
Да плевать я хотел на формальность. Физика явления самое главное - а слова это демагогия.

MS лоханулась с сообщением об ошибке. Этот тип проверки нужно тупо убрать.
Голосуйте.
19 апр 13, 12:06    [14202764]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Maxx
все таки ,скорее всего наличие ошибки с OUTPUT ето следствие предидущей ошибки с view
Что вы хотели сказать?
19 апр 13, 12:11    [14202812]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
И да, не обращайте на мой тон внимание. Такой говор, ну вы знаете меня, звиняйте.
19 апр 13, 12:15    [14202852]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior,

ну сообщение об ошибке такое же ,как для view (update set) , не более
Другое не очень понятно ,реально обращение идет по ключу к другой таблице,не той которая в самом апдейт....и в inserted можно указать только поля из Master которая апдейтиться через ключ (join) по Slave, при етом сам update все таки случаеться.
Скорее всего для view должно быть "расширеное" описание inserted
19 апр 13, 12:17    [14202872]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior
И да, не обращайте на мой тон внимание. Такой говор, ну вы знаете меня, звиняйте.

no problem
19 апр 13, 12:21    [14202930]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Maxx
Скорее всего для view должно быть "расширеное" описание inserted
От. Теперь мы на одной ... волне.

Я не думаю что нужно что-то менять в синтаксисе. Синтаксис остался логичным.
Если посмотреть на запись, и словно вы не знаете таблица это или вью, есть на ней INSTEAD OF триггера или нет:
inseted/deleted это просто синтаксис для той сущности, которая указана в секции UPDATE

А то что колонки физически могут меняются или нет - пофиг, значения то можно получить.
То что можно или нет менять - это должно проверятся в SET и только там. Не как проблема синтаксиса, а как проблема реализации.

Не понимаю, Maxx, почему вам такая интерпретация не нравится?
19 апр 13, 12:28    [14203001]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mnior
inseted/deleted это просто синтаксис для той сущности, которая указана в секции UPDATE
Более того, именно так и понимает Management Studiо, она мгновенно подсвечивает как ошибку, если префикс в OUTPUT и UPDATE совпадает
и нормально реагирует на колонки сущности для inserted - типа всё правильно.
19 апр 13, 12:35    [14203067]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior,
честно в данном случае очнеь похоже на то,что вы написали..
потому как для проверки повесил 2 простых триггера на update на обе таблицы.... вызываються реально,только для таблицы над которой происходит update ,хотя во втором примере без view в output inserted попадает таки все
19 апр 13, 12:42    [14203140]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Maxx
повесил 2 простых триггера на update на обе таблицы
А зачем? И к чему?
Я-то имел ввиду триггер на саму VIEW.
19 апр 13, 13:06    [14203339]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
CREATE TRIGGER [trvwDataUpdate] ON [dbo].[vwData]
INSTEAD OF UPDATE AS BEGIN
	PRINT 'Raised!'
END
Msg 404, Level 16, State 1, Line 3
Ссылка на столбец "inserted.MasterCount" недопустима, поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции.
Msg 404, Level 16, State 1, Line 5
Ссылка на столбец "inserted.MasterData" недопустима, поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции.
Msg 404, Level 16, State 1, Line 6
Ссылка на столбец "inserted.Data" недопустима, поскольку она ссылается на базовую таблицу, которая не изменяется в данной инструкции.
Msg 4104, Level 16, State 1, Line 7
Не удалось привязать составной идентификатор "V.Data".
Матерь божья. Не верю своим глазам.

Всё намного хуже, чем я думал.
19 апр 13, 13:15    [14203415]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior
Maxx
повесил 2 простых триггера на update на обе таблицы
А зачем? И к чему?
Я-то имел ввиду триггер на саму VIEW.

а я просто решил проверять все по шагам так сказать
19 апр 13, 13:27    [14203502]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Mnior
Всё намного хуже, чем я думал.

да чего,прогнозируемо было
ксате я смотрю вы на 12 гоняете,у меня на 2008 такое же поведение
19 апр 13, 13:54    [14203762]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mnior
Всё намного хуже, чем я думал.
Ладно мужики, вы меня начинаете убеждать.
Это что так в спецификации SQL описано?

PS: У меня только студия 2012, а скуль 2008.
19 апр 13, 14:18    [14203945]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3034
Mnior
На самом деле, должно работать именно вариант:
	,Inserted.Data --> Но в результате заменяется скулем самостоятельно на S.Data


при работе просто с таблицами, что-то такого у себя не наблюдаю или что-то не так сделал?
USE tempdb
-- SET Language Russian
GO
CREATE TABLE [dbo].[Master] (
	 ID		Int		Identity
	 CONSTRAINT [PK_Master]	PRIMARY KEY
	,[Count]	Int		NOT NULL
	 CONSTRAINT [DF_Master_Count]	DEFAULT 0
	,[Data]		VarChar(64)	NOT NULL
)
CREATE TABLE [dbo].[Slave] (
	 ID		Int	Identity
	 CONSTRAINT [PK_Slave]	PRIMARY KEY
	,[Master]	Int		NOT NULL
	 CONSTRAINT [FK_Slave]	REFERENCES [dbo].[Master] ([ID])
	,[Data]		VarChar(64)	NOT NULL
)
GO

Insert INto dbo.[master] Values (1, 'MasterData')
Insert INto dbo.[Slave] Values (1, 'SlaveData')

GO

UPDATE	M
SET	[Count]	+= 1
OUTPUT
	inserted.ID
	, inserted.[Count]	 
	, inserted.Data
	, deleted.ID
	, deleted.[Count]	 
	, deleted.Data

FROM	          dbo.Slave	S
	LEFT JOIN dbo.[Master] M ON M.ID = S.[Master]
WHERE	S.ID = 1

GO
DROP TABLE [dbo].[Slave]
DROP TABLE [dbo].[Master]


ID Count Data ID Count Data
1 2 MasterData 1 1 MasterData
19 апр 13, 14:55    [14204305]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
CREATE VIEW
автор
Updatable Views

You can modify the data of an underlying base table through a view, as long as the following conditions are true:

Any modifications, including UPDATE, INSERT, and DELETE statements, must reference columns from only one base table.

Ноги отсюда растут ,палюбому..но честно пока статьи никакой по етому поводу найти не могу гдеб было написано что мол НИЗЯ , by design
Видимо просто неточность в документации
И опять же ,дальше нет именно расматриваемого случая
OUTPUT
автор
The OUTPUT clause is not supported in the following statements:

DML statements that reference local partitioned views, distributed partitioned views, or remote tables.

INSERT statements that contain an EXECUTE statement.

Full-text predicates are not allowed in the OUTPUT clause when the database compatibility level is set to 100.

The OUTPUT INTO clause cannot be used to insert into a view, or rowset function.

A user-defined function cannot be created if it contains an OUTPUT INTO clause that has a table as its target.

To prevent nondeterministic behavior, the OUTPUT clause cannot contain the following references:

Subqueries or user-defined functions that perform user or system data access, or are assumed to perform such access. User-defined functions are assumed to perform data access if they are not schema-bound.

A column from a view or inline table-valued function when that column is defined by one of the following methods:

A subquery.

A user-defined function that performs user or system data access, or is assumed to perform such access.

A computed column that contains a user-defined function that performs user or system data access in its definition.

When SQL Server detects such a column in the OUTPUT clause, error 4186 is raised. For more information, see MSSQLSERVER_4186.


И если далее ,чичтать то очнеь похоже,что таки должна быть вот ета ошибка
4186
автор
User Action

Error 4186 can be corrected in one of the following ways:

Use joins instead of subqueries to define the column in the view or function. For example, you can rewrite the view dbo.V1 as follows.

USE AdventureWorks2012;
GO
CREATE VIEW dbo.V1
AS
SELECT City, sp.Name AS State
FROM Person.Address AS a
JOIN Person.StateProvince AS sp
ON sp.StateProvinceID = a.StateProvinceID;

Examine the definition of the user-defined function. If the function does not perform user or system data access, alter the function to include the WITH SCHEMABINDING clause.

Remove the column from the OUTPUT clause.

19 апр 13, 14:57    [14204325]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
Mnior
locky
парсер тут совершенно ни причем, это не его ошибка
Mnior
парсиг/компилятор (правильнее наверно компоновщик запроса)
Да да, парсер тут скорее не причём, просто ещё тяжело определить его границы.
Семантический анализ (СА) относится к парсеру? И вы думаете это (проверки) делаются не на его (СА) уровне?


Семантика уже за границами парсера
фактически, у парсера есть только одна ошибка - incorrect syntax near <>
всё остальное это отдельно семантика, отдельно - линкер, отдельно - всё остальное

например
select a,sum(b)
from tab1
group by c

синтаксически правильно, но семантически - нет
этот стейтмент пройдет проверку синтаксиса,но семантики - нет

ваш пример пройдет проверку синтаксиса, семантики, но свалится на внутренних ограничениях машины выполнения
19 апр 13, 14:57    [14204331]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
HandKot,

а если без view -то все честно , тут с наличие view свистопляска
19 апр 13, 14:59    [14204349]     Ответить | Цитировать Сообщить модератору
 Re: Баг (Логический, парсера): UPDATE View OUTPUT  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3034
Maxx, да это я к тому, что скуль что-то где-то сам меняет

с вью такой финт
CREATE VIEW [dbo].[vwData] AS
SELECT	 S.ID
	,S.[Master]
	,S.Data
	,M.MasterData
	,M.MasterCount
FROM	          dbo.Slave	S
	LEFT JOIN (Select * From dbo.[Master])	M(ID, MasterCount, MasterData) ON M.ID = S.[Master]


при моих небольших знаниях, думаю так
вью - это просто краткая запись для инструкции. Эта инструкция явно подставляется на момент компиляции и выполнения вместо имени вьюхи. Что в результате получаем: две таблицы с одинаковым названием полей и ошибку выдает как раз анализатор UPDATE. т.к при записи Inserted.Data - он считает это нужно брать из таблицы Slave, что противоречить об изменении ТОЛЬКО одной таблицы
19 апр 13, 15:20    [14204535]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить