Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Dependencies tracking & case-sensitive collation  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6203
Дано:
select @@version

------------------------------------------------------------------------
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86)
Jun 17 2011 00:57:23
Copyright (c) Microsoft Corporation
Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

Далее:
USE [master]
GO
create database Test
collate SQL_Latin1_General_CP1251_CS_AS -- case-sensitive collation

use Test
go
create table dbo.Foo (n int)
go

create procedure dbo.up_foo
as
begin
  select * from dbo.foo;
  select * from dbo.FOO;
end
go

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.Foo', 'OBJECT')

(0 row(s) affected)

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.foo', 'OBJECT')

(0 row(s) affected)

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.FOO', 'OBJECT')

(0 row(s) affected)

alter procedure dbo.up_foo
as
begin
  select * from dbo.foo;
  select * from dbo.FOO;
  select * from dbo.Foo;
end
go

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.Foo', 'OBJECT')

referencing_entity_name
-------------------------
up_foo

(1 row(s) affected)

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.foo', 'OBJECT')

(0 row(s) affected)

select referencing_entity_name from sys.dm_sql_referencing_entities(N'dbo.FOO', 'OBJECT')

(0 row(s) affected)

Смотрим в документацию:
For example, if a stored procedure references the entities Some_Table and SOME_TABLE in a database that uses a case-sensitive collation, dependency information for two entities is recorded because a comparison of the two names indicates that they are not the same.

