我有一个旧的客户端软件,它有一个连接的oracle数据库用于持久化。作为接口,客户端软件仅允许调用函数和过程。我几乎可以完全访问数据库,即我可以定义函数和过程。由于接口,只有函数可以返回值,我不能使用过程的OUT
参数选项。
现在我只想从表中读取一个值:
SELECT value FROM myTable WHERE id = 42;
然后增加价值:
UPDATE myTable SET value = value + 1 WHERE id = 42;
我可以使用select语句的函数和更新的过程,并连续调用。这里的问题是客户端不存在交易。因此,在select和update之间,另一个线程可能会得到错误的值。
所以我的问题是,如何在不使用事务的情况下在事务中使用这两个调用...
尝试方法:
PRAGMA AUTONOMOUS_TRANSACTION
- >我听说这是件坏事,不应该使用。 答案 0 :(得分:1)
你可以在函数中执行DML,如下所示,但我强调 - 请注意其他注释。看看使用一个序列(甚至多个序列),因为在函数内部执行DML通常是一个坏主意,因为函数调用的执行次数(如果从SQL调用)不是确定性的。此外,如果在大量使用中存在可伸缩性问题。在多用户环境中,您需要处理锁定/序列化,否则您将在多个会话中返回相同整数值。
所以......毕竟,你仍然想要走这条道路: - (
SQL> create table t ( x int );
Table created.
SQL> insert into t values (0);
1 row created.
SQL>
SQL> create or replace
2 function f return int is
3 pragma autonomous_transaction;
4 retval int;
5 begin
6 update t
7 set x = x + 1
8 returning x into retval;
9 commit;
10 return retval;
11 end;
12 /
Function created.
SQL>
SQL> select f from dual;
F
----------
1
1 row selected.
SQL> select * from t;
X
----------
1
1 row selected.
SQL> select f from dual;
F
----------
2
1 row selected.
SQL> select * from t;
X
----------
2
1 row selected.
SQL> select f from dual;
F
----------
3
1 row selected.
SQL> select * from t;
X
----------
3
1 row selected.