SQL Server / Oracle:私有临时表

时间:2010-09-10 05:09:05

标签: sql oracle sql-server-2008

在Oracle中,您可以使用以下内容创建临时表:

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

...这可能非常漂亮,因为这会创建一个对所有人都可见的表,但只有他或她才能看到INSERT进入表中的数据。此外,该数据会在事务或会话结束时自动删除(取决于其声明),使其他人的临时数据不受伤害。

但是,在SQL Server中,您可以使用以下命令创建临时表:

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

......据我所知,它与Oracle的实施在本质上和功能上有所不同。此临时表仅对您可见,并在使用后立即删除(表)。

如上所述,SQL Server中是否存在模仿Oracle行为的能力?或者,处理临时数据的唯一方法是不得不在每次迭代工作时重复创建临时表?

3 个答案:

答案 0 :(得分:9)

正如您发现SQL Server& Oracle临时表根本不同。

在Oracle中,全局临时表是存储临时会话特定(或特定于事务)数据的永久对象。

在SQL Server中,临时表是存储临时数据的临时对象,其中#temp_tables存储会话本地的数据,## temp_tables存储全局数据。 (我从来不需要SQL Server全局临时表,也不知道它们解决了什么问题。)如果#temp_table是在存储过程中创建的,那么当存储过程退出时它将被删除。否则会话结束时会被删除。

不,实际上没有办法让SQL Server模仿Oracle。您可以使用带有存储会话ID的额外列的普通表。但是,对于较少的日志记录,您不会获得临时表的优势。您必须手动删除临时数据。并处理过早退出会议的清理工作。

编辑: Oracle和SQL Server之间的另一个区别是SQL Server允许将DDL与其他语句一起包装在事务中。因此,如果您需要将临时表用作较大事务的一部分,create table #table_name...语句将不会隐式提交当前事务,就像Oracle中的create table语句一样。

答案 1 :(得分:1)

这是偏离主题的但你知道在SQL Server中你可以创建一个像这样的临时表:

select *
into #temp_table
from mytable

答案 2 :(得分:1)

当您需要合并来自具有公共合并字段的不同源的数据时,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