2013-02-19 9 views
5

Dlaczego Deklaruję tę samą nazwę zmiennej w pętli, ale nie dozwolone bez pętli?Zmienna serwera SQL: pętla kontra duplikat?

DECLARE @loop INT 

SET @loop = 0 

WHILE @loop<5 
BEGIN 
    DECLARE @t INT -- <-- This is called multiple times 
    SET @t = 1 
    SET @loop = @loop+1 
    SELECT @loop 
END 
  • ten wykona: 1,2,3,4,5

natomiast to:

DECLARE @t INT 
    SET @t = 1 
    DECLARE @t INT 
    SET @t = 1 

będzie oczywiście powiedzieć:

  • The Nazwa zmiennej "@ t" została już zadeklarowana.

Odpowiedz

6

Umieszczenie DECLARE ma znaczenia (z wyjątkiem parser nie będzie można spróbować użyć go przed DECLARE)

To tylko faktycznie deklaruje jedna zmienna, niezależnie od tego, ile razy bloku kod zawierający deklarację jest wykonywany.

Instrukcja DECLARE nie jest instrukcją wykonywaną. na przykład

IF 1 = 0 
BEGIN 
DECLARE @I INT 
END 

SELECT @I 

Działa dobrze, mimo że ten blok nigdy nie został wprowadzony. Pamięć dla zmiennych jest zarezerwowana w czasie kompilacji, zanim wykonanie zapytania zaczyna się w execution context.

Jednym ze sposobów widząc to

DBCC FREEPROCCACHE; 

GO 

SELECT m2.pages_allocated_count 
     --If 2012 use the next line instead 
     --,m2.pages_in_bytes/m2.page_size_in_bytes as pages_allocated_count 
     ,m2.page_size_in_bytes 
FROM sys.dm_exec_cached_plans cp 
     CROSS apply sys.dm_exec_sql_text(cp.plan_handle) t 
     JOIN sys.dm_os_memory_objects m1 ON m1.memory_object_address = cp.memory_object_address 
     JOIN sys.dm_os_memory_objects m2 ON m1.page_allocator_address = m2.page_allocator_address 
WHERE text LIKE '%this query%' 
AND m2.type = 'MEMOBJ_EXECUTE' 

DECLARE @A0 VARCHAR(8000); 
DECLARE @A1 VARCHAR(8000); 
DECLARE @A2 VARCHAR(8000); 
DECLARE @A3 VARCHAR(8000); 
DECLARE @A4 VARCHAR(8000); 
DECLARE @A5 VARCHAR(8000); 
DECLARE @A6 VARCHAR(8000); 
DECLARE @A7 VARCHAR(8000); 
DECLARE @A8 VARCHAR(8000); 
DECLARE @A9 VARCHAR(8000); 
DECLARE @A10 VARCHAR(8000); 
DECLARE @A11 VARCHAR(8000); 
DECLARE @A12 VARCHAR(8000); 
DECLARE @A13 VARCHAR(8000); 
DECLARE @A14 VARCHAR(8000); 
DECLARE @A15 VARCHAR(8000); 
DECLARE @A16 VARCHAR(8000); 
DECLARE @A17 VARCHAR(8000); 
DECLARE @A18 VARCHAR(8000); 
DECLARE @A19 VARCHAR(8000); 
DECLARE @A20 VARCHAR(8000); 

który pokazuje pamięć zarezerwowaną dla aktualnego zapytania, jeśli dostosować liczbę zmiennych deklarowanych widać zmianę pamięci zarezerwowana chociaż blok DECLARE jest tuż przy koniec partii.

+0

w pętli while zadeklaruje zmienną '@ t' 5 razy? – vikas

+0

@vikas - Nie. Wyrażenia 'DECLARE' nic nie robią w czasie wykonywania. W taki sam sposób, jak w przykładowym kodzie w mojej odpowiedzi, blok jest wykonywany 0 razy, ale zmienna jest nadal faktycznie zadeklarowana. –

+0

jak deklaracja zmiennych wewnątrz pętli for w C#, lub coś innego – vikas