zoukankan      html  css  js  c++  java
  • Oracle 11g 学习笔记 (3)

    一些 ASP.NET + Oracle 11g 系统边写边学的随笔,包括 Oracle 的「ROWNUM」、「Sequence 流水号」。

    (六) Oracle 的 ROWNUM,等同其它数据库的 SELECT TOP

    Oracle 不支持 SELECT TOP 语法,若要撷取最大的几笔、或最小的几笔记录,必须用 ROWNUM 关键词并搭配 Subquery。

    例如要取最小的 10 笔,可用如下语句:
    SELECT id, name, ROWNUM FROM (SELECT id, name FROM table ORDER BY id) WHERE ROWNUM <= 10;

    若要取最大的 10 笔,就再加上 DESC:
    SELECT id, name, ROWNUM FROM (SELECT id, name FROM table ORDER BY id DESC) WHERE ROWNUM <= 10;

    此外,还可以做一些变化应用:
    SELECT a.id, a.name, ROWNUM FROM (SELECT id, name FROM table ORDER BY id) a WHERE ROWNUM <= 10 ORDER BY ROWNUM DESC;

    要注意的是,包含有 ROWNUM 的 WHERE 条件式,一定要包含 1,例如:
    WHERE ROWNUM >0
    WHERE ROWNUM >=1
    WHERE ROWNUM <10
    若不包含 1 的话,所下的查询会永远查无数据。

    Oracle 的 ROWNUM、Top-N Query 官方教学 (英文):
    http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
    http://www.oracle.com/technology/oramag/oracle/07-jan/o17asktom.html

    此外,Oracle 还有两种 ROW_NUMBER() OVER 和 RANK() OVER 语法,亦可将已查询出来的全部数据,再给予连续的流水号。虽然它们无法像 ROWNUM 一样给 WHERE 条件式,但适
    合用来撰写 ASP.NET GridView 控件的「分页」功能的 Stored Procedure。有关其用法,可参考:
    http://i.cn.yahoo.com/gaoxiaoqing2003/blog/p_8/
    http://keke-wanwei.javaeye.com/blog/138632

    (七) Oracle 的 Sequence,等同其它数据库的 Identity

    Oracle 不支持 SQL Server 和 Sybase 都支持的 Identity 自动增号字段,也不支持 INSERT INTO 以后立即取得最新一笔记录 Identity 号码的「SELECT @@identity;」语法,
    要达成上述功能,必须改用 Sequence (流水号)。

    Sequence 不包含在 table 中,某一个 Sequence 亦不和 table 做一对一的对应。要用 Sequence,必须先自己手动建立,语法为:
    CREATE SEQUENCE seq_name;

    CREATE SEQUENCE seq_name
    INCREASE BY 1
    START WITH 1
    MAXVALUE 9999
    NOCACHE
    NOCYCLE;

    若不下参数,预设从 1 开始,每次增号 1,最大值为 10 的 27 次方,存储值达到 MAXVALUE 不会自动重新编号 (若对应至 table 的 Primary Key,此值应采默认值 NOCYCLE);
    CACHE 选项的默认值,会在 memory 产生 20 笔数据。

    执行以下语句,可看到所有 Sequence 的设定及存储内容。其中的 LAST_NAME 为其下一个将要产生的值。
    select * from user_sequences;

    要看某一个 Sequence 的当前值、下一个值,可用如下语句:
    select table1_seq.CURRVAL from dual;
    select table1_se1.NEXTVAL from dual;

    需注意第二个语句 NEXTVAL 只要一被执行到,该个 Sequence 的内部编号,就会自动增加一个号码,而不仅只是 select 撷取而已。


    若要搭配 Sequence,新增一笔记录到 table,可用如下语法:
    INSERT INTO table1 (id, name) VALUES (table1_seq.NEXTVAL, 'name1');


    在 Oracle 10g 以前的版本,或您用的是 OleDb 联机方式 (OracleClient 亦可),当您想在 INSERT INTO 记录时,Primary Key 希望能写入 Sequence 的值,可用如下写法 (亦
    可在新增完成后,立即传回该笔记录最新的 Sequence 值):

    using System.Data.OleDb;
    OleDbConnection odConn = null;
    OleDbCommand odCmd = null;
    Int64 intDATA_ID_AfterInserted = 0;
    string strSql = "BEGIN SELECT table1_seq.NEXTVAL INTO :id FROM dual; INSERT INTO table1(id, name) VALUES(:id, :name); END;";

    ...中间略...

    OleDbParameter p;
    p = odCmd.Parameters.Add(":id", OleDbType.Double, 7);
    p.Direction = ParameterDirection.Output;
    odCmd.Parameters.Add(":name", OleDbType.VarWChar, 30).Value = TextBox1.Text;

    odCmd.ExecuteNonQuery();
    intDATA_ID_AfterInserted = Convert.ToInt64(p.Value); // 立即传回该笔记录最新的 Sequence 值


    若您用的是 Oracle 10g 及以后的版本,且用的是 OracleClient Data Provider,则可用以下的「RETURNING INTO」更简洁写法。但须注意,OleDb 联机方式若用此种写法,在写
    入时并不会造成 error 或引发 exception,但写入值会不正常。

    string strSql = "INSERT INTO table1(id, name) VALUES(table1_seq.NEXTVAL, :name) RETURNING id INTO :id";


    ---------------------------------------------
    本帖第 (七) 点的 ASP.NET 2.0 + Oracle 11g 示例下载点 (批次新增 + 新增后马上取得最新 Sequence 值):
    https://files.cnblogs.com/WizardWu/081128.zip
    ---------------------------------------------

    若您执行本示例的操作系统中,并未安装 Oracle 11g server-side 软件 (数据库安装在别台主机),则当您用 Visual Studio 执行本示例时,可能会出现类似以下的错误讯息:
    “OraOLEDB.Oracle.1”未在本地计算机注册

    解决方式,是去 Oracle 官方网站,下载 Data Provider 和 Client-side 程序并安装,下载网址如下:
    http://www.oracle.com/technology/software/tech/windows/odpnet/index.html (较新)
    http://www.oracle.com/technology/software/tech/dotnet/utilsoft.html (较旧)

    安装完后,即能以 Visual Studio 执行本示例。但若改以 IIS 执行时,仍会出现上述的错误信息,因为您还要再设定一些让 IIS / ASP.NET 的用户,有写入伺服端 Oracle 所在文件夹的权限。有关其设定,其参考本站下一篇帖子「Oracle 11g 学习笔记 (4)」。

  • 相关阅读:
    JS进阶篇2---函数防抖(debounce)
    vue 的"响应式"是什么意思/ Object.freeze( ) 阻止数据响应
    try{...}catch(){...}语句的使用
    总结一下ES6的promise
    《ES6标准入门》(六)之Promise对象2——then()和catch()方法
    大白话讲解Promise(一)
    解决VSCode单击文件会替换已经打开文件的问题
    通俗理解“回调函数”
    vue中的时间格式处理
    vue之项目踩坑笔记
  • 原文地址:https://www.cnblogs.com/WizardWu/p/1343100.html
Copyright © 2011-2022 走看看