在 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 以及更新行的百分比是多少?
我有一个从 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 以及更新行的百分比是多少?