【问题标题】:Oracle SP use of global temporary tablesOracle SP 使用全局临时表
【发布时间】:2021-04-13 07:50:15
【问题描述】:

通常,我的程序 (Oracle 12c) 如下所示:

PROCEDURE xxx AS 
   declare variables
BEGIN
   save log
   create table 1
   save log
   ...
   create table 2
   save log
   ...
   create table n
   save log
END xxx

我创建表 1 到 n-1 作为辅助表(性能和模块化)以获得我想要的第 n 个表。当我应该使用全局临时表时,我使用的是普通表吗?

PD:我的第一个问题因基于意见而结束,我对其进行了修改以使其更加具体。

编辑:添加示例程序

create or replace PACKAGE BODY balance_mismatch_dca AS

    idproceduregeneral VARCHAR2(50);

    PROCEDURE aux_tables AS
        balance_zufi_dca_exists     INTEGER;
        balance_dfkkop_dca_exists   INTEGER;
    BEGIN
        idproceduregeneral := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
        uxxxxxx_logs('Start Aux Tables', idproceduregeneral);
        BEGIN
            SELECT
                COUNT(*)
            INTO balance_zufi_dca_exists
            FROM
                sys.all_tables
            WHERE
                table_name = upper('balance_zufi_dca');

        EXCEPTION
            WHEN no_data_found THEN
                balance_zufi_dca_exists := 0;
        END;

        IF ( balance_zufi_dca_exists ) = 1 THEN
            EXECUTE IMMEDIATE q'[Drop Table balance_zufi_dca]';
        END IF;
        EXECUTE IMMEDIATE q'[
        
        CREATE TABLE balance_zufi_dca
            AS
            WITH aux AS (
                SELECT
                    vkont,
                    vtref,
                    MAX(zzmfvdat) AS lat
                FROM
                    cdc.uap_zufi_t_dca_place@rbip
                WHERE
                    zzextamount != 0
                GROUP BY
                    vkont,
                    vtref
            ), aux2 AS (
                SELECT
                    a.vkont,
                    a.vtref,
                    a.lat,
                    MAX(b.zzextamount) AS amount_zufi,
                    MAX(b.zzplacref) AS dca,
                    MAX(zzplace_typ) AS placement
                FROM
                    aux                             a
                    JOIN cdc.uap_zufi_t_dca_place@rbip   b ON ( b.vkont = a.vkont
                                                              AND b.vtref = a.vtref
                                                              AND b.zzmfvdat = a.lat )
                GROUP BY
                    a.vkont,
                    a.vtref,
                    a.lat
            )
            SELECT
                vkont,
                SUM(amount_zufi) AS amount_zufi,
                MAX(dca) AS dca,
                MAX(placement) AS placement
            FROM
                aux2
            GROUP BY
                vkont
        ]'
        ;
        uxxxxxx_logs('End Balance Zufi DCA', idproceduregeneral);
        BEGIN
            SELECT
                COUNT(*)
            INTO balance_dfkkop_dca_exists
            FROM
                sys.all_tables
            WHERE
                table_name = upper('balance_dfkkop_dca');

        EXCEPTION
            WHEN no_data_found THEN
                balance_dfkkop_dca_exists := 0;
        END;

        IF ( balance_dfkkop_dca_exists ) = 1 THEN
            EXECUTE IMMEDIATE q'[Drop Table balance_dfkkop_dca]';
        END IF;
        EXECUTE IMMEDIATE q'[
        
        Create Table balance_dfkkop_dca AS
                WITH aux AS (
                    SELECT /*+ FULL(a) */
                        vkont,
                        betrw as amount_dfkkop
                    FROM
                        cdc.uap_dfkkop@rbip a
                    WHERE
                        augrs IS NULL
                        AND augst IS NULL
                        AND stakz IS NULL
                        AND abwbl IS NULL
                        AND (studt <= to_char(sysdate, 'YYYYMMDD') or studt is null)
                        AND faedn <= to_char(sysdate, 'YYYYMMDD')
                )
                SELECT
                    *
                FROM
                    aux
        ]'
        ;
        uxxxxxx_logs('End Balance DFKKOP DCA', idproceduregeneral);
    END aux_tables;

    PROCEDURE gen_view AS
    BEGIN
        idproceduregeneral := utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(1));
        EXECUTE IMMEDIATE q'[
        CREATE OR REPLACE VIEW vw_bm_dca_volumes AS
        WITH aux AS (
            SELECT
                a.vkont,
                a.amount_zufi,
                SUM(nvl(b.amount_dfkkop, 0)) AS amount_dfkkop
            FROM
                balance_zufi_dca   a
                LEFT JOIN balance_dfkkop_dca    b ON ( b.vkont = a.vkont )
            GROUP BY
                a.vkont,
                a.amount_zufi
        )
        SELECT
            CASE
                WHEN amount_zufi = amount_dfkkop THEN
                    'Chased for the Correct Balance'
                WHEN amount_zufi > amount_dfkkop THEN
                    'Chased for Higher Balance'
                WHEN amount_zufi < amount_dfkkop THEN
                    'Chased for Lower Balance'
                ELSE
                    NULL
            END AS status,
            COUNT(1) AS ca_count,
            round(RATIO_TO_REPORT(COUNT(1)) OVER() * 100, 2) perc
        FROM
            aux
        GROUP BY
            CASE
                WHEN amount_zufi = amount_dfkkop THEN
                    'Chased for the Correct Balance'
                WHEN amount_zufi > amount_dfkkop THEN
                    'Chased for Higher Balance'
                WHEN amount_zufi < amount_dfkkop THEN
                    'Chased for Lower Balance'
                ELSE
                    NULL
            END
        ORDER BY
            COUNT(1) DESC
    
    ]'
        ;
        
       EXECUTE IMMEDIATE q'[
        CREATE OR REPLACE VIEW vw_bm_dca_data AS
        WITH aux AS (
            SELECT
                a.vkont,
                a.dca,
                a.placement,
                a.amount_zufi,
                SUM(nvl(b.amount_dfkkop, 0)) AS amount_dfkkop
            FROM
                balance_zufi_dca     a
                LEFT JOIN balance_dfkkop_dca   b ON ( b.vkont = a.vkont )
            GROUP BY
                a.vkont,
                a.dca,
                a.placement,
                a.amount_zufi
        )
        SELECT
            *
        FROM
            aux
        WHERE
            amount_zufi != amount_dfkkop
    
    ]'
        ;
        uxxxxxx_logs('End Views', idproceduregeneral);
    END gen_view;

