2010-09-10 6 views
5

В Oracle, вы можете создать временную таблицу, используя что-то вроде:SQL Server/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, как описано выше? Или это единственный способ работы с временными данными, связанный с необходимостью повторно создавать временную таблицу с каждой итерацией работы?

+0

Можете ли вы объяснить, почему вы хотели бы имитировать поведение Oracle в SQLServer? Следует ли просто избегать требования выполнить инструкцию CREATE TABLE? –

+0

@Mark ~ хорошо, это в первую очередь. Но если бы я имел дело с (1) повторяющимися вставками временных данных, (2) с обычно одним и тем же форматом данных и полями, (3) и уникален для пользователя (т. Е. Данные являются частными для пользовательского сеанса), он просто делает намного больше смысл обрабатывать все это в таблице в соответствии с реализацией Oracle. :) –

+0

[Частные временные таблицы Oracle] (https://stackoverflow.com/a/48852466/5070879) – lad2025

ответ

9

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

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

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

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

EDIT: Еще одна разница между Oracle и SQL Server заключается в том, что SQL Server позволяет обменивать DDL в транзакцию с другими операторами. Поэтому, если вам нужно использовать временную таблицу как часть более крупной транзакции, оператор create table #table_name... не будет неявно совершать текущую транзакцию, как оператор create table в Oracle.

+0

~ Точно так же я не мог окунуться в SQL Server ## temp_tables. :) По общему признанию, я предпочел бы реализацию в соответствии с Oracle, но если это просто невозможно в SQL Server, то ваши предложения/предложения кажутся наиболее полезными. Благодаря! +1 –

+0

У меня есть сотрудник, который нашел использование для ## temp_tables - он использует SSIS для некоторых процессов, и если вы используете ## в одном proc и этот proc вызывает другой proc, proC# 2 может использовать ## temp_table. – user158017

+0

@sql_mommy: У меня был сотрудник, который сделал аналогичную вещь, в том, что они использовали таблицы ## для использования по сравнению с procs. Однако у них не было возможности остановить конечных пользователей от запуска того же процесса, в то время как кто-то еще уже работал, поэтому риск того, что работа двух пользователей будет смешиваться вместе в глобальной таблице темп. Мы переместили определения таблицы temp в верхний proc, поэтому все вызванные procs могли видеть их и создавать локальные таблицы temp. Для SSIS, если это пакетный процесс, который запускается заданием, возможно, ОК. –

1

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

select * 
into #temp_table 
from mytable 
+0

Yup, я сделал. Спасибо, что указали на это. –

1

Temp таблицы в 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 
Смежные вопросы