SQL Server / Oracle: частные временные таблицы - PullRequest
5 голосов
/ 10 сентября 2010

В Oracle вы можете создать временную таблицу, используя что-то вроде:

CREATE GLOBAL TEMPORARY TABLE temp_table (
    field1 NUMBER,
    field2 NUMBER
)
ON COMMIT DELETE ROWS;

... что может быть довольно изящным, поскольку это создает таблицу, видимую всем, но данные, которые ВСТАВЛЯЕТСЯ вСтол виден только ему или ей.Кроме того, эти данные автоматически удаляются в конце транзакции или сеанса (в зависимости от их объявления), в результате чего все остальные временные данные остаются невредимыми.

Однако в SQL Server вы можете создать временную таблицу с:

CREATE TABLE #temp_table (field1 INT, field2 INT);

... что, насколько я понимаю, существенно и функционально отличается от реализации Oracle.Эта временная таблица видна только вам и отбрасывается (таблица) сразу после использования.

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

Ответы [ 3 ]

9 голосов
/ 10 сентября 2010

Как вы обнаружили, временные таблицы SQL Server и Oracle принципиально отличаются.

В Oracle глобальные временные таблицы представляют собой постоянные объекты, которые хранят данные, относящиеся к временному сеансу (или транзакции).

В SQL Server временные таблицы - это временные объекты, хранящие временные данные, с #temp_tables, хранящими данные, локальные для сеанса, и ## temp_tables, хранящими данные, которые являются глобальными. (У меня никогда не было необходимости в глобальных временных таблицах SQL Server, и я не знаю, какую проблему они решают.) Если #temp_table был создан в хранимой процедуре, он будет удален при выходе из хранимой процедуры. В противном случае он будет сброшен при закрытии сессии.

И нет, на самом деле нет способа заставить SQL Server имитировать Oracle. Вы можете использовать обычную таблицу с дополнительным столбцом, хранящим идентификатор сеанса. Но вы не получите преимуществ временных таблиц по сравнению с меньшим количеством журналирования. Вы должны были бы вручную удалить временные данные. И заниматься очисткой от сессий, которые прекращаются преждевременно.

РЕДАКТИРОВАТЬ: Другое различие между Oracle и SQL Server заключается в том, что SQL Server позволяет заключать DDL в транзакцию с другими операторами. Поэтому, если вам нужно использовать временную таблицу как часть более крупной транзакции, оператор create table #table_name... не будет неявно фиксировать текущую транзакцию, как оператор create table в Oracle.

1 голос
/ 18 ноября 2011

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

Пример ниже для финансовой отчетности PeopleSoft. Модуль бюджета (таблицы KK) и главная книга (журнал) должны иметь одинаковые сальдо для фонда после запуска интерфейса между ними. Приведенный ниже запрос суммирует суммы бюджета по фондам из таблиц KK и сохраняет их во временной таблице, затем суммирует соответствующие суммы по фондам из главной книги, а затем объединяет две таблицы предварительно суммированных данных, чтобы можно было сравнить чистую сумму на фонд из два источника - и перечисляет результаты только тогда, когда есть разница между суммами для фонда. В этом случае модули бюджета и GL не синхронизированы. На самом деле это довольно элегантное решение, и для этого запроса / отчета не было необходимости создавать глобальную временную таблицу, доступную для других.

Я надеюсь, что кто-то найдет это полезным. Это помогло мне в то время.

/*** START NESTED QUERY #1                                             ***/
/*** THE FOLLOWING CREATES TWO TEMP TABLES WITH NET AVAILABLE PER FUND ***/
/*** WITH ONE AMOUNT BASED ON KK TABLES AND ONE AMOUNT BASED ON        ***/
/*** BUDGETARY GL BALANCES. THEN TEMP TABLES ARE MERGED BY FUND AND    ***/
/*** NET DIFFERENCE CALCULATED-SELECTING  FUNDS WITH DIFFERENCES.      ***/
/*** IF BUDGET CHECKING IS COMPLETE AND JOURNALS CREATED AND POSTED    ***/
/*** THERE SHOULD BE NO DIFFERENCES.                                   ***/

--create a temp table with journal amounts summed by fund code
CREATE TABLE #JRNLsum(
FUND_CODE char(5),
JRNLAMT decimal(19,2) )
INSERT INTO #JRNLsum (FUND_CODE, JRNLAMT)
select FUND_CODE, sum(MONETARY_AMOUNT * -1) JRNLAMT 
FROM PS_JRNL_LN 
INNER JOIN PS_JRNL_HEADER 
ON PS_JRNL_LN.JOURNAL_ID = PS_JRNL_HEADER.JOURNAL_ID 
where ((ACCOUNT BETWEEN 430000 and 469999) and (FISCAL_YEAR >= '2009')) 
GROUP BY FUND_CODE order by FUND_CODE


--create a temp table with KK ledger amounts summed by fund code
CREATE TABLE #KKsum(
FUND_CODE char(5),
KKAMT decimal(19,2) )
INSERT INTO #KKsum (FUND_CODE, KKAMT) 
select FUND_CODE, sum(POSTED_TOTAL_AMT  * -1) KKAMT
from PS_LEDGER_KK where LEDGER like 'FUND_%'
group by FUND_CODE order by FUND_CODE

--join kk temp date to journal temp data, keep only
--fund code, kk net amount, and journal net amount
--and select only fund codes where there is a difference
--between kk net amount and journal net amount
select #KKsum.FUND_CODE, JRNLAMT, KKAMT from #JRNLsum
INNER JOIN #KKsum
on #KKsum.FUND_CODE=#JRNLsum.FUND_CODE 
where (JRNLAMT - KKAMT) <> 0.00


--drop the two temp tables
drop table #KKsum
drop table #JRNLsum

/*** END NESTED QUERY #1   
1 голос
/ 10 сентября 2010

Это не по теме, но знаете ли вы, что в SQL Server вы можете создать временную таблицу следующим образом:

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