【问题标题】:SQL Server / Oracle : Private temporary tablesSQL Server / Oracle:私有临时表
【发布时间】:2011-04-10 14:07:24
【问题描述】:

在 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 行为?还是使用临时数据的唯一方法是必须在每次工作迭代中重复创建临时表?

【问题讨论】:

  • 您能解释一下为什么要模仿 SQLServer 中的 Oracle 行为吗?是否只是为了避免执行 CREATE TABLE 语句的要求?
  • @Mark ~ 嗯,主要是这样。但是,如果我正在处理 (1) 重复的临时数据插入,(2) 具有通常相同的数据格式和字段,(3) 并且是用户唯一的(即数据对用户会话来说是私有的),它只会产生更多根据 Oracle 的实现来处理表中的所有内容。 :)

标签: sql oracle sql-server-2008


【解决方案1】:

正如您所发现的,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 语句那样隐式提交当前事务。

【讨论】:

  • ~ 同样,我也无法理解 SQL Server ##temp_tables。 :) 诚然,我宁愿按照 Oracle 的实现,但如果这在 SQL Server 中根本不可能,那么您的建议似乎是最有意义的。谢谢! +1
  • 我有一位同事发现了##temp_tables 的用途 - 他将 SSIS 用于某些进程,如果您在一个 proc 中使用 ##,并且该 proc 调用另一个 proc,则 proc#2 可以使用##temp_table。
  • @sql_mommy:我有一个同事做了类似的事情,因为他们使用##tables 来使用 accross procs。但是,他们无法阻止最终用户在其他人已经在运行时启动相同的进程,因此冒着两个用户的工作在全局临时表中混合在一起的风险。我们将临时表定义移动到顶部 proc,因此所有被调用的 proc 都可以看到它们并使其成为本地临时表。对于 SSIS 来说,如果是由作业启动的批处理,可能还可以。
【解决方案2】:

这是题外话,但你知道在 SQL Server 中你可以像这样创建一个临时表:

select *
into #temp_table
from mytable

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2012-02-13
      • 1970-01-01
      • 2019-04-04
      • 2010-09-07
      • 2011-01-08
      • 2011-02-14
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多