Требуется ли COMMIT после завершения транзакции в Teradata? - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть хранимая процедура, которая читает строки из таблицы, выполняет некоторые вычисления для каждой строки и сохраняет результат в одной и той же строке.

Когда мне нужно обработать миллион строк, всеОБНОВЛЕНИЯ заполняют базу данных DBC , поэтому я хочу выполнить COMMIT после 1000 вычислений строк.

Нужно ли использовать транзакции или мне нужно использовать 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, более подробная информация.

То, что я действительно пытаюсь вычислить, это то, сколько рабочих дней проходит между двумя датами с учетом банковских выходных (или праздничных дней) и выходных для каждогоcity.

Например, я отправляю что-то из A в B, и у меня есть событие отслеживания, которое говорит, что это было в A в пятницу, 1 февраля, и в B в следующую среду, 6 февраля, поэтомуДля BI нужно запросить все дни между этими датами в поисках праздничных дней.

Для этого у меня есть таблица с 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 = 5 дней), а затем вычисляю выходные дни для B (SELECT COUNT(*) FROM FESTIVES_TABLE WHERE CITY='B' AND FESTIVE BETWEEN DATE '2019-02-01' AND DATE '2019-02-06') и он возвращает3 дня, которые затем вычитаем их до 5 дней (день 06 - дay 01 = 5days, 5days-3festives = 2days).

Таким образом, количество рабочих дней равно 2, и затем я обновляю строку с вычисленным значением.

Я проверил пробелдля базы данных DBC и имеет 1962 ГБайт.

Еще раз спасибо:)

1 Ответ

0 голосов
/ 11 февраля 2019

Существует очень простой способ подсчета количества рабочих (или праздничных) дней без циклов / счетчиков и т. Д., Он основан на вычисленном столбце числа рабочих дней в календарной таблице.В вашем случае это немного сложнее, потому что вам нужно несколько календарей, по одному на город.

Итак, давайте вычислим его в представлении (или используем общее выражение таблицы, 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 вы имеете в видуПереходный журнал?Ну, это может вырасти намного больше, чем dbc (если есть место в вашей системе).

Но 2 ТБ Пермского пространства довольно мало для БД (если у вас не очень маленькая система), насколько велика ваша таблица назначения и какой процент строк обновляется?

...