(http://technet.microsoft.com/en-us/library/ms345449(v=sql.105).aspx)

Т.е. согласно документации, должно быть 2(3) записи о зависимостях, и, как я предположил, 2 (3) записи в результате запроса к sys.dm_sql_referencing_entities. Однако до тех пор, пока мы не упомянули таблицу в том регистре, в котором она была создана, функция не выдавала ни одной записи, после упоминания - только одну. В sys.sql_dependencies результаты и поведение аналогичное. Что тут не так?
20 дек 13, 07:37    [15321153]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Сон Веры Павловны,

есть какая-то настройка серверная - типа выставляется на сервере - которая разруливает является ли большие и маленькие буквы - одним и тем же для сравнения или нет.

в sys.sql_dependencies - аналогично быть не может ибо там нет имен объектов - там только object_id.

если там связи нет - а по смыслу она должна быть - то можно посмотреть вот тут.
20 дек 13, 07:51    [15321173]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6203
Решил ради интереса посмотреть внутрь sys.dm_sql_referencing_entities:
ALTER FUNCTION sys.dm_sql_referencing_entities(@name nvarchar(517), @referenced_class nvarchar(60))
	RETURNS TABLE
	AS		   
	RETURN 
		SELECT DISTINCT
			d.referencing_schema_name as referencing_schema_name,
			d.referencing_entity_name as referencing_entity_name,
			d.referencing_id as referencing_id, 
			d.referencing_class as referencing_class, 
			d.referencing_class_desc as referencing_class_desc, 
			d.is_caller_dependent as is_caller_dependent 
		FROM sys.sql_expression_dependencies$ as d 
		WHERE d.referenced_class = 	CASE LOWER (@referenced_class collate Latin1_General_CI_AS) 
									WHEN N'object' THEN 1 
									WHEN N'type' THEN 6
									WHEN N'xml_schema_collection' THEN 10 
									WHEN N'partition_function' THEN 21 
									ELSE 0 END
			AND d.referenced_entity_name = parsename(@name, 1)
			AND 
			(-- Match by id (if caller dependent, then id will be NULL)
			d.referenced_id = entity_id(parsename(@name, 4), 
						parsename(@name, 3), 
						parsename(@name, 2), 
						parsename(@name, 1), 
						CASE LOWER (@referenced_class collate Latin1_General_CI_AS)
						WHEN N'object' THEN 1
						WHEN N'type' THEN 6 
						WHEN N'xml_schema_collection' THEN 10 
						WHEN N'partition_function' THEN 21 
						ELSE 0 
						END,
						0, 
						NULL)
			OR
			-- Match by name if caller dependent ref. and the referencing object is on this server in the current DB. 
			-- This will show all possible caller dependent references on the given object. 
			((d.is_caller_dependent = 1 AND 
				(d.referenced_database_name IS NULL OR
					((d.referenced_server_name IS NULL OR d.referenced_server_name = @@SERVERNAME) AND (d.referenced_database_name = N'' OR d.referenced_database_name = DB_NAME()))))
			))
			AND -- caller needs to have CONTROL permission on the referenced entity
				CASE LOWER (@referenced_class collate Latin1_General_CI_AS)
				WHEN N'object' THEN has_perms_by_name(@name, 'OBJECT', 'CONTROL')
				WHEN N'type' THEN has_perms_by_name(@name, 'TYPE', 'CONTROL')
				WHEN N'xml_schema_collection' THEN has_perms_by_name(@name, 'XML SCHEMA COLLECTION', 'CONTROL')
				WHEN N'partition_function' THEN has_perms_by_name(quotename(db_name()), 'DATABASE', 'CONTROL')
				ELSE 0
				END = 1

И далее
select referenced_entity_name, referenced_id from sys.sql_expression_dependencies

referenced_entity_name     referenced_id
-------------------------- -------------
foo NULL
Foo 2105058535
FOO NULL

Получается, что в документации всё правильно, записей действительно по одной штуке на каждое раздельное наименование в разном регистре. Только вот для наименований в регистре, отличном от регистра создания, не получилось определить referenced_id, и функция выдала пустой результат, т.к. использует условие по referenced_id. Баг? Следствие того, что
Unlike earlier versions of SQL Server, in which dependencies were tracked by ID, dependencies are now tracked by name. This means that the Database Engine tracks dependency information between two entities even if the referenced entity does not exist at the time the referencing entity is created. This circumstance can occur because of deferred name resolution.

?
(по ссылке из предыдущего постинга (в конец ссылки затесалась круглая скобка, которой там не должно быть))
20 дек 13, 07:52    [15321174]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6203
Jaffar
в sys.sql_dependencies - аналогично быть не может ибо там нет имен объектов - там только object_id.

Подразумевалось, что sql_dependencies пусто до тех пор, пока мы в процедуре не упомянем объект в том регистре, в котором он был создан. Тогда появляется 1 запись.

Jaffar
если там связи нет - а по смыслу она должна быть - то можно посмотреть вот тут.

Так это же, насколько я понял ситуацию, и есть косяк с разрешением deferred names resolution, которм чревато определение зависимостей по sql_dependencies/sp_depends. И появившиеся в 2008-й версии dm_sql_referencing_entities/dm_sql_referenced_entities как раз deferred names resolution успешно разрешают. Только ценой чувствительности к регистру.
20 дек 13, 08:02    [15321184]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Сон Веры Павловны,


все таки вы посмотрите на счет параметра определяющего равенство регистров.

что-то типа

select 123
where
'A' = 'a'
20 дек 13, 13:07    [15322714]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Сон Веры Павловны
Member

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

вообще-то это и есть collation
20 дек 13, 13:12    [15322758]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
o-o
Guest
Сон Веры Павловны
Так это же, насколько я понял ситуацию, и есть косяк с разрешением deferred names resolution, которм чревато определение зависимостей по sql_dependencies/sp_depends. И появившиеся в 2008-й версии dm_sql_referencing_entities/dm_sql_referenced_entities как раз deferred names resolution успешно разрешают. Только ценой чувствительности к регистру.


погодите, а в чем заключается "Только ценой чувствительности к регистру"?
про косяк с отложенным разрешением имен ок,
а при чем тут регистрозависимость?
20 дек 13, 13:45    [15323094]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
o-o
Guest
Сон Веры Павловны
referenced_entity_name     referenced_id
-------------------------- -------------
foo NULL
Foo 2105058535
FOO NULL

Получается, что в документации всё правильно, записей действительно по одной штуке на каждое раздельное наименование в разном регистре. Только вот для наименований в регистре, отличном от регистра создания, не получилось определить referenced_id, и функция выдала пустой результат, т.к. использует условие по referenced_id. Баг?


почему баг-то?
у Вас создана всего ОДНА таблица, это таблица Foo.
другие 2 -- НЕ СОЗДАНЫ.
Вы же создаете таблицы в рагистрозависимой базе,
объекты foo, Foo, FOO -- это не 1, это 3 разных объекта.
из них создан и имеется только один (Foo), остальные два только упомянуты,
поэтому у них id это NULL, они же не существуют.
досоздайте foo, FOO, получите 3 разных объекта с тремя разными id
20 дек 13, 13:57    [15323173]     Ответить | Цитировать Сообщить модератору
 Re: Dependencies tracking & case-sensitive collation  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6203
o-o
объекты foo, Foo, FOO -- это не 1, это 3 разных объекта.

Эмм.. да. Вот где я ошибался - полагал, что регистрозависимость collation распространяется только на операции со строками - а она распространяется и на именования объектов:
select * from dbo.Foo

(0 row(s) affected)
select * from dbo.foo

Msg 208, Level 16, State 1, Line 1
Invalid object name 'ggg'.
create table dbo.foo (n int)

Command(s) completed successfully.

Спасибо, вопрос исчерпан.
20 дек 13, 14:42    [15323529]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить