------------------------2013-5-16------------------------
1.sql概念,主要特点,使用sql工具,如何访问及本书实例两个数据表
2.单个表查询
3.多个表查询
4.复杂的嵌套查询
5.查询函数
6.sql录入数据
7.sql删除数据
8.sql更新数据

sql已经被ANSI(美国国家标准化组织)确定为数据库系统的工业标准。

DQL:查询
DDL:建立,删除和修改数据对象
DML:完成数据操作的命令,包括查询。
DCL:控制对数据库的访问,服务器的关闭,启动等。

--\Class1\扩展\Oracle9.0入门_基本SQL.pdf
--\Class6\扩展\Oracle9.0入门_04_SQL.pdf  相同

set serveroutput on  打开输出。

case .. when .. then .. else .. end case条件判断
declare
lv_Age_num number default 99;
lv_Name_char varchar2(8) := 'AZhu';
lc_Sex_char constant char(8) := 'Male';
begin
  dbms_output.put_line (lv_Age_num);
  dbms_output.put_line ('===========');
  lv_Age_num := 15;
  lv_Name_char := 'ANiu';
  --lc_Sex_char := 'Female';
  case lv_Age_num
  when 12 then
    dbms_output.put_line (lv_Name_char || '大于10!');
  when 10 then
    dbms_output.put_line (lv_Name_char || '等于10!');
  else
    dbms_output.put_line (lv_Name_char || '小于10!');
  end case;
end;

declare
lv_Age_num number default 99;
lv_Name_char varchar2(8) := 'AZhu';
lc_Sex_char constant char(8) := 'Male';
begin
  dbms_output.put_line (lv_Age_num);
  dbms_output.put_line ('===========');
  lv_Age_num := 9;
  lv_Name_char := 'ANiu';
  --lc_Sex_char := 'Female';
  case
  when lv_Age_num > 10 then
    dbms_output.put_line (lv_Name_char || '大于10!');
  when lv_Age_num = 10 then
    dbms_output.put_line (lv_Name_char || '等于10!');
  else
    dbms_output.put_line (lv_Name_char || '小于10!');
  end case;
end;

sql%found判断,返回影响的行数:sql%rowcount
begin
  update class6 set cname = 'PP' where cid = 3;
  if sql%found then
    dbms_output.put_line(sql%rowcount);
  else
    dbms_output.put_line('OhNo!');
  end if;
end;

for循环
for lv_ID_num in 2 .. 4  --退出条件--
  loop

end loop;

declare
lv_ID_num2 int := 12;
begin
  for lv_ID_num in 8 .. 10   --for变量,--退出条件--
  loop
    insert into Class6 values (lv_ID_num2, 'ANiu' || to_char(lv_ID_num2));
    lv_ID_num2 := lv_ID_num2 + 1;   --如果写成lv_ID_num := lv_ID_num + 1; 会报错。
  end loop;
  commit;
end;

while lv_ID_num < 8  --退出条件--
  loop

end loop;

loop
    exit when lv_ID_num = 21;  --退出条件--

end loop;

declare
lv_Title_char varchar2(80);
lv_Price_num number(19,4);
begin
  select  cname,cid
  into lv_Title_char, lv_Price_num    --可以赋予给多个变量--
  from class6
  where cid='2';    --'2'可以写成变量赋值的方式--
  dbms_output.put_line (lv_Title_char);
  dbms_output.put_line (lv_Price_num);
end;

declare
-- 定义记录(Record)
type type_Title is record    --创建类型--
(
lv_Title_char varchar2(80),
lv_Price_num number(19,4)
);
lv_title type_Title;
lv_TitleID_char varchar2(80);
begin
  lv_TitleID_char := 3;
  select  cname,cid
  into lv_title    --赋予给记录类型变量--
  from class6
  where cid= lv_TitleID_char;
  dbms_output.put_line (lv_title.lv_Title_char);
  dbms_output.put_line (lv_title.lv_Price_num);
end;

###
create type add_type as object(
  street varchar2(10),  --街道名
  city varchar2(10),    --城市名
  state char(2),        --州代码
  zip   number          --邮编
);
### -->ORACLE埃里森4.txt

创建视图
create view viewTitles
as
select cid, cname from class6

declare
-- 定义记录(Record)
lv_title viewTitles%rowtype;            --视图类型方式--, --表类型: lv_title class6%rowtype;
lv_TitleID_char varchar2(80);
begin
  lv_TitleID_char := 3;
  select cid, cname
  into lv_title    --赋予给记录类型变量--
  from class6
  where cid= lv_TitleID_char;
  dbms_output.put_line (lv_title.cid);
  dbms_output.put_line (lv_title.cname);
