5

ループ内で同じ変数名を宣言できるのに、ループなしでは許可されないのはなぜですか

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
  • これは実行されます:1、2、3、4、5

この間:

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

明らかに言うでしょう:

  • 変数名'@t'はすでに宣言されています。
4

1 に答える 1

6

の配置DECLAREは重要ではありません (ただし、パーサーは の前にそれを試して使用することを許可しませんDECLARE) 。

宣言を含むコードのブロックが実行される回数に関係なく、実際には 1 つの変数のみを宣言します。

それDECLARE自体は実行可能なステートメントではありません。例えば

IF 1 = 0
BEGIN
DECLARE @I INT
END

SELECT @I

そのブロックが入力されていなくても正常に動作します。変数のメモリは、クエリの実行が実行コンテキストで開始される前のコンパイル時に予約されます。

これを見る一つの方法は、

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);

DECLAREこれは、現在のクエリ用に予約されているメモリを示しています。宣言された変数の数を調整すると、ブロックがバッチの最後にある場合でも、メモリ予約の変更が表示されます。

于 2013-02-19T17:40:03.610 に答える