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

Откуда:
Сообщений: 12310
EXEC sp_addtype N'utTest1', N'int', N'not null'
go
create table t1(
    f utTest1
)
go
dbcc checkcatalog ('tempdb')
go
select * into #t1 from t1
go
dbcc checkcatalog ('tempdb')
go
drop table #t1
go
dbcc checkcatalog ('tempdb')
Результат:
DBCC results for 'tempdb'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Server: Msg 2514, Level 16, State 1, Line 1
Table error: Data type 275 (type '275') does not match between 'SYSCOLUMNS' and 'SYSTYPES'.
DBCC results for 'tempdb'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

DBCC results for 'tempdb'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Смотрим, что попадает в tempdb (до удаления временной таблицы):
select
    so.name,
    sc.name,
    sc.xtype,
    sc.xusertype,
    sc.type,
    sc.usertype
from
    tempdb..sysobjects so
    inner join tempdb..syscolumns sc on so.id = sc.id
where
    so.id = object_id('tempdb..#t1')
Результат:
name                      name xtype xusertype type usertype 
------------------------- ---- ----- --------- ---- -------- 
#t1__________00000000003E f    56    275       56   275


А в tempdb..systypes такого пользовательского типа нет:
select * from tempdb..systypes where name = 'f'
(0 row(s) affected)

Кстати, создать явно временную таблицу так не получится:
create table #t1(
    f utTest1
)
Server: Msg 2715, Level 16, State 7, Line 1
Column or parameter #1: Cannot find data type utTest1.
И это правильно.

Понятно, что есть несколько выходов из положения:
1. Завести пользовательский тип в tempdb
2. Не использовать конструкцию select into для описанного случая
3. Создавать временную таблицу явно, но вместо пользовательских типов указывать системные

но все равно нехорошо, что вполне легальной конструкцией можно так обидеть сервер.
25 окт 05, 18:48    [2004877]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
Taffy
Member

Откуда:
Сообщений: 20498
А, ээээ... Упс :(
Я как раз обдумывала стандартизацию проектов с использованием пользовательских типов данных. Но если их нельзя использовать во временных таблицах, то зачем они нужны?
Не понятно.
Спасибо, GreenSunrise, очень вовремя.
25 окт 05, 19:44    [2005043]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4255
GreenSunrise
[src]но все равно нехорошо, что вполне легальной конструкцией можно так обидеть сервер.


какая же она легальная - тип заводится в одной базе, а пытается использоватья в другой.
25 окт 05, 20:36    [2005177]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
Taffy
Member

Откуда:
Сообщений: 20498
GreenSunrise
1. Завести пользовательский тип в tempdb

А какие минусы у этого решения?
25 окт 05, 21:42    [2005273]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
ChA
Member

Откуда: Москва
Сообщений: 10989
Taffy
Лучше не связывайтесь с пользовательскими типами, практической пользы нет, а вот проблемы можете огрести в самый неожиданный момент. К сожалению, потерял ссылку, где, если правильно помню, MS не рекомендовала пользоваться UDT без особой необходимости. Увы, не помню всех аргументов, которые там были приведены, о чем сильно сожалею, просто запомнилось как факт. Может кто найдет или вспомнит случайно...
IMHO, одна из основных проблем, что UDT, в нынешнем своем состоянии привязаны к БД, где они определены, и абсолютно неизвестны за ее пределами, что сильно ограничивает их применимость. Есть и еще куча житейских минусов, пробегитесь хотя бы по этому

P.S. Впрочем, решение, безусловно, за Вами.
25 окт 05, 23:54    [2005634]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А почему б тогда не завести UDT в model (если уж так хочется его пользовать)?
26 окт 05, 06:45    [2005897]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
WiRuc
Member

Откуда: Воронеж
Сообщений: 1280
tpg
А почему б тогда не завести UDT в model (если уж так хочется его пользовать)?

Можно, но тогда есть вероятность того, что произойдет конфликт типов, если вдруг будет устанавливаться какое-либо другое приложение, использующее такое же наименование типа.
26 окт 05, 09:28    [2006180]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
WiRuc
tpg
А почему б тогда не завести UDT в model (если уж так хочется его пользовать)?

Можно, но тогда есть вероятность того, что произойдет конфликт типов, если вдруг будет устанавливаться какое-либо другое приложение, использующее такое же наименование типа.
Да это то понятно...
Предлагал только для решения таких узких мест.
ИМХО, все эти пользовательские типы - от лукавого...
26 окт 05, 09:40    [2006220]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31194
Действительно, использовать пользовательские типы нельзя - это, может, звучит красиво (можно кому-нибуть похвастаться, сделать умное лицо), но:
во-первых, это чревато проблемами при разработке и при обслуживании,
во-вторых, совершенно бесполезно - в отличии от определения типов в программе на C, если вы определили тип DOCUMENT_NUMBER как int, вы не сможете просто переопределить его как varchar(32) или uniqueidentifier - таблички-то придётся алтерить.

Вот если-бы можно было определить:
create table MYDOC(id DOCUMENT_NUMBER primary key, ...)
другие таблицы с ссылками на неё, а потом переопределить тип DOCUMENT_NUMBER по-другому (с заданием правил преобразования данных, если хочется), и сервер все данные сам-бы переделал...

Да ещё чтоб в разных БД DOCUMENT_NUMBER мог быть по-разному определён, а в темпдб конфликтов-бы не возникало...
26 окт 05, 09:47    [2006243]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
Welly
Member

Откуда: Novosibirsk
Сообщений: 174
Вот если-бы можно было определить:
create table MYDOC(id DOCUMENT_NUMBER primary key, ...)
другие таблицы с ссылками на неё, а потом переопределить тип DOCUMENT_NUMBER по-другому (с заданием правил преобразования данных, если хочется), и сервер все данные сам-бы переделал...

И это не настолько нереально :)
Microsoft сейчас разрабатывает проект LINQ:
The LINQ Project
.NET Language Integrated Query
Q&A
26 окт 05, 10:49    [2006589]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Lepsik
какая же она легальная - тип заводится в одной базе, а пытается использоватья в другой.