end;

%type理解,只要是类型都可以引用.
lv_Name_char varchar2(8) := 'AZhu';
lv_Sex_char lv_Name_char%type := 'Male';  --引用变量--

---------------------游标完整例子---------------------
declare
-- 声明游标(关联Select语句)
cursor cur_Titles is select cname,cid from class6;
lv_Title_char class6.cname%type;
lv_Price_num class6.cid%type;
begin
  -- 打开游标
  open cur_Titles;
  -- 提取游标
  fetch cur_Titles into lv_Title_char, lv_Price_num;
  loop
    exit when not cur_Titles%Found;  --退出循环条件
    dbms_output.put_line ('游标demo========');
    dbms_output.put_line (lv_Title_char);
    dbms_output.put_line (lv_Price_num);
    fetch cur_Titles into lv_Title_char, lv_Price_num;  --循环读取
  end loop;
  -- 关闭游标
  close cur_Titles;
end;

--游标类型--
declare
-- 声明游标(关联Select语句)
cursor cur_Titles is select cname,cid from class6;
lv_title_rec cur_Titles%rowtype;             --引用游标类型--
begin
  -- 打开游标
  open cur_Titles;
  -- 提取游标
  fetch cur_Titles into lv_title_rec;
  loop
    exit when not cur_Titles%Found;  --退出循环条件
    dbms_output.put_line ('游标demo========');
    dbms_output.put_line (lv_title_rec.cid);
    dbms_output.put_line (lv_title_rec.cname);
    fetch cur_Titles into lv_title_rec;  --循环读取
  end loop;
  -- 关闭游标
  close cur_Titles;
end;

select  .. for update ..
规则是:FOR UPDATE语句将锁住查询结果中的元组,这些元组将不能被其他事务的UPDATE,DELETE和FOR UPDATE操作,直到本事务提交。

在newlifeyhj帐户下面建立scott.emp表的结构和数据用来测试:
create table class6emp as
select * from scott.emp;

select sal from class6emp where job = 'CLERK';
       SAL
----------
       800
      1100
       950
      1300

##修改,取当前游标的记录.where current of c##
create or replace procedure proGeMing2
as
cursor c is select empno, job, sal from class6emp for update;
lv_emp_rec c%rowtype;   --那么这行不要
begin
   open c;    --那么这行不要
   --for lv_emp_rec in c  --另外一种fetch方式--
   loop
           fetch c into lv_emp_rec;  --那么这行不要
           exit when not c%found;    --那么这行不要
           case lv_emp_rec.job
           when 'CLERK' then
                   update class6emp set sal = sal * 2 where current of c;  --c是游标
           when 'SALESMAN' then
                   update class6emp set sal = sal / 2 where current of c;
           when 'MANAGER' then
                   update class6emp set sal = 0 where current of c;
           else
                   update class6emp set sal = 250 where current of c;
           end case;
   end loop;
   close c;        --那么这行不要
end;

begin
proGeMing2;
end;

select sal from class6emp where job = 'CLERK';
       SAL
----------
      1600
      2200
      1900
      2600

create or replace procedure proGeMing2
as
cursor c is select empno, job, sal from class6emp for update;
begin
   for lv_emp_rec in c  --另外一种fetch方式--
   loop
           case lv_emp_rec.job
           when 'CLERK' then
                   update class6emp set sal = sal * 2 where current of c;  --c是游标
           when 'SALESMAN' then
                   update class6emp set sal = sal / 2 where current of c;
           when 'MANAGER' then
                   update class6emp set sal = 0 where current of c;
           else
                   update class6emp set sal = 250 where current of c;
           end case;
   end loop;
end;

select sal from class6emp where job = 'CLERK';
       SAL
----------
      3200
      4400
      3800
      5200

不使用游标的方式,直接查询。那么就不可以用where current of c
create or replace procedure proGeMing2
as
begin
   for lv_emp_rec in (select empno, job, sal from class6emp for update)
   loop
       case lv_emp_rec.job
       when 'CLERK' then
               update class6emp set sal = sal * 2 where empno = lv_emp_rec.empno;
       when 'SALESMAN' then
               update class6emp set sal = sal / 2 where empno = lv_emp_rec.empno;
       when 'MANAGER' then
               update class6emp set sal = 0 where empno = lv_emp_rec.empno;
       else
               update class6emp set sal = 250 where empno = lv_emp_rec.empno;
       end case;
   end loop;
end;

select sal from class6emp where job = 'CLERK';
       SAL
----------
      6400
      8800
      7600
     10400

##带参数的游标##  变量方式
declare
-- 声明参数游标
cursor cur_Titles(p_t class6.cid%type)
is
select cname,cid from class6 where cid = p_t;
lv_Title_char class6.cname%type;
lv_Price_num class6.cid%type;
begin
  -- 打开游标
  open cur_Titles('2');   --参数游标--
  loop
    -- 提取游标
    fetch cur_Titles into lv_Title_char, lv_Price_num;
    exit when not cur_Titles%Found;
    dbms_output.put_line ('========');
    dbms_output.put_line (lv_Title_char);
    dbms_output.put_line (lv_Price_num);
  end loop;
  -- 关闭游标
  close cur_Titles;
  -- 打开游标
  open cur_Titles('3');   --参数游标--
  loop
    -- 提取游标
    fetch cur_Titles into lv_Title_char, lv_Price_num;
    exit when  cur_Titles%notFound;
    dbms_output.put_line ('========');
    dbms_output.put_line (lv_Title_char);
    dbms_output.put_line (lv_Price_num);
  end loop;
  -- 关闭游标
  close cur_Titles;
end;

--记录方式存储--
declare
type ttt is record(
  lv_Title_char class6.cname%type,
  lv_Price_num class6.cid%type
);
-- 声明参数游标
cursor cur_Titles(p_t class6.cid%type)
is
select cname,cid from class6 where cid = p_t;
--lv_Title_char class6.cname%type;
--lv_Price_num class6.cid%type;
objttt ttt;
begin
  -- 打开游标
  open cur_Titles('2');   --参数游标--
  loop
    -- 提取游标
    --fetch cur_Titles into lv_Title_char, lv_Price_num;
    fetch cur_Titles into objttt;
    exit when not cur_Titles%Found;
    dbms_output.put_line ('========');
    dbms_output.put_line (objttt.lv_Title_char);
    dbms_output.put_line (objttt.lv_Price_num);
    --如果游标有多条记录,那么循环取。
  end loop;
  -- 关闭游标
  close cur_Titles;
end;

loop
    -- 提取游标
    fetch cur_Titles into objttt;

end loop;

 -- 提取游标
 fetch cur_Titles into objttt;
 loop
   
   
    fetch cur_Titles into objttt;  --需要再次提取游标,便于循环。
  end loop;

##定义引用游标##
declare
type ttt is record(
  lv_Title_char class6.cname%type,
  lv_Price_num class6.cid%type
);
-- 定义引用游标
type type_Titles_cur is ref cursor;     --这个地方是关键。
-- 声明游标
cur_Titles type_Titles_cur;
objttt ttt;
begin
  -- 打开游标
  open cur_Titles
  for
  select cname, cid from class6;       --给游标赋予值。
  loop
    -- 提取游标
    fetch cur_Titles into objttt;
    exit when not cur_Titles%Found;
    dbms_output.put_line ('========');
    dbms_output.put_line (objttt.lv_Title_char);
    dbms_output.put_line (objttt.lv_Price_num);
  end loop;
  -- 关闭游标
  close cur_Titles;
end;

##循环游标##
-- 循环游标
declare
-- 定义记录(Record)
-- 声明游标
cursor cur_Titles
is
select cid, cname from class6;
begin
  -- 自动打开游标
  -- 自动提取游标存储到一个自动定义的记录变量
  -- 在循环结束部分自动提取下一条记录
  -- 当读到游标结尾自动关闭游标
  for lv_Title_type in cur_Titles
  loop
    dbms_output.put_line ('========');
    dbms_output.put_line (lv_Title_type.cid);
    dbms_output.put_line (lv_Title_type.cname);
  end loop;
  -- 关闭游标
end;

##隐式游标##
-- 隐式游标
declare
-- 定义记录(Record)
-- 自动声明游标
begin
 -- 自动打开游标
 -- 自动提取游标存储到一个自动定义的记录变量
 -- 在循环结束部分自动提取下一条记录
 -- 当读到游标结尾自动关闭游标
 for lv_Title_type in (select cid, cname from class6)
 loop
  dbms_output.put_line ('========');
  dbms_output.put_line (lv_Title_type.cid);
  dbms_output.put_line (lv_Title_type.cname);
 end loop;
 -- 关闭游标
end;

PRAGMA EXCEPTION_INIT的用法     --自动触发,而不要手动raise 异常名; --
http://blog.csdn.net/wanggangytsoft/article/details/5408692

ora-01843: 这个错误代表无效的月份一般在日期转化的时候会提示。
ORA-00001: 违反唯一约束条件

ORA-06511 CURSOR_ALREADY_OPEN: 程序尝试打开一个已经打开的游标。一个游标在重新打开之前必须关闭。
ORA-00001 DUP_VAL_ON_INDEX: 唯一索引上有重复值

-- 自定义错误消息
-- Raise_Application_error
raise_application_error(-20001, '没有!');

ORA-01722 invalid number 无效数字
ORA-01476: divisor is equal to zero 这个错误是sql语句中存在除数为0的情况

ora-01422:输出值太多。查询返回的记录行大于1。

NO_DATA_FOUND

##游标异常##
declare
-- 声明游标
cursor cur_Titles
is
select * from class6;
begin
  -- 打开游标
  open cur_Titles;
  open cur_Titles;
  -- 关闭游标
  close cur_Titles;
exception
  when CURSOR_ALREADY_OPEN then                   --重复打开问题-- CURSOR_ALREADY_OPEN
    dbms_output.put_line('Cursor is Opened!');
    dbms_output.put_line('Cursor is Opened!');
end;

#存储过程参数 in 是参数的默认模式。# in, out, in out三种类型。

##创建存储过程##
create or replace procedure GetTitle
(
p_titleid in class6.cid%type := '2',
p_title out class6.cid%type,
p_price out class6.cname%type
)
as
begin
select cid, cname into p_title, p_price from class6 where cid = p_titleid;
end;

##调用存储过程##
declare
lv_title_char class6.cid%type;
lv_price_num class6.cname%type;
begin
GetTitle (p_title => lv_title_char, p_price => lv_price_num);    --参数名称要和过程定义的相同--,否则参数个数不匹配。
  --GetTitle (4,lv_title_char, lv_price_num);    --参数接受,个数匹配--这样也可以的!!! --
dbms_output.put_line(lv_title_char);
dbms_output.put_line(lv_price_num);
end;

create or replace procedure GetTitle
(
p_title out class6.cid%type,
p_price out class6.cname%type
)
as
begin
select cid, cname into p_title, p_price from class6 where cid = 2;
end;

declare
lv_title_char class6.cid%type;
lv_price_num class6.cname%type;
begin
GetTitle (lv_title_char, lv_price_num);    --参数接受,个数匹配--
dbms_output.put_line(lv_title_char);
dbms_output.put_line(lv_price_num);
end;

create or replace procedure GetTitleByTitleID2
(
p_TitleID in class6.cid%type,
p_Title out class6.cid%type,
p_Price out class6.cname%type         --关键点:这个地方没有逗号。--
)
as
begin
select cid, cname into p_Title, p_Price from class6 where cid = p_TitleID;
end;

exec 不要写,否则会报错。

set serveroutput on; 打开,否则无法看到输出信息,pl/sql developer 测试窗口可以运行存储过程。

set serveroutput on;
declare
lv_Title class6.cid%type;
lv_Price class6.cname%type;
begin
  GetTitleByTitleID2 ( 2, lv_Title,lv_Price);
  dbms_output.put_line('----' || lv_Title);
  dbms_output.put_line('====' || lv_Price);
end;

综合存储过程和调用与过程的对比。
declare
lv_Title class6.cid%type;
lv_Price class6.cname%type;
begin
  select cid, cname into lv_Title, lv_Price from class6 where cid = 2;
  dbms_output.put_line('----' || lv_Title);
  dbms_output.put_line('====' || lv_Price);
end;

#类型的引用可以基于表,也可以基于视图。!!!#

##函数## 与存储过程的区别,是函数是有返回值的。
--创建函数
create or replace function funGetTotalQtyByTitleID
(
p_titleid in class6.cid%type
)
return class6.cname%type        --返回类型--
as
p_totalqty class6.cname%type;
begin
select cname into p_totalqty from class6 where cid = p_titleid;
return (p_totalqty);            --返回值--与返回类型一一匹配
end;

#函数的调用#与系统函数的调用和使用是一样的
select funGetTotalQtyByTitleID('4') from dual;

-- 赋值语句
declare
p_totalqty class6.cname%type;
begin
p_totalQty := funGetTotalQtyByTitleID('5');
dbms_output.put_line(p_totalqty);
end;

转载于:https://www.cnblogs.com/simpledev/archive/2013/05/22/3092922.html

