PL/SQL8——PL/SQL记录

http://blog.csdn.net/robinson_0612/article/details/6084390

 PL/SQL记录有着类似于表的数据结构,是一个或多个字段且拥有数据类型的集合体。定义了PL/SQL记录类型之后,可以定义PL/SQL记录变

量。声明一个PL/SQL记录变量相当于定义了多个标量变量,简化了变量的声明,从而大大节省了内存资源。多用于简化单行多列的数据处理。

   

一、定义PL/SQL记录

    1.直接定义PL/SQL记录(首先定义记录类型,类型中包含的记录成员,其次是记录类型变量)

        TYPE type_name IS RECORD                                      --type_name用于指定自定义记录类型的名称

        (field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],   --定义记录的成员、数据类型及缺省值

        field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],

        ...

        field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);

        record_name TYPE_NAME;                                        --定义记录变量名record_name

    2.使用%rowtype定义PL/SQL记录

        使用%rowtype时,记录成员名称和类型与所依赖对象(表,视图,游标)名称和类型完全相同

        对于表和视图,游标所有列定义时,使用%rowtype定义将大大节省内存空间

        record_name table_name%rowtype              --基于不同的对象定义PL/SQL记录,此处为表

        record_name view_name%rowtype

        reocrd_name cursor_name%rowtype

 

二、PL/SQL记录的使用

    1. SELECT INTO语句中使用

        --使用PL/SQL记录变量

            undefine no

            DECLARE

                TYPE emp_record_type IS RECORD

                (

                    name emp.ename%TYPE,

                    salary emp.sal%TYPE,

                    dno emp.deptno%TYPE

                );

                emp_record emp_record_type;

            BEGIN                      --下面的查询到的数据插入到记录变量,注意列之间的顺序与声明顺序保持一致

                SELECT ename, sal, deptno INTO emp_record 

                FROM emp WHERE empno = &no;

                dbms_output.put_line(emp_record.name);   --输出时仅仅输出记录变量的一个成员emp_record.name

            END;           

           

            Enter value for no: 7788

            SCOTT

       

        --使用PL/SQL记录成员

            undefine no

            DECLARE

                TYPE emp_record_type IS RECORD

                (

                    name emp.ename%TYPE,

                    salary emp.sal%TYPE,

                    dno emp.deptno%TYPE

                );

                emp_record emp_record_type;

            BEGIN

                SELECT ename, sal INTO emp_record.name, emp_record.salary  --此处仅仅使用到了name和salary 成员

                FROM emp WHERE empno = &no;

                dbms_output.put_line(emp_record.name);   --输出时仅仅输出记录变量的一个成员emp_record.name

            END;

            /          

   

    2.INSERT语句中使用记录变量及成员

        --使用PL/SQL记录变量

            DECLARE

                dept_record dept%ROWTYPE;

            BEGIN

                dept_record.deptno := 50;

                dept_record.dname := 'ADMINISTRATOR';

                dept_record.loc := 'BEIJING';

                INSERT INTO dept VALUES dept_record;

            END;

            /      

            scott@ORCL> select * from dept where deptno=50;

 

                DEPTNO DNAME          LOC

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

                    50 ADMINISTRATOR  BEIJING          

       

        --使用PL/SQL记录成员

            scott@ORCL> DECLARE

              2  dept_record dept%ROWTYPE;

              3  BEGIN

              4  dept_record.deptno := 60;

              5  dept_record.dname := 'SALES';

              6  INSERT INTO dept(deptno, dname) VALUES(dept_record.deptno, dept_record.dname);

              7  END;

              8  /

 

            PL/SQL procedure successfully completed.   

 

            scott@ORCL> select * from dept where deptno in (50,60);

 

                DEPTNO DNAME          LOC

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

                    50 ADMINISTRATOR  BEIJING

                    60 SALES               

       

    3.UPDATE语句中使用记录变量及成员

        --使用PL/SQL记录变量(使用ROW来更新整行)

            DECLARE

                dept_record dept%ROWTYPE;

            BEGIN

                dept_record.deptno := 50;

                dept_record.dname := 'SERVICE';

                dept_record.loc := 'GuangZhou';

                UPDATE dept SET ROW = dept_record WHERE deptno = 50;--注意update时,使用ROW来表示整行

            END;

            /              

       

        --使用PL/SQL记录成员(使用成员记录更新单列或多列)

            scott@ORCL> DECLARE

              2  dept_record dept%ROWTYPE;

              3  BEGIN

              4      dept_record.loc:='ShangHai';

              5      UPDATE dept SET loc=dept_record.loc WHERE deptno=60;

              6  END;

              7  /         

       

    4.DELETE语句中使用记录变量及成员

            DECLARE

                dept_record dept%ROWTYPE;

            BEGIN

                dept_record.deptno:=60;

                DELETE FROM dept WHERE deptno=dept_record.deptno;

            END;

            /  

       