Она абсолютно легальна, также как и попытка сделать create table #t с UDT. Но почему-то для select into все пройдет якобы нормально, а для create table #t выдастся ошибка. Мне кажется, что ошибка должна выдаваться в обоих случаях.

Под "легальностью" я подразумеваю то, что я не лезу руками в системные таблицы, не правлю mdf файлы в нотепаде и т.д., я выполняю совершенно законную конструкцию, пропускаемую SQL Server'ом. Незаконные конструкции должны просто отваливаться с ошибкой.

Taffy
А какие минусы у этого решения?

Минус единственный :-) Как выяснилось, он не работает. Если я создаю UDT в tempdb явно, то он получает свое значение в поле usertype и xusertype в systypes. Конструкция же select into вдувает структуру таблицы вместе с типами так, что в полях usertype и xusertype таблицы syscolumns значение копируется прямо из рабочей базы. А там оно вовсе не обязано совпадать с аналогичным в базе tempdb. Получается опять же расхождение и все та же ошибка "Data type N (type 'N') does not match between 'SYSCOLUMNS' and 'SYSTYPES'."

Кстати, у меня очепятка вкралась в самый первый пост. Запрос про типы должен быть вот такой:
select * from tempdb..systypes where name = 'utTest1'
Но сути дела он не меняет. Все равно ни одной строки не возвращается.

tpg
А почему б тогда не завести UDT в model (если уж так хочется его пользовать)?

Ответ тот же, что и Taffy. Числовой идентификатор все равно совпадать не будет и проблема останется.

И то, что WiRuc сказал, тоже.
-------------------------------
И почему почти все красивости и вкусности MSSQL, которые так удачно выглядят в пресс-релизах и тестах, на поверку оказываются совершенно неюзабельными? Что UDT, что индексированные вьюхи, что INSTEAD OF триггера... Примеров куча. На тестовых примерах все зашибись, а как до дела доходит, так обязательно вылезет что-то, что обломает все преимущества использования.

2Taffy: ссылка от ChA очень показательна. Я тоже присоединяюсь к мнению, что UDT в их теперешней реализации неработоспособны.
26 окт 05, 15:38    [2008489]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
trayal
Member

Откуда: Пенза
Сообщений: 471
Да-а... Разгромили UDT в пух и прах...
А я их юзаю по полной программе :(
С одной стороны, неудобств много у них (нельзя использовать во врем. таблицах, гемор при смене типа...).
Но с другой стороны, они же вносят упорядоченность в разработку... Например, удобно использовать тип Tсущность_id вместо того, чтобы вспоминать, а какой же целочисленный тип надо использовать.
Или это решается документированием разработки? Или как-то еще?
26 окт 05, 18:38    [2009606]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
а INSTEAD OF триггера то в чем провинились?
26 окт 05, 18:52    [2009662]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
2trayal: угу. Потому и использую их. Несмотря на все заморочки.

2SergSuper: пример - имеем INSTEAD OF UPDATE триггер. На таблицу, не на вьюшку даже. В нем какие-то действия, а потом нужен апдейт базовой таблицы. Причем проапдейтить надо только те поля, которые участвовали в исходном апдейте. Как? Ну допустим, проверю я через columns_updated или if update(), какие поля менялись. Дальше мне надо сформировать стейтмент на обновление базовой таблицы. Как? Динамическим sql'ем? Или перечислять ВСЕ поля? А мне нужно только изменившиеся.
26 окт 05, 19:09    [2009710]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
GreenSunrise


2SergSuper: пример - имеем INSTEAD OF UPDATE триггер. На таблицу, не на вьюшку даже. В нем какие-то действия, а потом нужен апдейт базовой таблицы. Причем проапдейтить надо только те поля, которые участвовали в исходном апдейте. Как? Ну допустим, проверю я через columns_updated или if update(), какие поля менялись. Дальше мне надо сформировать стейтмент на обновление базовой таблицы. Как? Динамическим sql'ем? Или перечислять ВСЕ поля? А мне нужно только изменившиеся.

Ну если из-за такой фигни считать это неюзабельными... тогда сдаюсь.
(я бы не задумывался, все поля менял :)
27 окт 05, 14:01    [2012443]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Это вам фигня. А у меня логгирование на таблицах стоит, причем логгирование ТОЛЬКО изменившихся полей. Поэтому для меня перечисление ВСЕХ как раз неюзабельно совершенно.
27 окт 05, 14:04    [2012462]     Ответить | Цитировать Сообщить модератору
 Re: Как поломать consistency для системных таблиц  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Про INSTEAD OF триггеры лучше обсудить в отдельном топике вопрос:
https://www.sql.ru/forum/actualthread.aspx?tid=229723

Очень волнующий меня вопрос!
27 окт 05, 15:53    [2013091]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Как поломать consistency для системных таблиц  [new]
Павел Малежик
Member

Откуда: Киев
Сообщений: 6
GreenSunrise,

Каким образом можно поставить журналирование по только измененным полям?
26 окт 09, 12:28    [7837736]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить