2012-11-05 16 views
7

dlaczego ta praca kod bez problemu:Różnica między tabelami i tabel Temp

drop table t1 
select * into t1 from master..spt_values 
drop table t1 
select * into t1 from master..spt_values 

Output

Msg 3701, Level 11, State 5, Line 1 
Cannot drop the table 't1', because it does not exist or you do not have permission. 

(2508 row(s) affected) 

(2508 row(s) affected) 

ale ten kod nie działa:

drop table #t1 
select * into #t1 from master..spt_values 
drop table #t1 
select * into #t1 from master..spt_values 

Wyjście

Msg 2714, Level 16, State 1, Line 4 
There is already an object named '#t1' in the database. 

jaka jest różnica między tabelami i tabelami temperatur w tym kodzie?

+3

Dobre pytanie. Aby lepiej zilustrować twój punkt [ten SQLFiddle] (http://sqlfiddle.com/#!3/d41d8/5748) nie działa, ale zastąpienie zwykłymi tabelami robi – RichardTheKiwi

+4

[Wyjaśnienie tego zachowania jest tutaj] (http: //sqlblog.com/blogs/michael_zilberstein/archive/2008/08/28/Name-resolution-in-SQL-Server.aspx) Dla 't1' instrukcje podlegają odroczonej kompilacji, ale tak nie jest w przypadku' # t1 ' –

+0

Tak samo, jak na marginesie" [DROP TABLE i CREATE TABLE nie powinny być wykonywane w tej samej tabeli w tej samej partii. W przeciwnym razie może wystąpić nieoczekiwany błąd.] (http://msdn.microsoft.com/en-us/ library/ms173790.aspx) " –

Odpowiedz

4

Aby przeciwdziałać wszelkie inne złe odpowiedzi, prawidłowa droga do testowania tabeli #temp jest

if object_id('tempdb..#temp') is not null 
    drop table #temp; 


Oto interesting article o fazie kompilacji i wykonanie fazy zabawy z tabelami #temp.


To jest numer referencyjny MSDN dla Deferred Name Resolution (DNR). Aby pomóc w tworzeniu procedur i zestawieniach procedur przechowywanych w pamięci podręcznej, w SQL Serverze 7 dodano funkcję dodawania Deferred Name Resolution. Wcześniej (bardzo trudno byłoby utworzyć i używać tabel w partii bez użycia dużej ilości dynamicznego kodu SQL).

Istnieją jednak ograniczenia w tym, że jeśli istnieje nazwa , SQL Server przejdzie dalej i sprawdzi inne aspekty instrukcji, takie jak nazwy kolumn obiektów tabel. DNR nigdy nie był rozszerzany na zmienne ani tymczasowe (#)/(##) obiekty, a gdy wbudowane funkcje zostały dodane do SQL Server 2000, DNR nie został rozszerzony do nich, ponieważ celem DNR było tylko - problem z wsadowym plikiem wsadowym. Nie mylić, inline funkcje o wartości tabelarycznej nie obsługują DNR; multi-statement TVFs zrobić.

Obejście problemu NIE polega na używaniu tego wzoru, a zamiast tego na utworzeniu tabeli najpierw i tylko raz.

-- drop if exists 
if object_id('tempdb..#t1') is not null 
    drop table #t1; 
-- create table ONCE only 
select * into #t1 from master..spt_values where 1=0; 
-- .... 
-- populate 
insert #t1 
select * from master..spt_values 
-- as quick as drop 
truncate table #t1; 
-- populate 
insert #t1 
select * from master..spt_values 
-- as quick as drop 
truncate table #t1; 

-- clean up 
drop table #t1; 
+0

to nie działa, testuję wszystkie te sposoby zanim zapytam tutaj ... – NeatAttack

+0

@Neat Jeśli masz na myśli w kontekście partii bez' GO', to tak, tak nie robi ' t pracują nad rozwiązaniem problemu z kompilacją. Podnoszę odpowiedź, ponieważ wszystkie pozostałe testy są po prostu błędne. – RichardTheKiwi

+0

Czy jest tu jakiś powód do łączenia połączeń? Wszystko, co widziałem w Internecie, mówi, że zostały usunięte po zresetowaniu połączenia. –

Powiązane problemy