背景
図のようにDB_A
からDB_temp
,DB_Z
へとNode-Redを使ったバケツリレーシステムがある。
DB_Z
へデータを格納するNode-RedはDB_temp
のcre_rec_date
という日付のカラムを参照して、日付の範囲を限定してDB_Z
へとデータを格納していく。
一度にDB_temp
全データを対象としてしまうと処理が重くなるためである。
で、ある日、DB_Z
をぶっ壊してしまった。何も考えずにやるとDB_A
からのバケツリレーを最初からやり直せば直るのだが、DB_temp
にはデータが残っている。ならば、DB_temp
のデータを再利用したほうがいいだろう!
しかし、DB_temp
のcre_rec_date
は過去のデータとなっている。且つ、一気にcre_rec_date
を最新日付にしてしまうと、DB_Z
へデータ格納するNode-Redがハングアップする。(これもいかがなものかと思うがそれはここでは置いておく)
ってことで、タイトル通りのことがしたくなった。
環境
あまり環境に依存しないやり方ではあるが、一応記載しておく。
- PostgreSQL 13.1 (9以上であればバージョンに依存しないのではないか?)
- Windows 10 (server/client共に)
Table作成
create table test_table (
pkey_code integer not null,
cre_rec_date timestamp with time zone not null,
constraint test_table_PKC primary key (pkey_code)
);
テストデータ作成
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (1, '2021/02/09 00:00:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (2, '2021/02/09 00:00:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (3, '2021/02/09 00:00:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (4, '2021/02/09 00:00:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (5, '2021/02/09 00:00:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (6, '2021/02/09 00:00:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (7, '2021/02/09 00:01:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (8, '2021/02/09 00:01:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (9, '2021/02/09 00:01:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (10, '2021/02/09 00:01:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (11, '2021/02/09 00:01:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (12, '2021/02/09 00:01:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (13, '2021/02/09 00:02:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (14, '2021/02/09 00:02:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (15, '2021/02/09 00:02:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (16, '2021/02/09 00:02:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (17, '2021/02/09 00:02:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (18, '2021/02/09 00:02:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (19, '2021/02/09 00:03:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (20, '2021/02/09 00:03:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (21, '2021/02/09 00:03:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (22, '2021/02/09 00:03:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (23, '2021/02/09 00:03:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (24, '2021/02/09 00:03:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (25, '2021/02/09 00:04:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (26, '2021/02/09 00:04:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (27, '2021/02/09 00:04:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (28, '2021/02/09 00:04:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (29, '2021/02/09 00:04:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (30, '2021/02/09 00:04:50');
UPDATE 文 (今回の肝)
UPDATE
test_table
SET
cre_rec_date = current_timestamp
WHERE
pkey_code IN (
SELECT
pkey_code
FROM
test.test_table
WHERE
cre_rec_date >= '2021/02/09 00:00:00' -- 再登録したい日付
AND cre_rec_date <= '2021/02/09 22:40:00' --おおよその現在時刻より少し前
ORDER BY
cre_rec_date
LIMIT
10
);
このUPDATE文を実行した後DB_Z
のNode-Redを回して、完了したら再度同様のUPDATEを実行を繰り返すと、バケツリレーの完了。
UPDATE文に直接ORDER BY句やLIMIT句が使用できないので、少しだけトリッキーなSQLになったということで、自分の備忘録も兼ねて。
アーキが悪いのではないかと思っているが、このバケツリレー仕様。。。