Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временные таблицы и ХП / 6 сообщений из 6, страница 1 из 1
17.12.2001, 12:03
    #32019111
maximF
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
MS SQL7 SP3.
Я недавно наткнулся на новое для меня поведение временных таблиц в ХП - может кому-то ещё будет интересно.

Если процедура "а" создаёт временную таблицу #t и вызывает процедуру "аа", то "аа" видит временную таблицу #t - это понятно.
Если же процедура "аа" сама создаёт временную таблицу #t, то не возникает ошибки, и таблица образуется. По выходу из "аа" "а" видит исходную версию таблицы.
IMHO довольно нелогичное поведение.

Вот скрипт:
if exists (
select * from sysobjects
where id = object_id(N'[dbo].[a]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[a]

if exists (
select * from sysobjects
where id = object_id(N'[dbo].[aa]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[aa]
go
CREATE PROCEDURE a
AS
set nocount on
select 1 as a
into #t

exec aa
select 'a', * from #t
GO

CREATE PROCEDURE aa AS

select 'aa', * from #t
select 2 as a, 'test' as t
into #t

select 'aa', * from #t
GO

exec a

a
---- -----------
aa 1

a t
---- ----------- ----
aa 2 test

a
---- -----------
a 1
...
Рейтинг: 0 / 0
17.12.2001, 12:06
    #32019112
Tarantino
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
Почему же не логично, всё логично, в данном случае можно сказать что временная таблица это как-бы глобальная переменная.
...
Рейтинг: 0 / 0
17.12.2001, 12:48
    #32019118
maximF
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
2 Тarantino:
Если бы поведение было как у глобальных переменных, то после вызова ХП "аа" в процедуре "а" содержимое временной таблицы изменялось, а это не так.
...
Рейтинг: 0 / 0
17.12.2001, 19:43
    #32019149
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
А почему вы решили что
select 2 as a, 'test' as t into #t
есть добавление еще одной записи в существующую таблицу ?
В BOL же сказано
"The SELECT INTO statement creates a new table and populates it with the result set of the SELECT . The structure of the new table is defined by the attributes of the expressions in the select list"

Если заменить приведенную выше строку на
update #t set a = 2, то все работает правильно.

Дело в том то на самом деле временные таблицы имеют имя в виде ИмяЗаданноеПользователем+символы"_"+12значноеHexчисло (символы "_" нужны для заполнения имени до нужной длины)
Т.е. в процедуре А вы создаете временную таблицу с уникальным именен вроде такого
#t__________________________________________________________________________________________________________________0001000007AC,
!! не просто #t !!!

а в процедуре АА из-за того, что используете select ... into вы опять создаете временную процедуру с уникальным именем
#t__________________________________________________________________________________________________________________0002000007AC

т.е. никакого казалось бы ожидаемого конфликта на самом деле нет - оба объекта уникальны(для системы)
А дальше все еще проще
"A local temporary table created within a stored procedure or trigger is distinct from a temporary table with the same name created before the stored procedure or trigger is called. If a query references a temporary table, and two temporary tables with the same name exist at that time, it is not defined which table the query is resolved against. Nested stored procedures can also create temporary tables with the same name as a temporary table created by the stored procedure that called it. All references to the table name in the nested stored procedure are resolved to the table created in the nested procedure " Т.е. временная таблица номер2 внутри процедуры АА будет иметь более высокий приоритет при , т.к. создана в ней. Для того, чтобы работать со временной таблицой номер1(созданной в процедуре А), обращаться к ней нужно по полному имени.

Увидеть имена и идентификаторы ваших временных таблиц вы сможете, если добавите в ваши проверочные запросы следующие столбцы
object_id('tempdb..#t'), (select top 1 name from tempdb..sysobjects where id=object_id('tempdb..#t'))

ЗЫ
Проверял на SQL2000 SP2
...
Рейтинг: 0 / 0
18.12.2001, 17:50
    #32019247
maximF
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
2 Glory: Спасибо за подробный ответ! Мог и сам прочитать!

Собственно, нетривиальной мне показалась эта часть:
"Nested stored procedures can also create temporary tables with the same name as a temporary table created by the stored procedure that called it. All references to the table name in the nested stored procedure are resolved to the table created in the nested procedure".

Странно звучит фраза "...If a query references a temporary table, and two temporary tables with the same name exist at that time, it is not defined which table the query is resolved against. "Получается, могут быть ситуации, когда временная таблица, участвующая в запросе, выбирается случайно?
...
Рейтинг: 0 / 0
19.12.2001, 10:45
    #32019313
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временные таблицы и ХП
Насчет первой цитаты - это все-таки локальные временные таблицы. Логично, что нечто локальное имеет больший приоритет там, где оно было создано.

Насчет второй цитаты - если предположить, что триггер пытается получить id временной таблицы таким путем

select top 1 * from tempdb..sysobjects where name like '#t%' (!без order by!),

то BOL по этому поводу также ясно сказано, что при порядок вывода записей без order by непрогназируем.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временные таблицы и ХП / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]