Сессионные глобальные временные таблицы в SQL Server

В SQL Server временные таблицы с именем типа #temp имеют локальную область. Если вы создаете их в своем сеансе, все в вашем сеансе может видеть их, но не за пределами вашего сеанса. Если вы создаете такую ​​таблицу в хранимой процедуре, область действия является локальной для этой процедуры. Поэтому, когда процесс завершается, таблица исчезает.

Единственная альтернатива, о которой я знаю, - это использовать таблицы с таким именем, как ##temp. Это временные, но видимые для всего сервера. Так что, если я создам стол в своем сеансе, Боб в соседнем офисе также увидит их.

То, что я ищу, находится где-то посередине, поэтому я могу создать таблицу в хранимой процедуре и сделать эту таблицу доступной для моего сеанса даже после выхода из хранимой процедуры. Самое близкое, что мне удалось найти, - это создать таблицу только с одним полем и затем изменить ее в сохраненном процессе. Хотя это кажется чем-то вроде клуджа.

4 ответа

Решение

Не могли бы вы создать таблицу при запуске сеанса, затем выполнить хранимый процесс, а затем делать все, что вы хотите сделать с таблицей после выполнения хранимого процесса?

Еще один ключ, который может работать на вас - это зависит от того, сколько временных таблиц задействовано здесь.

Создайте ваши временные таблицы как реальные таблицы с дополнительным столбцом под названием SPID, по умолчанию @@SPID,

Затем создайте представление, которое обращается к этим таблицам, но фильтры на основе @@SPID значение. Все операции, выполняемые через это представление, должны выглядеть так, как будто они изолированы для каждой сессии. Например:

create table temp_Boris (
    SPID int default @@SPID,
    ColA int,
    ColB varchar(10)
)
go
create view vBoris
as
    select ColA,ColB from temp_Boris where SPID = @@SPID
go

Затем на одном соединении выполните следующее:

insert into vBoris(ColA,ColB)
select 10,'abc' union all
select 20,'def'
go
select * from vBoris

И на другом соединении выполните следующее:

insert into vBoris(ColA,ColB)
select 10,'abc' union all
select 20,'def'
go
select * from vBoris
select * from temp_Boris
go
delete from vBoris
go
select * from vBoris
select * from temp_Boris

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

Хорошо, я признаю, это тоже ужасно.

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

Другими словами, с точки зрения результата и вызова вызов хранимой процедуры должен быть без сохранения состояния. Если данные являются частными для сеанса, они должны быть в клиенте. Это позволяет избежать использования ресурсов сервера и означает, что вам не нужно держать соединение открытым между вызовами

Сказав это, вы можете сохранить небольшие объемы (128 байт) данных в открытом соединении для этого соединения только с помощью CONTEXT_INFO.

Я не думаю, что есть готовое решение на сервере SQL для того, что вам нужно. я думаю, что единственный способ - управлять им самостоятельно. Допустимо ли создавать обычную таблицу с некоторым суффиксом вместо таблицы blobal (где у вас есть контроль над ее полным именем)? поскольку глобальные таблицы идут в базу данных tempdb, это также поможет вам изолировать данные в вашей базе данных в качестве побочного эффекта.

Другие вопросы по тегам