2015-09-01 93 views
1

我在寫一個調用dbaccess的shell腳本。Informix dbaccess here文檔方法的交易

我想開始一個交易,做一些事情(例如調用某些過程),然後做出決定並提交或回滾當前的工作。這可能嗎?

這裏是什麼,我試圖完成

#!/bin/bash 

v_value 

dbaccess $DB - << SQL 

unload to "abc.csv" 
select value from table1 where id=1; 
SQL 

IFS=$'|' arr=($(awk -F, -v OFS='\n' '{$1=$1}1' abc.csv)) 
v_value=${arr[0]} 

dbaccess $DB - << SQL 

begin; 

execute procedure progname(); 

-- here check everything is ok (e.g. using the previously retrieved $v_value) and either commit or rollback 
-- commit|rollback 
SQL 

回答

0

也許你能犯這種程序的內部/回滾一個例子。

但你寫你的腳本的方式,我不認爲有必要創建一個程序,就可以解決使用shell腳本:

#!/bin/bash 

v_value="" 

dbaccess $DB - << SQL 

unload to "abc.csv" 
select value from table1 where id=1; 
SQL 

IFS=$'|' arr=($(awk -F, -v OFS='\n' '{$1=$1}1' abc.csv)) 
v_value=${arr[0]} 

{ 
echo " 
begin work; 
execute procedure progname(); 
" 
if [ "$v_value" = "1" ] ; then 
    echo "commit ;" 
else 
    echo "rollback;" 
fi; 

} | dbaccess $DB - 

PLUS

關於「卸載」 ,正如建議(我不喜歡這種腳本的使用卸載):

v_value=$(echo "select first 1 value from table1 where id=1;" | dbaccess $DB 2>/dev/null | egrep -v '^ *$|^ *value" | awk '{print $1}') 

使用PR OCEDURE
如果你想避免使用shell腳本和所有保持到SQL代碼,你將需要創造一個具體的程序,是這樣的:

create table test(desc char(10)) ; 
--drop procedure commit_rollback ; 
create procedure commit_rollback() 
    define x int ; 
    select count(*) into x from test ; 
    if x > 5 then 
    commit work; 
    else 
    rollback work ; 
    end if ; 
end procedure ; 

begin work ; 
insert into test values ('111') ; 
insert into test values ('222') ; 
insert into test values ('333') ; 
insert into test values ('444') ; 
insert into test values ('555') ; 
execute procedure commit_rollback() ; 

select * from test ; 
begin work; 
insert into test values ('111') ; 
insert into test values ('222') ; 
insert into test values ('333') ; 
insert into test values ('444') ; 
insert into test values ('555') ; 
insert into test values ('666') ; 

execute procedure commit_rollback() ; 
select * from test ; 

上面的代碼都會有這樣的輸出

desc 

desc 

111 
222 
333 
444 
555 
666 
+0

是否有可能在{}塊內部從db中檢索值?我想在進行比較時使用該值來決定是否提交或回滾。 – oceanfeeling

+1

嗨@oceanfeeling,我只使用SQL語句改進答案,沒有shell腳本處理... – ceinmart

1

您可能想要使用DBACCNOIGN環境變量,它使DB-Access關注失敗的語句 - 並停止。如果已設置並且您啓動了事務,然後事務內的語句失敗,則DB-Access將終止,這意味着事務將被回滾。

例如:

$ DBACCNOIGN=1 dbaccess stores - <<'EOF' 
> begin work; 
> create table anything (num INT NOT NULL, str VARCHAR(20) NOT NULL); 
> insert into anything values(1, "one"); 
> select * from abelone; 
> insert into anything values(2, "two"); 
> select * from anything; 
> commit work; 
> EOF 

Database selected. 


Started transaction. 


Table created. 


1 row(s) inserted. 


    206: The specified table (abelone) is not in the database. 

    111: ISAM error: no record found. 
Error in line 1 
Near character position 21 


    377: Must terminate transaction before closing database. 

    853: Current transaction has been rolled back due to error 
or missing COMMIT WORK. 

$ dbaccess stores - <<'EOF' 
> begin work; 
> create table anything (num INT NOT NULL, str VARCHAR(20) NOT NULL); 
> insert into anything values(1, "one"); 
> select * from abelone; 
> insert into anything values(2, "two"); 
> select * from anything; 
> commit work; 
> EOF 

Database selected. 


Started transaction. 


Table created. 


1 row(s) inserted. 


    206: The specified table (abelone) is not in the database. 

    111: ISAM error: no record found. 
Error in line 1 
Near character position 21 

1 row(s) inserted. 



     num str     

      1 one     
      2 two     

2 row(s) retrieved. 


Data committed. 



Database closed. 

$ 

然後我不得不再次使用DB-訪問命令來刪除創建的表什麼。

DBACCNOIGN設定的值無關緊要;將其設置爲01或者一個空字符串都工作得很好。

這是一個有限的設施;您沒有程序控制是否忽略來自任何給定語句的錯誤。您要麼放棄出現第一個錯誤,要麼無論錯誤如何都繼續結束。

您可以考慮從IIUG(International Informix User Group)Software Archive獲得的'真正'的SQLCMD程序(而不是微軟的johnny-come-lately)。它允許您控制是否忽略來自任何給定語句組的錯誤。但是,它不會給你全面的流量控制 - 你不能有條件地執行語句。