Подтвердить что ты не робот

Временные таблицы в хранимых процедурах

Мне было интересно о временных таблицах в sp и о том, как все это может повлиять на concurrency. SP, сделанный на сервере MSSQL 08.

Если у меня есть SP, где я создаю временную таблицу и снова ее возвращаю следующим образом:

BEGIN

CREATE TABLE #MyTempTable
(
   someField int,
   someFieldMore nvarchar(50)
)

... Use of temp table here
... And then..

DROP TABLE #MyTempTable

END

Этот SP будет вызван очень часто, поэтому мой вопрос в том, могут ли возникать проблемы concurrency здесь?

4b9b3361

Ответ 1

Неа. Независимые экземпляры временной таблицы будут созданы для каждого подключения.

Ответ 2

Может быть.

Временные таблицы с префиксом # (# пример) хранятся в каждом сеансе. Поэтому, если ваш код снова вызывает хранимую процедуру, когда выполняется другой вызов (например, фоновые потоки), вызов create завершится неудачно, поскольку он уже существует.

Если вы действительно беспокоитесь, используйте вместо этого переменную таблицы

DECLARE @MyTempTable TABLE 
(
   someField int,
   someFieldMore nvarchar(50)
)

Это будет специфично для "экземпляра" этого вызова хранимой процедуры.

Ответ 3

Не совсем, и я говорю о SQL Server. Временная таблица (с единственным #) существует и видна в пределах области, в которой она создана (с привязкой к области). Каждый раз, когда вы вызываете свою хранимую процедуру, создается новая область, и поэтому временная таблица существует только в этой области. Я считаю, что временные таблицы также видны хранимым процедурам и udfs, которые также вызываются в пределах этой области. Если вы, однако, используете double pound (##), то они становятся глобальными в пределах вашего сеанса и поэтому видны другим исполняемым процессам как часть сеанса, в котором создана временная таблица, и вам придется подумать, есть ли возможность доступа к таблице temp одновременно желательно или нет.

Ответ 4

Для всех тех, кто рекомендует использовать переменные таблицы, будьте осторожны при этом. Переменная таблицы не может быть проиндексирована, тогда как временная таблица может быть. Переменная таблицы лучше всего подходит для работы с небольшими объемами данных, но если вы работаете с более крупными наборами данных (например, 50 тыс. Записей), то временная таблица будет намного быстрее, чем табличная переменная.

Также имейте в виду, что вы не можете полагаться на try/catch, чтобы принудительно очистить хранимую процедуру. определенные типы сбоев не могут быть пойманы в попытке/уловке (например, сбои компиляции из-за отложенного разрешения имен), если вы действительно уверены, что вам может понадобиться создать хранимую процедуру-оболочку, которая может выполнить попытку/улов хранимой процедуры работника и выполните очистку там.

например.   создать proc worker AS   НАЧАТЬ       - сделайте что-нибудь здесь   END

create proc wrapper AS
BEGIN
    Create table #...
    BEGIN TRY
       exec worker
       exec worker2 -- using same temp table
       -- etc
    END TRY
    END CATCH
       -- handle transaction cleanup here
       drop table #...
    END CATCH 
END

Ответ 5

В соответствии с документами SQL Server 2008 Вы можете создавать локальные и глобальные временные таблицы. Локальные временные таблицы видны только в текущем сеансе, а глобальные временные таблицы видны для всех сеансов.

'# table_temporal

'## table_global

Если локальная временная таблица создается в хранимой процедуре или приложении, которые могут выполняться одновременно несколькими пользователями, то механизм Database Engine должен иметь возможность отличать таблицы, созданные разными пользователями. Механизм Database делает это, внутренне добавляя числовой суффикс к каждому локальному временному имени таблицы.

Тогда проблем не возникает.

Ответ 6

База данных использует ту же блокировку для всех таблиц #temp, поэтому, если вы используете много, вы столкнетесь с проблемами взаимоблокировки. Лучше использовать переменные @table для concurrency.

Ответ 7

Используйте таблицы @temp, когда это возможно, то есть вам нужен только один первичный ключ, и вам не нужно получать доступ к данным из подчиненного сохраненного процесса.

Используйте таблицы #temp, если вам нужно получить доступ к данным из подчиненного хранимого proc (это злая глобальная переменная для сохраненной цепочки вызовов proc), и у вас нет другого чистого способа передачи данных между хранимыми процедурами. Также используйте его, если вам нужен вторичный индекс (хотя, действительно спросите себя, если это таблица #temp, если вам нужно больше одного индекса)

Если вы это сделаете, всегда объявляйте таблицу #temp в верхней части функции. SQL заставит перекомпилировать ваш сохраненный proc, когда он увидит инструкцию create table.... так что если у вас есть объявление таблицы #temp в середине хранимой процедуры, вы запомнили, что proc должен прекратить обработку и перекомпилировать.