Oracle Class6-1. PL/SQL 简介(数据类型,逻辑比较,控制结构,错误处理)相关推荐

  1. 【Oracle】ORA-06510: PL/SQL: 用户定义的异常错误未得到处理

    异常除了定义,还需要有代码块去处理异常. 详见参考文章:https://www.techonthenet.com/oracle/errors/ora06510.php

  2. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  3. PL/SQL 简介及基本语法

    PLSQL 简介及基本语法 什么是PL/SQL PLSQL 是 Oracle 对 sql 语言的过程化扩展,指在 SQL 命令语言中增加了过程处理语句(如分支.循环等),使 SQL 语言具有过程处理能 ...

  4. Oracle数据库之PL/SQL程序基础设计

    一.PL/SQL块结构 前边我们已经介绍了PL/SQL块的结构,再来回顾一下: DECLARE /** 声明部分--定义常量.变量.复杂数据类型.游标.用户自定义异常*/ BEGIN /** 执行部分 ...

  5. PL/SQL复合数据类型

    --一.PL/SQL复合数据类型 --(一).PL/SQL记录 --1.定义PL/SQL记录 --(1).定义PL/SQL记录 --Grammar TYPE type_name IS RECORD(f ...

  6. Oracle实验五 PL/SQL编程

    Oracle实验五 PL/SQL编程 [实验目的] 熟悉PL/SQL的数据类型和书写规则 熟悉控制结构和游标的使用 编写和运行函数.过程和触发器 [实验内容] 编写脚本文件,调试运行脚本文件,并记录结 ...

  7. Oracle Study之--PL/SQL Developer软件错误

    Oracle Study之--PL/SQL Developer软件错误 博文在51cto和CSDN同时开通 系统环境: 操作系统: Windows  XP(64) 软件:          PL/SQ ...

  8. 【学亮IT手记】oracle远程连接工具PL/SQL Developer的安装使用教程

    [学亮IT手记]oracle远程连接工具PL/SQL Developer的安装使用教程 客户端远程连接oracle,可以使用oracle自带的连接工具sqlplus,instanceclient_12 ...

  9. Windows 7 下安装 Oracle 数据库和 PL/SQL Developer

    win7下无论是32bits还是64bits,建议只安装oracle 11g 32bits,然后直接安装pl/sql developer,不需要额外的配置,就可以通过pl/sql developer来 ...

  10. 编译错误 错误:PL/SQL: ORA-00932: 数据类型不一致: 应为 DATE, 但却获得 NUMBER 行

    文章目录 1. 现象 2. 分析 3. 解决方案 通过存储过程将临时B表中的数据同步到轨迹表中 1. 现象 PROCEDURE LABS.ASSET_LOANP 编译错误错误:PL/SQL: ORA- ...

最新文章

  1. Altium designer--变压器封装图
  2. pytorch 之 加载不同形式的预训练模型
  3. 合并多个wordpress到一个
  4. SeDuMi教程(2)_线性规划的两种求解器的对比
  5. HTML 视频和音频
  6. python 2.7.9 安装beautifulsoup4
  7. chainmaker 区块中最大交易数 block_tx_capacity设置 区块大小 区块容量
  8. nvidia-smi介绍
  9. Python验证信用卡号码是否有效
  10. python实现线性回归
  11. 结算系统功能详解-上篇
  12. Kafka高性能之页缓存(page cache)使用
  13. 通过uart串口和printf函数打印
  14. Sql语句中的DDL、DML、DCL的介绍
  15. Vue 使用 yarn 报错
  16. C语言程序设计第六章例题(数组)
  17. 中点法 matlab,中点法解常微分方程(组)
  18. 第一份功能较多的安卓项目--纪念日app
  19. 超级实习生名企实习经历经得起背调吗?是正规实习吗?
  20. 4.服务器如何防止信息泄露,怎样防止共享文件信息泄露

热门文章

  1. 屏幕录制专家,如何上传到优酷的高清视频?
  2. manjaro wechat
  3. 《阿里巴巴Java开发手册(正式版)》--安全规约
  4. 郁金香搜索引擎的方案(2017版)
  5. matlab里添加白噪声,转Matlab中添加高斯白噪声
  6. intel服务器无线网卡,刷版本号?Intel再发新版无线网卡驱动
  7. android 找不到手机,找不到 Android 开发者选项,难道我的手机系统没有?| 有轻功 #290...
  8. My console windows won't go away
  9. Python大法之告别脚本小子系列—信息资产收集类脚本编写(下)
  10. 苏宁易购:前后端分离架构的落地思考