0

PostgreSQLデータベースからOracleデータベースへのChangedDataCapture(CDC)を実装する必要があります。

CDCforPostgreSQL用のJournalizationKnowledgeModuleがないため、https: //forums.oracle.com/forums/thread.jspa?threadID=620355で指定されているようにJKMOracleSimpleを適応させようとしています。

ただし、Jythonの「Createtrigger」コマンドで問題が発生しています。

ODIでは、「トリガーの作成」コマンドを次のように置き換えました。

drop trigger if exists public_t_payment on public.payment;

drop sequence if exists idSequence;

CREATE SEQUENCE idSequence;

CREATE OR REPLACE FUNCTION public_t_payment_trigger() RETURNS TRIGGER AS $$
declare
    V_FLAG  VARCHAR(1);
    V_id    integer NOT NULL DEFAULT nextval('idSequence');
begin
    if inserting then
        V_id := NEW.id;
        V_FLAG := 'I';
    end if;

    if updating then
        V_id := NEW.id;
        V_FLAG := 'I';
    end if;

    if deleting then
        V_id := OLD.id;
        V_FLAG := 'D';
    end if;

    insert into public.j$payment
    (
        JRN_SUBSCRIBER,
        JRN_CONSUMED,
        JRN_FLAG,
        JRN_DATE,
        id
    )
    select  JRN_SUBSCRIBER,
        '0',
        V_FLAG,
        sysdate,
        V_id
    from    public."SNP_SUBSCRIBERS"
    where   JRN_TNAME = 'public.payment';
    /* The following line can be uncommented for symetric replication */
    /* and  upper(USER) <> upper(''postgres'') */
end; $$ LANGUAGE plpgsql;

create trigger public_t_payment
after insert or update or delete on public.payment
for each row
execute procedure public_t_payment_trigger();

上記のコードはPostgreSQLでコピーして実行するとうまく機能しますが、ソーステーブルで「StartJournal」を実行すると、ODIによって次のエラーが発生します。

ODI-1217: Session payment (712013) fails with return code 7000.
ODI-1226: Step payment fails after 1 attempt(s).
ODI-1231: An error occurred while performing a Journal operation on datastore payment.
Caused By: org.apache.bsf.BSFException: exception from Jython:
SyntaxError: ("no viable alternative at character '$'", ('<string>', 6, 19, 'returns trigger as $test\n'))

問題はトリガーの「as」名($$)を返すことにあるようですが、Jythonでこの問題を解決する方法がわかりません。

4

1 に答える 1

1

私はこれを次のように解決することができました。

「CreateTrigger」コマンドのテクノロジーはJythonに設定されていましたが、私のコードは純粋にPostgreSQLでした。

[テクノロジー]ドロップダウンを[Jython]から[PostgreSQL]に変更すると、CreateTriggerコマンドをエラーなしで実行できるようになりました。

ただし、コマンドをできるだけ元のコマンドと同じように保ちたいので、必要なJython構文を含めるように上記のコードを更新しました。

上記の質問に投稿されたSQLはPostgreSQLで実行されますが、トリガーが起動されたときにエラーが発生していたため、完全には正しくないことに注意してください。

PostgreSQLソースデータベースで実行されるCreateTriggerコマンドの完全なJythonコードを以下に貼り付けました。PostgreSQLからOracleJKMがないため、誰かが役立つと思うかもしれません。

triggerCmd = """
drop trigger if exists "<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>" on <%=odiRef.getJrnInfo("FULL_TABLE_NAME")%>;

drop sequence if exists "seq_<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>_id";

create sequence "seq_<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>_id";

create or replace function "fn_<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>"()
returns trigger as $$
declare
    V_FLAG  VARCHAR(1);
    V_id integer NOT NULL DEFAULT nextval('"seq_<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>_id"');
begin
    if (TG_OP = 'INSERT') then
        <%=odiRef.getColList("", "V_[COL_NAME] := new.[COL_NAME];", "\n\t\t", "", "PK")%>
        V_FLAG := 'I';
    end if;

    if (TG_OP = 'UPDATE') then
        <%=odiRef.getColList("", "V_[COL_NAME] := new.[COL_NAME];", "\n\t\t", "", "PK")%>
        V_FLAG := 'I';
    end if;

    if (TG_OP = 'DELETE') then
        <%=odiRef.getColList("", "V_[COL_NAME] := old.[COL_NAME];", "\n\t\t", "", "PK")%>
        V_FLAG := 'D';
    end if;

    insert into  <%=odiRef.getJrnInfo("JRN_FULL_NAME")%>
    (
        JRN_SUBSCRIBER,
        JRN_CONSUMED,
        JRN_FLAG,
        JRN_DATE,
        <%=odiRef.getColList("", "[COL_NAME]", ",\n\t\t", "", "PK")%>
    )
    select  JRN_SUBSCRIBER,
        '0',
        V_FLAG,
        now(),
        <%=odiRef.getColList("", "V_[COL_NAME]", ",\n\t\t", "", "PK")%>
    from    <%=odiRef.getJrnInfo("SNP_JRN_SUBSCRIBER")%>
    where   JRN_TNAME = '<%=odiRef.getJrnInfo("FULL_TABLE_NAME")%>';
    /* The following line can be uncommented for symetric replication */
    /* and  upper(USER) <> upper('<%=odiRef.getInfo("DEST_USER_NAME")%>') */
return new;
end $$ language plpgsql;

create trigger "<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>"
after insert or update or delete on <%=odiRef.getJrnInfo("FULL_TABLE_NAME")%>
for each row    
execute procedure "fn_<%=odiRef.getJrnInfo("JRN_FULL_TRIGGER")%>"();
"""

# Create the statement
myStmt = myCon.createStatement()

# Execute the trigger creation
myStmt.execute(triggerCmd)

myStmt.close()
myStmt = None

# Commit, just in case
# myCon.commit()
于 2013-01-08T09:38:48.627 に答える