而不是使用 Oracle 序列触发
Instead of trigger with Oracle sequence
我有一些旧应用程序(遗留应用程序)使用它们自己的 MAX NUMBER table。问题是我们不能同时修改和发布所有的应用程序。因此,我们希望分阶段进行。
我提出了以下建议。但是,我不知道为什么Oracle在我执行更新语句时执行视图的select查询。
当前使用情况:
-- Update the max number table
Update Sysadm.DummyTable
Set MaxNumber = MaxNumber + 1;
-- An application needs to select current value from the MaxNumber table.
Select * From Sysadm.DummyTable;
建议的解决方案:
CREATE SEQUENCE SYSADM.SEQ_DummyTable START WITH 12345 INCREMENT BY 1;
--- Common function ---
--- The following function will get the current sequence number of the Oracle sequence across all the sessions.
CREATE OR REPLACE FUNCTION Sysadm.GetCurrValue(sLSeqName VARCHAR)
RETURN NUMBER
AS nLDummy NUMBER;
BEGIN
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.CURRVAL Into nLDummy FROM DUAL;
Else
Return null;
End If;
RETURN(nLDummy);
END;
/
--- The existing DummyTable table will be dropped and DummyTable (exactly with the same name including its structure) view will be created.
Create or Replace View Sysadm.DummyTable (MAXNUMBER)
As
Select sysadm.GetCurrValue('SEQ_DUMMYTABLE') As MAXNUMBER From Sysadm.ABC Where RowNum = 1;
--- The following trigger will get executed when the application tried to update the DummyTable table. This trigger will get executed instead of update statement from the application.
Create Or Replace Trigger Sysadm.TR_DummyTable
Instead of UPDATE ON Sysadm.DummyTable
Declare
nLDummy NUMBER;
Begin
SELECT SEQ_DUMMYTABLE.NEXTVAL Into nLDummy FROM DUAL;
End;
/
我在视图上使用 而不是 触发器。但是,当我尝试执行以下更新查询时,我收到一条错误消息。
-- Update the max number table
Update Sysadm.DummyTable
Set MaxNumber = MaxNumber + 1;
ORA错误信息:
Error starting at line : 1 in command -
Update Sysadm.DUMMYTABLE Set MaxNumber = MaxNumber + 1
Error report -
SQL Error: ORA-08002: sequence SEQ_DUMMYTABLE.CURRVAL is not yet defined in this session
ORA-06512: at "SYSADM.GETCURRVALUE", line 10
08002. 00000 - "sequence %s.CURRVAL is not yet defined in this session"
*Cause: sequence CURRVAL has been selected before sequence NEXTVAL
*Action: select NEXTVAL from the sequence before selecting CURRVAL
正如 Oracle 告诉您的那样:如果您没有从该会话中的序列中获取,则无法获取 currval
,您可以通过选择 nextval
来获取。例如:
SQL> create sequence seqa;
Sequence created.
这不起作用 - 你已经知道了,你已经遇到了错误:
SQL> select seqa.currval from dual;
select seqa.currval from dual
*
ERROR at line 1:
ORA-08002: sequence SEQA.CURRVAL is not yet defined in this session
因此:nextval
首先,currval
其次(如果需要的话):
SQL> select seqa.nextval from dual;
NEXTVAL
----------
1
SQL> select seqa.currval from dual;
CURRVAL
----------
1
SQL>
在你的情况下,这意味着这看起来像
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.NEXTVAL Into nLDummy FROM DUAL;
Else -------
只需更改功能,我们就可以让它工作。这也将解决并发问题:
--- The following function will get the current sequence number of the Oracle sequence across all the sessions.
CREATE OR REPLACE FUNCTION Sysadm.GetCurrValue(sLSeqName VARCHAR)
RETURN NUMBER
AS nLDummy NUMBER;
BEGIN
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.CURRVAL Into nLDummy FROM DUAL;
Else
Return null;
End If;
RETURN(nLDummy);
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/
我有一些旧应用程序(遗留应用程序)使用它们自己的 MAX NUMBER table。问题是我们不能同时修改和发布所有的应用程序。因此,我们希望分阶段进行。
我提出了以下建议。但是,我不知道为什么Oracle在我执行更新语句时执行视图的select查询。
当前使用情况:
-- Update the max number table
Update Sysadm.DummyTable
Set MaxNumber = MaxNumber + 1;
-- An application needs to select current value from the MaxNumber table.
Select * From Sysadm.DummyTable;
建议的解决方案:
CREATE SEQUENCE SYSADM.SEQ_DummyTable START WITH 12345 INCREMENT BY 1;
--- Common function ---
--- The following function will get the current sequence number of the Oracle sequence across all the sessions.
CREATE OR REPLACE FUNCTION Sysadm.GetCurrValue(sLSeqName VARCHAR)
RETURN NUMBER
AS nLDummy NUMBER;
BEGIN
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.CURRVAL Into nLDummy FROM DUAL;
Else
Return null;
End If;
RETURN(nLDummy);
END;
/
--- The existing DummyTable table will be dropped and DummyTable (exactly with the same name including its structure) view will be created.
Create or Replace View Sysadm.DummyTable (MAXNUMBER)
As
Select sysadm.GetCurrValue('SEQ_DUMMYTABLE') As MAXNUMBER From Sysadm.ABC Where RowNum = 1;
--- The following trigger will get executed when the application tried to update the DummyTable table. This trigger will get executed instead of update statement from the application.
Create Or Replace Trigger Sysadm.TR_DummyTable
Instead of UPDATE ON Sysadm.DummyTable
Declare
nLDummy NUMBER;
Begin
SELECT SEQ_DUMMYTABLE.NEXTVAL Into nLDummy FROM DUAL;
End;
/
我在视图上使用 而不是 触发器。但是,当我尝试执行以下更新查询时,我收到一条错误消息。
-- Update the max number table
Update Sysadm.DummyTable
Set MaxNumber = MaxNumber + 1;
ORA错误信息:
Error starting at line : 1 in command -
Update Sysadm.DUMMYTABLE Set MaxNumber = MaxNumber + 1
Error report -
SQL Error: ORA-08002: sequence SEQ_DUMMYTABLE.CURRVAL is not yet defined in this session
ORA-06512: at "SYSADM.GETCURRVALUE", line 10
08002. 00000 - "sequence %s.CURRVAL is not yet defined in this session"
*Cause: sequence CURRVAL has been selected before sequence NEXTVAL
*Action: select NEXTVAL from the sequence before selecting CURRVAL
正如 Oracle 告诉您的那样:如果您没有从该会话中的序列中获取,则无法获取 currval
,您可以通过选择 nextval
来获取。例如:
SQL> create sequence seqa;
Sequence created.
这不起作用 - 你已经知道了,你已经遇到了错误:
SQL> select seqa.currval from dual;
select seqa.currval from dual
*
ERROR at line 1:
ORA-08002: sequence SEQA.CURRVAL is not yet defined in this session
因此:nextval
首先,currval
其次(如果需要的话):
SQL> select seqa.nextval from dual;
NEXTVAL
----------
1
SQL> select seqa.currval from dual;
CURRVAL
----------
1
SQL>
在你的情况下,这意味着这看起来像
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.NEXTVAL Into nLDummy FROM DUAL;
Else -------
只需更改功能,我们就可以让它工作。这也将解决并发问题:
--- The following function will get the current sequence number of the Oracle sequence across all the sessions.
CREATE OR REPLACE FUNCTION Sysadm.GetCurrValue(sLSeqName VARCHAR)
RETURN NUMBER
AS nLDummy NUMBER;
BEGIN
if (sLSeqName = 'SEQ_DUMMYTABLE') Then
SELECT SEQ_DUMMYTABLE.CURRVAL Into nLDummy FROM DUAL;
Else
Return null;
End If;
RETURN(nLDummy);
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/