переменная определенного пользователем типа не очищает значение внутри транзакции - PullRequest
1 голос
/ 09 марта 2012

У меня есть сценарий использования Временной переменной определенного пользователем типа в транзакции, но временная переменная не очищает значение внутри транзакции.

CREATE TYPE [int_list_table] AS TABLE([item_id] [int] NULL) 
GO

DECLARE @int_val BIGINT

-- Create a Temp table with 5 rows
;WITH TEMP(int_val)
AS
(SELECT 1
    UNION ALL
SELECT int_val = 1 + int_val FROM TEMP WHERE int_val < 5
)SELECT * INTO #int FROM TEMP;

SET NOCOUNT ON

DECLARE IntCursor CURSOR FAST_FORWARD FOR
SELECT int_val FROM #int

OPEN IntCursor
FETCH NEXT FROM IntCursor INTO @int_val

WHILE(@@FETCH_STATUS = 0)
BEGIN

    BEGIN TRY
        BEGIN TRANSACTION

        -- a temprory table to store the integer value
        DECLARE @table [int_list_table]
        INSERT INTO @table
        SELECT 1 WHERE 2 = @int_val         
        -- Actually @table should have resultset only at @int_val = 2, But once it filled with values even for 3 and 4
        SELECT 
            'User Table Type Value' = item_id,
            'Loop Integer Value' = @int_val
        FROM 
            @table          
        COMMIT TRANSACTION 
    END TRY    
    BEGIN CATCH
        ROLLBACK 
    END CATCH   
    FETCH NEXT FROM IntCursor INTO @int_val
END
CLOSE IntCursor
DEALLOCATE IntCursor
SET NOCOUNT OFF

Для вышеприведенного запроса выводом является

Actually it has to return only the record for 2, but it is not clearing the value once it is initialized. Please guide me to proceed further.

На самом деле он должен возвращать только запись для 2, но не очищает значение после его инициализации.Пожалуйста, направьте меня, чтобы продолжить.

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Объявление типа данных не очищает содержимое таблицы. Как только переменная таблицы будет там, она будет иметь все, что вы положили в нее. Выполнение кода даже не должно проходить место, где объявлена ​​переменная. Это также будет работать.

 if 0 = 1
 begin
   DECLARE @table [int_list_table]
 end 

Вам нужно только убедиться, что объявление находится перед любыми ссылками на переменную.

Чтобы исправить код так, чтобы он делал то, что вам нужно, вы, конечно, можете добавить delete from @table непосредственно перед оператором вставки.

1 голос
/ 09 марта 2012

Из документации по TSQL variables;

Область действия переменной длится с момента ее объявления до конца пакета или хранимой процедуры, в которой онаобъявляется.

Поскольку весь ваш пример, насколько я могу судить, представляет собой один пакет, ваша переменная @table никогда не выходит из области видимости и поэтому сохраняет свои значения до конца пакета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...