我正在编写一个调用dbaccess的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]}
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 :(得分: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-Access删除表创建的任何内容。
设置DBACCNOIGN
的值并不重要;将其设置为0
或1
或空字符串都同样有效。
这是一个有限的设施;您没有编程控制是否忽略任何给定语句中的错误。您可以在第一个错误时放弃发货,也可以不管错误而继续结束。
你可以考虑从IIUG(国际Informix用户组)Software Archive获得的'真正的'SQLCMD程序(而不是微软的johnny-come-lately)。它允许您控制是否忽略来自任何给定语句组的错误。但是,它不能为您提供全流控制 - 您无法有条件地执行语句。
答案 1 :(得分: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}')
使用程序
如果你想避免使用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