选择用于Oracle包中的更新
我为update语句创建了包和包体 我在书堆里找不到这方面的任何东西, 我不知道我这样做是不是很好, 以及你是否会改变什么 如果我调用程序选择用于Oracle包中的更新,oracle,plsql,Oracle,Plsql,我为update语句创建了包和包体 我在书堆里找不到这方面的任何东西, 我不知道我这样做是不是很好, 以及你是否会改变什么 如果我调用程序 begin account_api.upd_account(1, 'user', 1000) end; 在我使用commit语句完成事务之前,应该锁定这些过程 CREATE OR REPLACE PACKAGE account_api AS PROCEDURE upd_account ( p_acc_id
begin
account_api.upd_account(1, 'user', 1000)
end;
在我使用commit语句完成事务之前,应该锁定这些过程
CREATE OR REPLACE PACKAGE account_api AS
PROCEDURE upd_account
(
p_acc_id accounts.acc_id%type
, p_acc_name accounts.acc_name%type
, p_acc_amount accounts.acc_amount%type
);
end account_api;
/
CREATE OR REPLACE PACKAGE BODY account_api AS
PROCEDURE upd_account (
p_acc_id accounts.acc_id%type
, p_acc_name accounts.acc_name%type
, p_acc_amount accounts.acc_amount%type
)
is
l_current_balance NUMBER;
l_new_balance NUMBER;
BEGIN
SELECT acc_amount INTO l_current_balance
FROM accounts
WHERE acc_id = p_acc_id
FOR UPDATE;
l_new_balance := l_current_balance + p_acc_amount;
IF l_new_balance < 0 THEN
raise_application_error(-20001, 'Sorry you re overdrawn');
END IF;
UPDATE accounts
SET acc_amount = l_new_balance,
acc_name = p_acc_name
WHERE acc_id = p_acc_id;
COMMIT;
end;
end account_api;
/
创建或替换包帐户\u api作为
程序upd_账户
(
会计科目id科目。会计科目id%类型
,p_acc_name帐户。acc_name%类型
,p_acc_金额科目。acc_金额%类型
);
最终账户(api),;
/
创建或替换包体帐户\u api作为
程序upd_账户(
会计科目id科目。会计科目id%类型
,p_acc_name帐户。acc_name%类型
,p_acc_金额科目。acc_金额%类型
)
是
l_当前_余额编号;
l_新_余额编号;
开始
选择账户金额进入当前余额
来自帐户
其中acc_id=p_acc_id
更新;
l_新余额:=l_当前余额+应付账款金额;
如果l_新的_余额<0,则
引发应用程序错误(-20001,“对不起,您透支了”);
如果结束;
更新帐户
设置acc\U金额=l\U新余额,
acc_名称=p_acc_名称
其中acc_id=p_acc_id;
犯罪
终止
最终账户(api),;
/
对我来说,这个过程似乎还可以,但我会将其简化为一条语句,并添加一条显式回滚语句,如下所示:
UPDATE accounts
SET acc_amount = acc_amount + p_acc_amount,
acc_name = p_acc_name
WHERE acc_id = p_acc_id
RETURNING acc_amount INTO l_new_balance;
IF l_new_balance < 0 THEN
rollback;
raise_application_error(-20001, 'Sorry you re overdrawn');
ELSE
commit;
END IF;
更新帐户
设置会计科目金额=会计科目金额+会计科目金额,
acc_名称=p_acc_名称
其中acc_id=p_acc_id
将acc_金额返回到l_新余额中;
如果l_新的_余额<0,则
回降;
引发应用程序错误(-20001,“对不起,您透支了”);
其他的
犯罪
如果结束;
无需使用其他
选择。。。FOR UPDATE
以锁定行,因为UPDATE语句也会锁定行。多亏了返回到子句,您可以检索新余额,然后在更新后检查它,如果新余额太低,则回滚更改,否则提交更改。标题中说要更新,但SELECT语句中没有。为什么?我为更新添加的代码中没有提交sorrylocking在什么之后开始<代码>开始帐户\u api。upd\u帐户(1,'用户',1000)结束代码>UPDATE语句在更改数据之前放置锁。在begin account\u api.upd\u account(1,'user',1000)结束后,如果发出提交或回滚,锁将保持活动状态代码>我可以立即生成第二条语句,没有任何问题,是否应该出错?我想在其他用户尝试执行updateWell时出错,update语句会持续几毫秒,因此看起来可能会立即运行第二个事务,但实际上,这两个事务都是通过锁序列化的——第一次更新锁定记录,进行更改,然后提交——整个过程持续10-20毫秒。同时,第二个事务将等待记录解锁20毫秒,然后进行第二次更新。