三、PL/SQL记录使用时的几个问题

    1.记录成员非空值的问题(非空值应当在初始化时赋值,而不是在使用时赋值)

        scott@ORCL> DECLARE

          2  TYPE ex_type IS RECORD

          3      (col1 NUMBER(3),

          4       col2 VARCHAR2(5) NOT NULL);

          5  ex_record ex_type;

          6  BEGIN

          7      ex_record.col1:=15;

                 ex_record.col1:=TO_CHAR(ex_record.col1);

          8      ex_record.col2:='John';

          9      DBMS_OUTPUT.PUT_LINE('ex_record.col1 is '||ex_record.col1);

         10      DBMS_OUTPUT.PUT_LINE('ex_record.col2 is '||ex_record.col2);

         11  END;

         12  /

             col2 VARCHAR2(5) NOT NULL);

             *

        ERROR at line 4:

        ORA-06550: line 4, column 6:

        PLS-00218: a variable declared NOT NULL must have an initialization assignment--错误消息指出非空值应当在初始化时指定

       

        DECLARE

          TYPE ex_type IS RECORD(

            col1 NUMBER(3),

            col2 VARCHAR2(5) NOT NULL := 'John');  --注意对于非空值应当在初始化时赋值,而不是在使用时赋值

          ex_record ex_type;

        BEGIN

          ex_record.col1 := 15;

          ex_record.col1 := TO_CHAR(ex_record.col1);

          --ex_record.col2:='John';

          DBMS_OUTPUT.PUT_LINE('ex_record.col1 is ' || ex_record.col1);

          DBMS_OUTPUT.PUT_LINE('ex_record.col2 is ' || ex_record.col2);

        END;

       

        ex_record.col1 is 15

        ex_record.col2 is John

       

    2.记录变量之间的赋值问题

        下面的例子中两个PL/SQL变量name_rec1与name_rec2尽管具有表面上相同的定义,但两者之间不能相互赋值

            DECLARE

              TYPE ex_type1 IS RECORD(

                first_name VARCHAR2(15),

                last_name  VARCHAR2(30));

              TYPE ex_type2 IS RECORD(

                first_name VARCHAR2(15),

                last_name  VARCHAR2(30));

              ex_rec1 ex_type1;

              ex_rec2 ex_type2;

            BEGIN

              ex_rec1.first_name := 'Robinson';

              ex_rec1.last_name  := 'Cheng';

              ex_rec2            := ex_rec1;  -- 不合理的赋值方式

            END;   

       

              ex_rec2            := ex_rec1;

                                    *

            ERROR at line 13:

            ORA-06550: line 13, column 25:

            PLS-00382: expression is of wrong type

            ORA-06550: line 13, column 3:

            PL/SQL: Statement ignored

       

        具有相同的记录类型时,不同记录变量之间可以相互赋值

            DECLARE

              TYPE ex_type1 IS RECORD(

                first_name VARCHAR2(15),

                last_name  VARCHAR2(30));

              ex_rec1 ex_type1;

              ex_rec2 ex_type1;

            BEGIN

              ex_rec1.first_name := 'Robinson';

              ex_rec1.last_name  := 'Cheng';

              ex_rec2            := ex_rec1;

              DBMS_OUTPUT.PUT_LINE('ex_rec1 is '||ex_rec1.first_name||'
'||ex_rec1.last_name);

              DBMS_OUTPUT.PUT_LINE('ex_rec2 is '||ex_rec2.first_name||'
'||ex_rec2.last_name);

            END;       

           

            ex_rec1 is Robinson Cheng

            ex_rec2 is Robinson Cheng

    3.基于表,基于游标,基于自定义PL/SQL记录的综合使用

        DECLARE

          CURSOR dept_cur IS --声明游标

            SELECT * FROM dept WHERE deptno = 30;

          TYPE dept_type IS RECORD( --声明一个自定义的PL/SQL记录类型

            deptno NUMBER(2),

            dname  VARCHAR2(14),

            loc    VARCHAR2(13));

 

          dept_rec1 dept%ROWTYPE; --声明基于表dept的记录变量

          dept_rec2 dept_cur%ROWTYPE; --声明基于游标dept_cur的记录变量

          dept_rec3 dept_type; --声明基于自定义dept_type的记录变量

 

        BEGIN

          SELECT * INTO dept_rec1 FROM dept WHERE deptno = 30; --将查询的结果插入到基于表dept的记录变量中

 

          OPEN dept_cur;

          LOOP

            FETCH dept_cur

              INTO dept_rec2; --将游标的内容插入到游标记录变量中

            EXIT WHEN dept_cur%NOTFOUND;

          END LOOP;

 

          dept_rec1 := dept_rec2;

          dept_rec3 := dept_rec2;

 

          DBMS_OUTPUT.PUT_LINE(dept_rec1.deptno || ' ' || dept_rec1.dname);

          DBMS_OUTPUT.PUT_LINE(dept_rec2.deptno || ' ' || dept_rec2.dname);

          DBMS_OUTPUT.PUT_LINE(dept_rec3.deptno || ' ' || dept_rec3.dname);

        END;

       

        30 SALES

        30 SALES

        30 SALES

           

时间: 2024-07-31 06:19:53

PL/SQL8——PL/SQL记录的相关文章

PL/SQL --> PL/SQL记录

--======================= -- PL/SQL --> PL/SQL记录 --=======================       PL/SQL记录有着类似于表的数据结构,是一个或多个字段且拥有数据类型的集合体.定义了PL/SQL记录类型之后,可以定义PL/SQL记录变 量.声明一个PL/SQL记录变量相当于定义了多个标量变量,简化了变量的声明,从而大大节省了内存资源.多用于简化单行多列的数据处理.     一.定义PL/SQL记录     1.直接定义PL/SQL

php CI框架插入一条或多条sql记录示例

  本节主要为大家介绍了php CI框架如何插入一条或多条sql记录,示例代码如下,不了解的朋友不要错过 1.插入一条记录 $data = array( 'title' => 'My title' , 'name' => 'My Name' , 'date' => 'My date' ); $this->db->insert('mytable', $data); // Produces: INSERT INTO mytable (title, name, date) VALU

如何清除oracle中的执行sql记录在日志里面的的记录

问题描述 如何清除oracle中的执行sql记录在日志里面的的记录 如何清除oracle中的执行sql记录在日志里面的的斤斤计较绝对经典如何清除oracle中的执行sql记录在日志里面的的记录 解决方案 http://www.zhihu.com/question/27579044

查询SQLSERVER执行过的SQL记录

原文:查询SQLSERVER执行过的SQL记录 有的时候,需要知道SQLSERVER执行了什么语句,可以用下面的方法: SELECT TOP 1000 --创建时间 QS.creation_time, --查询语句 SUBSTRING(ST.text,(QS.statement_start_offset/2)+1, ((CASE QS.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE QS.statement_end_offse

php CI框架插入一条或多条sql记录示例_php技巧

1.插入一条记录 $data = array( 'title' => 'My title' , 'name' => 'My Name' , 'date' => 'My date' ); $this->db->insert('mytable', $data); // Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') 2.插入多条记录 $data

c#怎么查询SQL记录,显示在TEXTBOX上

问题描述 我想查询特定的ID列,让其所有的信息,分别显示在多个TEXTBOX控件上,求代码或例子... 解决方案 解决方案二:SqlDataReader读取简单的操作解决方案三:textBox1.DataBindings,添加字段绑定解决方案四:SqlDataReader读取解决方案五:额,就是忘了怎么用SqlDataReader读取了...解决方案六:搜一下repeater之类的绑定数据的控件吧,这东西很容易找到的解决方案七:嗯嗯,我找找看解决方案八:获取DataSetds;获取DataTab

动态SQL和PL/SQL的EXECUTE IMMEDIATE选项

动态       EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当容易编码.尽管DBMS_SQL仍然可用,但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上.    使用技巧   1. EXECUTE IMMEDIATE将不会提交一个DML事务

PL/SQL重建存储过程时出错

前提:测试库和正式库的表结构相同,并且存储过程(5570行)在测试环境下运行正常. 晚上八点,产品准备上线的时候,开始拷贝存储过程(procedure)时,竟然出问题了!!!而且是找不到原因, 很是莫名其妙,只好临时中断了上线,之后的两天,开始苦逼的查找原因,查无所获,决定放弃,改为曲线救国.在重建P的时候,如果将此P分段创建,则编译通过,分析认为,新建P出错,更新P没问题:无意间,点了下"格式化代码"操作,重建竟然成功了,于是查找不同代码,发现原存储过程有几行代码是 /(除号)  *

全面探讨PL/SQL的复合数据类型

PL/SQL有两种复合数据结构:记录和集合.记录由不同的域组成,集合由不同的元素组成.在本文中我们将讨论记录和集合的类型.怎样定义和使用记录和集合. PL/SQL记录 记录是PL/SQL的一种复合数据结构,scalar数据类型和其他数据类型只是简单的在包一级进行预定义,但复合数据类型在使用前必须被定义,记录之所以被称为复合数据类型是因为他由域这种由数据元素的逻辑组所组成.域可以是scalar数据类型或其他记录类型,它与c语言中的结构相似,记录也可以看成表中的数据行,域则相当于表中的列,在表和虚拟