Глобальные временные таблицы - SQL Server против Oracle - PullRequest
5 голосов
/ 18 января 2012

Я использую глобальные временные таблицы Oracle 11g, поскольку мне нужно решение, в котором я могу добавить строки во временную таблицу для объединения, и я хочу, чтобы были включены только строки, добавленные во временную таблицу для соединения / сеанса Oracle. Я использую Global Temp Table в Oracle, потому что я хочу, чтобы таблица существовала между сессиями, поэтому ее не нужно создавать заново каждый раз, когда я создаю запрос. Это работает хорошо.

Мое определение таблицы Oracle выглядит следующим образом:

CREATE GLOBAL TEMPORARY TABLE book_id_temp 
( 
   book_id RAW(32)
)ON COMMIT DELETE ROWS;

У меня такая же структура базы данных также на стороне SQL Server 2008-R2, и мне нужно аналогичное решение в SQL Server. Я хочу:

  1. Открыть соединение SQL (ADO.NET)
  2. Внутри транзакции:
  3. -Добавить строки во временную таблицу.
  4. -Присоедините их к другой таблице, ВЫБЕРИТЕ результаты
  5. - В объединение должны быть включены только строки, добавленные во время этого сеанса. Другой поток может выполняться в той же временной таблице. Возможно, тогда лучше использовать локальную временную таблицу?
  6. Откат всей транзакции.

Из того, что я прочитал о глобальных временных таблицах в SQL Server, таблицы существуют после завершения соединения, как обычная таблица и как глобальная временная таблица в Oracle. Тем не менее, это не ясно, в отношении объема данных. Только ли сеанс SQL Server, который создал строки, имеет доступ к нему, как в Oracle? Какова доступность данных с помощью глобальных временных таблиц SQL Server? У вас есть предложение альтернативы для достижения моей цели?

Ответы [ 4 ]

6 голосов
/ 18 января 2012

Временные таблицы в Oracle - это постоянные объекты, которые содержат временные данные локально для сеанса.Временные таблицы в SQL Server являются временными объектами.

  1. В SQL Server глобальная временная таблица содержит данные, видимые для всех сеансов.«Глобальные временные таблицы видны любому пользователю и любому соединению после их создания».http://msdn.microsoft.com/en-us/library/ms186986.aspx
  2. Глобальные временные таблицы все еще являются временными объектами, которые не сохраняются бесконечно, и, возможно, их необходимо будет создать перед использованием.«Глобальные временные таблицы ... удаляются, когда все пользователи, ссылающиеся на таблицу, отключаются от экземпляра SQL Server».http://msdn.microsoft.com/en-us/library/ms186986.aspx

Я считаю, что локальная временная таблица или табличная переменная наиболее близка к глобальной временной таблице Oracle, большая разница в том, что вы должны создавать ее каждый раз.

Обычно в случае, подобном вашему, шаг 3, добавление строк в временную таблицу, выполняется с помощью select ... into #temp_table_name .... (эквивалентно Oracle create table ... as select ...) http://msdn.microsoft.com/en-us/library/ms188029.aspx

Также,Вы не можете сделать следующее в хранимой процедуре: (псевдокод.)

begin proc
   call another proc to create local temp table.
   use temp table
end proc

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

Обновление 2014-10-14: Поведение локальных временных таблиц отличается в версии SQL Server для Parallel Data Warehousev.Временные таблицы не удаляются при выходе из хранимой процедуры, которая их создала, и вместо этого продолжают существовать до конца сеанса.Такое поведение наблюдается на:

select @@version
Microsoft SQL Server 2012 - 10.0.5108.1 (X64) Jun 24 2014 20:17:02 Copyright (c) Microsoft Corporation Parallel Data Warehouse (64-bit) on Windows NT 6.2 <X64> (Build 9200: )
4 голосов
/ 18 января 2012

Временные таблицы на SQL Server являются локальными по умолчанию. Стол будет удален после окончания сеанса. Если вы выполняете скрипт как:

create table #Foo (
       FooID  int
      ,FooCode1  varchar (20)
)

insert table #Foo (FooID, FooCode1)
values (1001, 'X')

insert table #Foo (FooID, FooCode1)
values (1002, 'Y')

select f.FooID
      ,f.FooCode1
      ,b.BarID
      ,b.BarCode1
  from #foo f
  join bar b
    on bar.FooID = f.FooID -- (or whatever predicate)

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

1 голос
/ 18 января 2012

Если вы создадите глобальную временную таблицу (## table) в SQL Server, она будет «жить» и будет доступна через другие сеансы, пока этот сеанс не будет закрыт. Кроме того, вы не сможете создать эту Глобальную временную таблицу с тем же именем для другого сеанса, пока не закроется исходный сеанс, вы получите, что таблица уже существует. Для вашей цели Global Temp Table не будет хорошим решением.

Локальная временная таблица (#table) была бы намного лучше и достигла того, что вы хотите сделать.

Надеюсь, это поможет

1 голос
/ 18 января 2012

Если вы вручную создаете таблицы в базе данных tempdb, вы получаете более или менее тот же эффект:

USE tempdb;

CREATE TABLE foo...

и затем обратиться к ним:

select * from tempdb..foo

Эти таблицы не будут удаляться между сеансами. Вам нужно их вручную обрезать, но нет эквивалента ON COMMIT DELETE ROWS.

...