END balance_mismatch_dca;

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    这取决于。例如:

    • 如果只有“你”在使用这些表格,那么这并不重要。
    • 如果有很多用户使用相同的程序,那么
      • 如果您使用“普通”表,则必须有一些标识符(ID、用户名等)来区分一个用户的数据和另一个用户的数据,因为 - 如果不这样做 - 他们将修改所有用户的所有行和你会遇到严重的问题(从不一致到锁定)。除非您手动从表中删除行,否则它们将保持填充状态
      • 如果您使用(全局)临时表,每个用户将只能看到自己的数据,并且当会话(或事务;取决于您创建表的方式)结束时,他们的(表的)内容将丢失

    所以,正如我所说,这取决于。

    【讨论】:

    • 非常感谢您的回答。只是我在处理程序。曾经有人告诉我,在存储过程中创建“普通”表“非常奇怪”,并且试图弄清楚在使用存储过程时是否有更好的方法..
    • 这几乎肯定是错误的做法。在 Oracle 中,我们“一次”(在 SQL 级别)创建表并“多次”使用它们,无论它们是 普通 还是 全局临时 表。我认为您的“创建表 1”语句实际上代表“插入表 1”。不要在 PL/SQL 中创建表。如果这样做,则需要使用动态 SQL。
    • 如何插入/更新/删除这些表?使用合并?我已经编辑了我的原始问题,并使用我当前的方法添加了一个存储过程的示例。为了实现这一目标,应该做哪些改变?
    • 正如我所说:NOT 在 PL/SQL 中创建表。在一个过程中,您只需插入或合并或更新,无论您在特定时刻发现什么合适。
    • 我并没有说一般情况下应该避免动态 SQL;有时这是必需品。在我看来,从 PL/SQL 创建任何对象通常是一个坏主意,坏方法,没有任何改进,使许多事情复杂化,我避免了它。一般。
    猜你喜欢
    • 2017-10-02
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2015-07-27
    • 2012-02-13
    • 1970-01-01
    相关资源
    最近更新 更多