2012-12-27 77 views
0

我需要將PostgreSQL數據庫中的更改數據捕獲(CDC)實施到Oracle數據庫。Oracle ODI JKM for PostgreSQL:創建觸發器

由於沒有用於CDC for PostgreSQL的日記知識模塊,我正在嘗試修改JKM Oracle Simple,如https://forums.oracle.com/forums/thread.jspa?threadID=620355所述。

但是我遇到了Jython的「Create trigger」命令問題。

在ODI,我已經取代了「創建觸發器」命令執行以下操作:複製和PostgreSQL的執行時,卻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')) 

這個問題似乎是與回報「作爲」名稱觸發($$),但我無法弄清楚如何解決Jython的這個問題。

回答

1

我設法解決這個如下。

「創建觸發器」命令的技術設置爲Jython,但我的代碼純粹是PostgreSQL。

將技術下拉列表從「Jython」更改爲「PostgreSQL」允許執行Create Trigger命令而不會給出任何錯誤。

但是,由於我想保持命令與原始命令儘可能相似,因此我更新了上述代碼以包含必需的Jython語法。

請注意,雖然上述問題中發佈的SQL在PostgreSQL中執行,但它並不完全正確,因爲它在觸發器被觸發時仍然出錯。

我粘貼了完整的Jython代碼項的規定執行的PostgreSQL源數據庫上創建觸發器的命令,也許有人會在有用的發現,因爲沒有PostgreSQL的甲骨文JKM ..

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()