`
271788203
  • 浏览: 490248 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

PL/SQL NEXTVAL DUAL表

阅读更多


dual表是个虚拟表,你在操作大多数Oracle对象的时候都可以使用这个表,比如sequence,sysdate等等。
比如:
select sysdate from dual
select seq1.nextval from dual

----------------------------------------------------------------------------------------------------------------------

DUAL表是一个奇特的小结构。这个表驻留于SYS模式中,PL/SQL开发人员用它来访问那些PL/SQL自身不提供的SQL特定功能。

DUAL表的最常见应用就是生成和检索一个序列中的下一个数值,通常是用于一个表的主关键字,如下所示: 

 

SELECT employee_seq.NEXTVAL
   INTO :employee.employee_id
   FROM DUAL;

 

Oracle不允许我们直接在PL/SQL代码中引用employee_seq.NEXTVAL;而是必须从一个SELECT语句中调用它。为什么我们要为这一操作使用DUAL表呢?因为它只有唯一一个行(或者应该只有一行)。 NEXTVAL操作符于是自该序列返回下一个(也是唯一的一个)取值。不幸的是,经常会听到参加我们研讨会的人们说到此DUAL表不至一行的情况。在这种情况下,我以前的查询将会出现TOO_MANY_ROWS错误而失败。更糟的情况是,PL/SQL中某些内建的函数,如USER也可能失败,从Oracle数据所提供的stdbody.sql文件中所取出的这一代码中可以清楚地看出这一点:

FUNCTION USER
    RETURN VARCHAR2
  IS
    c VARCHAR2 (255);
  BEGIN
     SELECT USER
     INTO c
     FROM SYS.DUAL;
 
    RETURN c;
 END;

 

如果(a)你依靠DUAL表来生成序列值和(b)你不能保证DUAL表中的行数不超过一行,那么就很难拥有一个自管理式的代码基础。当然,你可以定义一个用于DUAL表的触发器,以防止任何向DUAL表中插入多于一行数据的尝试。但是,为SYS所拥有的表创建用户定义的触发器是一个禁忌。那么,如果开发人员希望避免使用DUAL表,那他们应当怎么做呢?创建并使用他们自己的单行表,并使其具有与DUAL的结构相同的结构。

代码清单5 给出了创建这样一个表的代码和为该表定义一个触发器以保证其只能包含一行数据。

定义了onerow后,我现在可以取得我的下一个主关键字值,如下所示:

SELECT employee_seq.NEXTVAL
  INTO :employee.employee_id
  FROM onerow;

 

因为我对onerow的内容有更多的控制,所以相对于从DUAL中进行查询来说,这是一个更好的解决方案。然而,它还不太理想。如果Oracle数据库的未来版本允许在PL/SQL中直接引用<sequence>.NEXTVAL,那么情况会如何呢? 我将坚持用所有这些现在过时的代码,我可能希望用更简单(且更有效)的代码来代替这些代码:

 

:employee.employee_id := employee_seq.NEXTVAL;

于是,作为使我的应用程序免于被破坏并且易于随着时间的推移而进行更新的最后一步,我将我的查询隐藏于一个"一般"函数之后,此函数利用自有的动态SQL来一般地获得任意序列的下一个值,如代码清单6所示。

现在我可以只用下面的代码就可以获得我的主关键值:

:employee.employee_id := next_pky ('employee_seq');

 

并且,当Oracle数据库取消关于引用NEXTVAL的限制之后,我可以在这一个函数中修改实施;在重新编译后,我的全部代码就可以更新以便使用Oracle数据库的最新功能。尽管这一步骤不会导致100%的自管理,但它确实有助于将你的应用程序基础达到"最少管理"的状态。

你甚至可以利用自有的动态SQL将所有这些步骤组合成一个单一的过程,它将在你的模式中设置对DUAL表的替换操作。  

分享到:
评论

相关推荐

    Oracle存储过程 知识点总结

    另外,如果需要先存储序列值再使用,可以通过查询序列的`NEXTVAL`到变量,如`SELECT SEQNAME.NEXTVAL INTO id_temp FROM DUAL;`,然后使用变量`id_temp`。 2. **PL/SQL中的错误处理**: - 在PL/SQL中,如果在条件...

    ORACLE_PLSQL存储过程教程.doc

    你可以直接在INSERT语句中使用,如`INSERT INTO test VALUES(SEQNAME.NEXTVAL)`,或者通过查询DUAL表来获取,如`SELECT SEQNAME.NEXTVAL INTO id_temp FROM DUAL`,然后使用变量id_temp。 在编写PL/SQL代码时,可能...

    Orcal 数据库触发器文件

    Oracle数据库触发器是数据库管理系统中的一种重要特性,它允许开发者在特定的数据操作(如INSERT、UPDATE、DELETE)之前或之后执行自定义的SQL代码或PL/SQL块。这些代码可以用来实现业务规则、数据验证、审计跟踪等...

    oracle存储过程教程

    Oracle存储过程是数据库管理系统Oracle中的一个重要特性,它允许开发者创建一系列复杂的SQL和PL/SQL语句,形成可重用的程序单元。Oracle存储过程对于初学者来说,理解其基本概念和使用方法至关重要。 首先,我们要...

    调试oracle触发器方法

    - 特别是在示例代码中,`SELECT iampuser.SEQ_EmployerRegInfo.NEXTVAL INTO :NEW.EmployerID FROM DUAL;`这行语句是为新插入的记录获取序列号。如果在调试过程中发现`iampuser.SEQ_EmployerRegInfo.NEXTVAL`没有...

    plsql编号序列号

    这个例子首先创建了一个名为`test_table`的表和一个名为`test_seq`的序列,然后在PL/SQL块中获取序列的下一个值,并将其插入到表中。 总之,PLSQL编号序列号是Oracle数据库中实现自动递增ID的一种有效方法,它通过...

    Oralec,mysql数据库基础知识小结

    根据给定文件的信息,我们可以提炼出关于Oracle与MySQL数据库的基础知识和特定的Oracle PL/SQL编程概念。以下是对这些知识点的详细阐述: ### Oracle数据库基础知识 #### 1. Oracle SQL语句与序列(Sequence) - ...

    oracle 不用新建序列 重置序列(从1开始增长)

    这种方法通过编写PL/SQL过程来动态调整序列的增量,从而达到重置的目的。 ### Oracle序列重置方法 首先,我们需要理解Oracle序列的工作原理。序列是由两个主要属性定义的:`INCREMENT BY` 和 `START WITH`。`...

    第8章 Oracle 的其它对象.pptx

    **触发器(Triggers)**是与表、视图或其他数据库事件关联的PL/SQL代码,当特定事件发生时自动执行,如INSERT、UPDATE或DELETE操作。 **函数(Functions)**与存储过程类似,但函数必须返回一个值,而存储过程可能...

    Oracle存储过程实例[定义].pdf

    这个过程还展示了如何返回主键(`UserID`)值,通过从`DUAL`表(Oracle的一个特殊表,通常用于单行、单列的查询)中选择`currval`,并将结果存入输出参数。 在Oracle中,序列(Sequence)是一种自动增长的数据类型...

    oracle 存储过程使用 sequence

    Oracle存储过程是数据库管理系统中一个非常重要的特性,它允许开发者编写包含一系列SQL和PL/SQL语句的程序单元,以实现更复杂的业务逻辑。在Oracle中,Sequence则是一种自增序列号生成器,通常用于主键或者唯一标识...

    powerdesigner创建oracle_数据库表,设置表主键列为自动增长

    SELECT Sequence_LotCateID.NEXTVAL INTO :NEW.lcId FROM DUAL; -- Error handling EXCEPTION WHEN integrity_error THEN RAISE_APPLICATION_ERROR(errno, errmsg); END; / INSERT INTO G_EC_LotteryCategory ...

    Oracle.pdf

    SELECT 序列名.NEXTVAL FROM DUAL; ``` 8. Trigger(触发器):在特定事件(如INSERT、UPDATE、DELETE)发生时自动执行的PL/SQL代码段。例如,当更新工单回复时间时自动计算处理时长,或为无指定ID的数据自动填充...

    oracle试题整理.docx

    7. **获取序列值**:使用`SELECT seq1.NEXTVAL FROM DUAL`可以获取序列seq1的下一个值,而`SELECT seq1.CURRVAL FROM DUAL`获取当前值,但在使用currval之前,必须先使用nextval。 8. **LGWR进程**:LGWR(Log ...

    Oracle创建序列的方法及技巧.doc

    在表单中,你可以添加以下PL/SQL代码: ```sql SELECT seq_Agents.NEXTVAL INTO :AGENTS.AGENTID FROM dual; ``` 这行代码将序列的下一个值赋给表单的 `AGENTID` 字段,从而在插入新记录时自动填充主键。 序列的...

    Oracle创建主键自增表(sql语句实现)及触发器应用

    SELECT TestIncrease_Sequence.NEXTVAL INTO :NEW.userid FROM DUAL; END; /* 退出sqlplus行编辑 */ ``` 这个触发器会在`Test_Increase`表上的每个插入操作之前运行,将序列的下一个值赋给新行的`userid`字段。 ...

    oracle_function用法

    * 不能使用 PL/SQL 的特有数据类型(boolean, table, record 等) * 不能在 SQL 语句中包含 INSERT, UPDATE 和 DELETE 语句 函数语法 Oracle 函数的语法如下: `CREATE OR REPLACE FUNCTION function_name (argu1...

    oracle

    SELECT scott.seq_test.NEXTVAL INTO :new.tid FROM dual; END trg_test; ``` 4. **测试** 插入多条记录进行测试。 ```sql SET SERVEROUTPUT ON; SET AUTO ON; DECLARE c_count INT := 0; BEGIN FOR c_...

    oracle常用操作(创建数据库等操作)

    2. 用PL/SQL创建用户 创建用户通常涉及到指定用户名、密码、默认表空间和临时表空间。例如: ```sql CREATE USER 用户名 IDENTIFIED BY 密码 DEFAULT TABLESPACE 默认表空间 TEMPORARY TABLESPACE 临时表空间; ``` ...

    8 数据库对象&表空间.ppt

    6. **其他对象**:除了上述对象外,还有存储过程、函数、包等,它们用于存储和执行PL/SQL代码,实现业务逻辑或数据库操作。 在使用同义词时,不同类型的用户有不同的权限限制。例如,方案用户可以直接使用自己的...

Global site tag (gtag.js) - Google Analytics