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

Откуда: Москва
Сообщений: 2646
Интересная статья про временные таблицы.

(убрать в слове D_ROP подчеркивание, без этого не отправлялось)
USE tempdb
GO

IF OBJECT_ID('tempdb..#T') IS NOT NULL D_ROP TABLE #T
IF OBJECT_ID('T', 'U') IS NOT NULL D_ROP TABLE T
GO
-- создаем таблицу, чтобы на ней создать триггер
CREATE TABLE t (a int)
GO
----------------------------------------------------------------
IF object_id ('tr_t') IS NULL
EXEC ('CREATE TRIGGER tr_t ON T FOR INSERT as return')

GO
ALTER TRIGGER tr_t ON T FOR INSERT, UPDATE, DELETE
AS
    CREATE TABLE #T (a int, b varchar(10))
    
    INSERT #T (a, b)
    SELECT 2, 'asd7'
    
    SELECT * FROM #T
    RETURN
----------------------------------------------------------------    
GO

IF OBJECT_ID('tempdb..#T') IS NULL
    --CREATE TABLE #T (a int, b varchar(10))          -- 1) так работает, т.к. таблицы #T одинаковы
     CREATE TABLE #T (c int, b varchar(10))           -- 2) так не работает
     --CREATE TABLE #T (a int, d varchar(10))           -- 3) так не работает
     --CREATE TABLE #T (a int, c int, b varchar(10))    -- 4) так работает
   

INSERT t (a) SELECT 1

--Msg 207, Level 16, State 1, Procedure tr_t, Line 4
--Invalid column name 'a'.


Почему-то вариант 2 и 3 (см. код) не работает. Сервер хочет, чтобы совпадали названия полей.
7 ноя 12, 15:18    [13433645]     Ответить | Цитировать Сообщить модератору
 Re: конфликт временных таблиц с одинаковыми именами, интересное поведение (ms sql 2005)  [new]
Crimean
Member

Откуда:
Сообщений: 13147
в ms sql спокойно можно делать так:

create proc p1
as
create table #t1 ()
exec p2
...
create proc p2
as
select ... from #t1


от этого все беды. это и хорошо и плохо одновременно. хорошо - дает возможность передачи массивов данных между хранимками ибо "insert exec cant be nested". плохо - в случае "внезапного" совпадения имен временных объектов в стеке вызова хранимок можно "влететь", причем после очень долго искать причину

p.s.

ну а времянки в триггере - зло достаточно большое
7 ноя 12, 15:31    [13433769]     Ответить | Цитировать Сообщить модератору
 Re: конфликт временных таблиц с одинаковыми именами, интересное поведение (ms sql 2005)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37254
А вы отвыкайте во всех местах делать времянку с одним и тем же именем. Внесите в имя хотя бы имя процедуры или триггера, и не будет таких проблем.

Сообщение было отредактировано: 7 ноя 12, 15:42
7 ноя 12, 15:42    [13433881]     Ответить | Цитировать Сообщить модератору
 Re: конфликт временных таблиц с одинаковыми именами, интересное поведение (ms sql 2005)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31912
trew
Почему-то вариант 2 и 3 (см. код) не работает. Сервер хочет, чтобы совпадали названия полей.
Да, всегда было такое поведение...
7 ноя 12, 15:43    [13433889]     Ответить | Цитировать Сообщить модератору
 Re: конфликт временных таблиц с одинаковыми именами, интересное поведение (ms sql 2005)  [new]
Glory
Member

Откуда:
Сообщений: 104751
trew
Почему-то вариант 2 и 3 (см. код) не работает. Сервер хочет, чтобы совпадали названия полей.

Когда триггер компилируется, то уже существует таблица #T, созданная до этого.
Поэтому план составляется с учетом структуры этой таблицы. А не таблицы #T, которая будет создана внутри триггера

так
ALTER TRIGGER tr_t ON T FOR INSERT, UPDATE, DELETE
AS
    CREATE TABLE #T (a int, b varchar(10))
    
    EXEC('INSERT #T (a, b)  SELECT 2, ''asd7''')
    
    SELECT * FROM #T
    RETURN
7 ноя 12, 16:34    [13434387]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить