访问ORACLE

访问ORACLE

(一)检索单行数据

1、当在PL/SQL块中嵌入SELECT语句时,必须要带有INTO子句。该语句必须且只能返回一条数据,否则会触发NO_DATE_FOUND或TOO_MANY_ROWS例外。

SELECT...INTO...语法:

    SELECT select_list INTO (variable_name1[,......] | record_name)

    FROM table|view     

    WHERE condition;   

 

例1、使用标量变量接收数据

DECLARE
  v_no dept.deptno%type not null default 10;
  v_name dept.dname%type;
  v_loc dept.loc%type;
BEGIN
  select deptno,dname,loc into v_no,v_name,v_loc from dept where deptno=20;
  dbms_output.put_line('部门号: '||v_no||' 部门名: '||v_name||' 部门位置: '||v_loc);
End;

输出:部门号: 20 部门名: RESEARCH 部门位置: DALLAS

例2、使用记录变量接收数据

DECLARE
  TYPE record1 IS RECORD
  (
  v_no dept.deptno%type not null default 10,
  v_name dept.dname%type,
  v_loc dept.loc%type,
  v char
  );
  r1 record1;
BEGIN
  select deptno,dname,loc into r1.v_no,r1.v_name,r1.v_loc from dept where deptno=30;
  dbms_output.put_line('部门号: '||r1.v_no||' 部门名: '||r1.v_name||' 部门位置: '||r1.v_loc);
End;

输出:部门号: 30 部门名: SALES 部门位置: CHICAGO

DECLARE
  TYPE record1 IS RECORD
  (
  v_no dept.deptno%type not null default 10,
  v_name dept.dname%type,
  v_loc dept.loc%type
  );
  r1 record1;
BEGIN
  select deptno,dname,loc into r1 from dept where deptno=30;
  dbms_output.put_line('部门号: '||r1.v_no||' 部门名: '||r1.v_name||' 部门位置: '||r1.v_loc);
End;

输出:部门号: 30 部门名: SALES 部门位置: CHICAGO

 2、例外处理

 ①NO_DATA_FOUND   --SELECT ...INTO...语句没有返回任何数据时,会触发NO_DATA_FOUND 例外。

 例:

DECLARE
  TYPE record1 IS RECORD
  (
  v_no dept.deptno%type not null default 10,
  v_name dept.dname%type,
  v_loc dept.loc%type,
  v char
  );
  r1 record1;
BEGIN
  select deptno,dname,loc into r1.v_no,r1.v_name,r1.v_loc from dept where deptno=50;
  dbms_output.put_line('部门号: '||r1.v_no||' 部门名: '||r1.v_name||' 部门位置: '||r1.v_loc);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.put_line('不存在该部门号,请检查');
End;

输出:不存在该部门号,请检查

 

②TOO_MANY_ROWS  --SELECT ...INTO...语句返回多条数据时,会触发TOO_MANY_ROWS  例外。

例:

DECLARE
  TYPE record1 IS RECORD
  (
  v_no dept.deptno%type not null default 10,
  v_name dept.dname%type,
  v_loc dept.loc%type,
  v char
  );
  r1 record1;
BEGIN
  select deptno,dname,loc into r1.v_no,r1.v_name,r1.v_loc from dept where deptno>=30;
  dbms_output.put_line('部门号: '||r1.v_no||' 部门名: '||r1.v_name||' 部门位置: '||r1.v_loc);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.put_line('不存在该部门号,请检查');
  WHEN TOO_MANY_ROWS THEN
    DBMS_OUTPUT.put_line('返回了多行数据');
End;

输出:返回了多行数据

 

3、WHERE子句使用注意事项

     在WHERE子句中使用变量时注意,变量名不能与列名相同,否则会触发TOO_MANY_ROWS例外。

例:

declare
  deptno dept.deptno%type :=10;
  v_name dept.dname%type;
begin
  select dname into v_name from dept where deptno=deptno;
exception
  when too_many_rows then
    dbms_output.put_line('返回了多条数据——例外!');
end;

输出:返回了多条数据——例外!

 

 

(二)操纵数据

在pl/sql中不仅可以使用SELECT...INTO...,还可以使用INSERT、UPDATE、DELETE、游标等。

1、INSERT      --必须为表的主键列和NOT NULL列提供数据。

  • 使用INSERT...VALUES...插入数据,语法:

   INSERT INTO table|view [coumn1[,......]] VALUES (column1[,......]);

 

例:

declare
  v_name varchar2(10) not null default 'china';
begin
  insert into v_dept values(50,v_name,'beijing');   --使用变量
end;

 

  • 使用子查询插入数据,语法:

INSERT INTO table|view [coumn1[,......]] subquery;

 

例:

begin
  insert into v_dept select * from dept;
end;

 

2、UPDATE

  • 使用表达式更新列值

语法:UPDATE table|view SET <column>=<value>[,<column>=<value>,......] [WHERE conditions];

例:

DECLARE
     V char(10) not null :='项目部';
BEGIN
    UPDATE V_DEPT SET DNAME=V WHERE DEPTNO=&N;  --使用变量
END;
 

  • 使用子查询更新列值

语法: UPDATE table|view SET (column1,column2,...)=(select column1,column2,... from table|view)

[WHERE conditions];

例:

begin
  update v_dept set (deptno,dname,loc)=(select * from dept where deptno=10) ;
end;

 

 3、DELETE

  •  使用变量或数值删除数据

语法:DELETE FROM table|view [WHERE condition];

例:

declare
  v_no constant number(2):=10;
begin
  delete from v_dept where deptno=v_no;
end;

 

  • 使用子查询删除数据

语法:DELETE FROM table|view [WHERE (column1,... )=(select column1,... from table|view)];

例:

begin
  delete from v_dept where dname=(select dname from v_dept where deptno=10);
end;

 

 

 

 4、游标

(三)使用事务控制语句

1、事务的作用:事务用于确保数据库数据的一致性,他由一组相关的DML语句组成。该组DML语句所执行的操作要么全部成功,要么全部取消。

2、数据库事务主要由INSERT、UPDATE、DELETE和SELECT...FOR  UPDATE语句组成。当在应用程序中执行第一条SQL语句时,开始事务,当执行COMMIT或ROLLBACK语句时,结束事务。

3、事务和锁

     当执行事务操作(DML语句)时,ORACLE会在被作用表上加表锁,以防止其他用户改变表结构。同时会在被作用行上加行锁,以防止其他事务在相应行上执行DML操作。

例1:加表锁

错误操作方法:

会话1:

SQL> update v_dept set dname='售货员' WHERE DEPTNO=10;

已更新 1 行。

会话2:

SQL> ALTER TABLE V_DEPT ADD AAA VARCHAR2(20);
ALTER TABLE V_DEPT ADD AAA VARCHAR2(20)
*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源

正确操作方法:

会话1:

SQL> update v_dept set dname='售货员' WHERE DEPTNO=10;

已更新 1 行。

SQL> commit;

提交完成。

会话2:

SQL> ALTER TABLE V_DEPT ADD AAA VARCHAR2(20);

表已更改。
例2:加行锁

会话1:

SQL> update v_dept set dname='研究员' where deptno=20;

已更新 1 行。

会话2:

SQL> update v_dept set dname='操作员' where deptno=40;

已更新 1 行。--立即执行

SQL> delete v_dept where deptno=20;  --一直等待,直到会话1提交后才执行完成

例3:读脏数据

错误操作:

会话1:

SQL> DELETE V_DEPT;

已删除4行。

会话2:

SQL> SELECT * FROM V_DEPT;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

正确操作:

会话1:

SQL> DELETE V_DEPT;

已删除4行。

SQL> commit;

提交完成。

会话2:

SQL> SELECT * FROM V_DEPT;

未选定行

4、提交事务

     使用commit语句可以提交事务。当执行commit语句之后,会确认事务变化,结束事务、删除保存点、释放锁。当使用commit语句结束事务之后,其他会话将可以查看到事务变化后的新数据。

当出现以下情况时会自动提交事务:

①当执行DDL语句时会自动提交事务。例如:CREATE TABLE、ALTER TABLE、DROP TABLE等语句。

②当执行DCL语句(GRANT、REVOKE)时。

③当退出SQL*PLUS时。

5、回退事务

     保存点(savepoint):保存点是事务中的一点,它用于取消部分事务。当结束事务时,会自动删除该事务所定义的所有保存点。在执行rollback命令时,通过指定保存点可以取消部分事务。

①设置保存点

   |-savepoint   a;

   |-exec dbms_transaction.savepoint('a');

②取消部分事务

   |-rollback to a;

   |-exec  dbms_transaction.rollback_savepoint('a');

③取消全部事务

   |-rollback;

   |-exec  dbms_transaction.rollback;

   注:当使用rollback取消全部事务时,会取消所有事务变化,结束事务,删除所有保存点并释放锁。

   当出现系统灾难或应用程序地址例外时,会自动回退其事务变化。

6、只读事务

①设置只读事务

  • SET TRANSACTION READ ONLY
  • EXEC dbms_transaction.read_only

注:当设置只读事务时,该语句必须是事务开始的第一条语句。

②只读事务是指只允许执行查询操作,而不允许执行任何DML操作的事务。

例1:在只读事务中执行查询、更新、插入、删除操作

SQL> set transaction read only  --设置只读事务
  2  /

事务处理集。

SQL> select * from v_dept where deptno=10;                     --查询操作

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约

SQL> update v_dept set dname='上海' where deptno=10;   --更新操作
update v_dept set dname='上海' where deptno=10
       *
第 1 行出现错误:
ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作


SQL> insert into v_dept values(50,'北京','中国');                   --插入操作
insert into v_dept values(50,'北京','中国')
            *
第 1 行出现错误:
ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作


SQL> delete v_dept where deptno=20;                              --删除操作
delete v_dept where deptno=20
       *
第 1 行出现错误:
ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作

SQL> select * from v_dept for update;                               --SELECT...FOR  UPDATE
select * from v_dept for update
              *
第 1 行出现错误:
ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作

 ③当使用只读事务时,可以确保用户取得特定时间点的数据。在设置了只读事务后,尽管其它会话可能会提交新事务,但只读事务将不会取得新的数据变化,从而确保取得特定时间点的数据信息。

例3:

会话1:

SQL> exec dbms_transaction.read_only;                               --设置只读事务,也就是指定了时间点,该事务不会取到其他会话在该操作之后提交的新事务

PL/SQL 过程已成功完成。

SQL> select * from v_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿

会话2:

SQL> insert into v_dept values(50,'项目部','杭州');                 --其他会话

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from v_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿
        50 项目部         杭州

会话1:

 SQL> exec dbms_transaction.read_only;

PL/SQL 过程已成功完成。

SQL> select * from v_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿

SQL> select * from v_dept;                                                --未取到其他会话提交的新事务所带来的数据变化

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿

 

 7、顺序事务

声明顺序事务语法:

set transaction isolation level  serializable;

作用:顺序事务可以确保用户取得特定时间点的数据,并且允许执行DML操作。

例1:

会话1:

SQL> set transaction isolation level  serializable;                         --声明顺序事务

事务处理集。

SQL> select * from v_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿
        50 项目部         杭州

会话2:

SQL> delete v_dept where deptno=50;

已删除 1 行。

SQL> commit;

提交完成。

SQL> select * from v_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿

会话1:

SQL> select * from v_dept;                                                        --在会话2提交新事务后执行的查询操作

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     纽约
        20 RESEARCH       达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿
        50 项目部         杭州

SQL> delete v_dept where deptno=10;                                    --执行DELETE语句

已删除 1 行。

SQL> update v_dept set dname='研发部' where deptno=20;    --执行UPDATE语句

已更新 1 行。

SQL> insert into v_dept values (60,'服务部','苏州');                     --执行INSERT语句              

已创建 1 行。

SQL> select * from v_dept;                                                        --经过以上操作后的结果

    DEPTNO DNAME          LOC
---------- -------------- -------------
        20 研发部         达拉斯
        30 SALES          芝加哥
        40 OPERATIONS     波士顿
        50 项目部         杭州
        60 服务部         苏州 

8、在PL/SQL中使用事务控制语句 

当编写PL/SQL程序时,不仅可以直接嵌入SELECT...INTO和DML语句,也可以直接嵌入事务控制语句。

例1:在PL/SQL块中使用COMMIT和ROLLBACK语句

begin
    update v_dept set dname='bbb' where deptno=20;
    commit;
exception
    when others then
    rollback;
end;
例2:在PL/SQL块中使用ROLLBACK和SQVEPOINT语句

begin
    update v_dept set dname='ccc' where deptno=30;
    savepoint c;
    update v_dept set dname='ddd' where deptno=40;
    rollback to c;
    commit;
exception
    when others then
    rollback;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值