在 Teradata 中结束事务后是否需要 COMMIT?

Is COMMIT required after ending a transaction in Teradata?

我有一个从 table 中读取行的存储过程,对每一行进行一些计算并将结果存储在同一行中。

当我需要处理一百万行时,所有更新都在填满 DBC 数据库,所以我想在 1000 行计算后执行 COMMIT。

我需要使用事务还是需要使用 COMMIT? COMMIT WORK 有什么作用?

我都是在TERA模式下执行的,版本是15.00

这是我程序的简化示例:

-- Creates a sample table
--DROP TABLE DM_CALIDAD.RGR_TEST_PROCEDURE;
CREATE MULTISET TABLE DM_CALIDAD.RGR_TEST_PROCEDURE AS(
SELECT T.TABLENAME AS "TABLE_NAME", 0(INTEGER) AS IND_NAME FROM DBC.TABLESV T
)WITH DATA
;

--Creates the procedure
REPLACE PROCEDURE DM_CALIDAD.SP_TEST_NAME()
BEGIN

    DECLARE V_TABLE_NAME VARCHAR(256) DEFAULT NULL;
    DECLARE V_CALC INTEGER;
    DECLARE SQL_CURSOR1, SQL_UPDATE VARCHAR(10000) DEFAULT NULL;
    DECLARE CONT INTEGER DEFAULT NULL;

    DECLARE CUR_CURSOR1 CURSOR FOR PREP_CURSOR1;

    SET SQL_CURSOR1 = 'SELECT TABLE_NAME FROM DM_CALIDAD.RGR_TEST_PROCEDURE';

    SET CONT = 1;
    PREPARE PREP_CURSOR1 FROM SQL_CURSOR1;
    OPEN CUR_CURSOR1;

    BEGIN TRANSACTION;
    l_loop: 
    LOOP

        FETCH CUR_CURSOR1 INTO V_TABLE_NAME;

        IF (SQLCODE <> 0) THEN
            LEAVE l_loop;
        END IF;

        SET SQL_UPDATE = 'UPDATE DM_CALIDAD.RGR_TEST_PROCEDURE SET IND_NAME = IND_NAME+1 WHERE TABLE_NAME = ''' ||V_TABLE_NAME || '''';
        EXECUTE IMMEDIATE SQL_UPDATE;

        -- Ends the transacion each 1000 updates 
        SET CONT = CONT + 1;
        IF (CONT MOD 1000 = 0) THEN
            END TRANSACTION;
            --COMMIT WORK;
            BEGIN TRANSACTION;
        END IF;

    END LOOP l_loop;
    END TRANSACTION;
    CLOSE CUR_CURSOR1;

END;

-- Calls procedure
CALL DM_CALIDAD.SP_TEST_NAME();

提前致谢。


Edit1,更多细节。

我真正想计算的是考虑到每个城市的银行假期(或节日)和周末,两个日期之间有多少工作日。

例如,我要从 A 向 B 发送一些东西,并且我有一个跟踪事件说它是在 2 月 1 日星期五在 A 和下个星期三,2 月 6 日在 B,所以对于 B 我需要查询这些日期之间的所有日子以查找节日。

对于这个提议,我有一个 table 包含 2 列,城市和节日。

CITY | FESTIVE
  B    2019-02-02 -- For being Saturday
  B    2019-02-03 -- For being Sunday
  B    2019-02-04 -- For being festive at B

因此,对于每一行,我都阅读了 first_event 列和 last_event 列并进行了区分(6-1 = 5days) 然后我计算 B 的休息天数 (SELECT COUNT(*) FROM FESTIVES_TABLE WHERE CITY='B' AND FESTIVE BETWEEN DATE '2019-02-01' AND DATE '2019-02-06') 它 returns 3 天,然后我将它们减去 5 天(第 06 天 - 第 01 天 = 5 天,5 天-3 节 = 2 天)。

所以劳动天数是 2,然后我用计算值更新行。

我检查了 DBC 数据库的 perm space,它有 1962GBytes。

再次感谢:)

有一种非常简单的方法可以计算没有 loops/counts/etc 的工作(或假期)天数,它基于日历 table 中计算的 business_day 数字列。在您的情况下,它稍微复杂一些,因为您需要多个日历,每个城市一个。

所以让我们在视图中计算它(或使用通用 Table 表达式,WITH my_cal AS SELECT ...):

REPLACE VIEW my_cal AS
SELECT c.*,
  -- running business day number
  -- increases only for each business day
  Sum(CASE WHEN f.festive IS NULL THEN 1 ELSE 0 end)
  Over (PARTITION BY c.city
        ORDER BY c.caldt
        ROWS Unbounded Preceding) AS business_day_num
FROM 
 ( -- this simply create all dates for each city
   SELECT *
   FROM 
    ( -- all cities
      SELECT DISTINCT city
      FROM festivetable
    ) AS f
   CROSS JOIN 
    ( -- all dates
      SELECT calendar_date AS caldt
      FROM sys_calendar.CALENDAR AS c -- you should use your company's calendar instead
      WHERE caldt BETWEEN DATE '2018-10-01' AND DATE '2019-02-28' 
    ) AS c
 ) AS c
LEFT JOIN festivetable AS f
  ON  c.city = f.city
 AND c.caldt = f.festive;

现在只是 start_date/end_date 上的两个连接并计算差值。

SELECT ...
   end_cal.business_day_num - start_cal.business_day_num AS duration_in_business_days
FROM mytable
JOIN my_cal AS start_cal
  ON mytable.city = start_cal.city
 AND mytyble.first_event = start_cal.caldt
JOIN my_cal AS end_cal
  ON mytable.city = end_cal.city
 AND mytyble.first_event = end_cal.caldt

关于 DBC,当您说 所有更新都在填满 DBC 数据库时,您是指 Transient Journal 吗?好吧,它可以比 dbc 大得多(如果您的系统上有 space 可用)。

但是 2TB Perm Space 对于 dbc 来说是相当低的(除非你有一个非常小的系统),你的目标有多大 table 以及更新行的百分比是多少?