由于我们的数据仓库中缺少权限和很多限制,我想使用一些肮脏的解决方案。 我有2张桌子
create table patrik_test (
marke varchar2(2)
)
create table patrik_test2 (
marke varchar2(2)
)
第一个表应该每天用新数据刷新。首先,表将被截断,然后填充新数据。 问题是这是在 KNIME 中完成的,并且一如既往,流程可能会由于超时等原因而失败。但是表将在开始时被截断,因此这种情况总是会发生。
我们需要避免没有数据的表,但此时没有解决方案,因此出现了另一个解决方案。 我们可以创建另一个表 patrik_test2 ,当 patrik_test 中插入新数据时,它将获取数据。 所以基本上一开始两个表都是空白的。 当 patrik_test 被截断并随后填充新数据时,表 patrik_test2 也应该被截断并从 patrik_test 获取新插入的数据。
所以我们构建了一个这样的触发器
create or replace trigger patrik_test_trg
after insert on patrik_test for each row
declare
pragma autonomous_transaction;
begin
execute immediate 'truncate table patrik_test2';
insert into patrik_test2
select * from patrik_test;
commit;
end
;
问题是表 patrik_test2 被截断,但不会立即填充。
insert into patrik_test values ('AA');
patrik_test 将填充 AA,但 patrik_test2 不会。
为什么以及如何解决?
如果 patrik_test 在 KNIME 中失败,那么表会被截断,但没有插入数据,表 patrik_test2 将保留相同的数据,因此我们有一些棘手的解决方案,但至少最终表始终有一些数据
MERGE
两张桌子:
CREATE TRIGGER patrik_test_mrg_trg
AFTER INSERT ON patrik_test
BEGIN
MERGE INTO patrik_test2 dst
USING patrik_test src
ON (src.marke = dst.marke)
WHEN NOT MATCHED THEN
INSERT (marke) VALUES (src.marke);
END;
/
或者,使用
PROCEDURE
并复制 patrik_test
,然后重命名表格以制作副本 patrik_test2
:
CREATE PROCEDURE patrik_test_mv
IS
has_rows PLS_INTEGER;
TABLE_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942);
BEGIN
SELECT 1
INTO has_rows
FROM patrik_test
WHERE ROWNUM = 1;
EXECUTE IMMEDIATE 'CREATE TABLE patrik_test_new AS SELECT * FROM patrik_test';
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE patrik_test_old';
EXCEPTION
WHEN TABLE_DOES_NOT_EXIST THEN
NULL;
END;
EXECUTE IMMEDIATE 'ALTER TABLE patrik_test2 RENAME TO patrik_test_old';
EXECUTE IMMEDIATE 'ALTER TABLE patrik_test_new RENAME TO patrik_test2';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('patrik_test is empty!');
RAISE;
END;
/
将数据加载到
patrik_test
后运行该程序。