2020-08-24oracle学习

2020-08-24

1、string用varchar2,date 用Date,数字用number(总长度,小数位数)
2、去重:select distinct name from table;
3、用||连接字符串
4、别名不用加单引号

2020-08-25

  • 条件查询:where
  • is null,is not null空和非空
  • nvl(xxx,0),xxx不是空值就是xxx,空就是0
  • decode(a,x,y,z,b,c):如果a是x,则y,如果a是z,则b,都不是,则c
  • 外连接:非全量表后面加个(+),eg: xxx.name(+) ,在做连接时,另外一张表能查询到所有数据
  • join相当于 ',' on相当于 、where
  • A left join B on A.a=B.b 这时,A是全量表,都会查出来
  • 不建议用count(*),影响性能,用count(id)一样
  • group by 分组 后面有的,前面才能select出来:select a,b,c group by a, b, c order by a.
  • exists 子查询若为0 则假,不为0,则真,用exists取代in(in效率低)
  • union all 不去重,unio 去重。合并是两个句子,列名要一致
  • update一条数据,提交之前,这条数据是被锁住的。commit之后,才能继续对这条数据执行别的。
  • select .....for update(是带着事务的查询,别人查不了了)只有这条句子 提交或回滚,才行。
  • 主键约束:constraint xxxxx primary key(xxx)
    • 建数据唯一性约束:constraint xxxxx unique(name)
    • 检查约束:constraint xxxxx check (gender in (1,2))
    • 外键约束:constraint xxxxx foreifn key(该表的id) references 另一张表的表名(另一张表的主键) [ on delete casade] ---级联删除
  • rownum 是行号,在oracle 中做分页,不支持 大于号 >
  • create or replace view xxx (sql句子)创建视图,就可以直接 select * from xxx(视图名)不支持有重复的列名
  • 不建议修改update视图,创建只读的视图: xxxxxx with read only

2020-08-26

  • 序列sequence的作用时 实现一个自动增长的列。
    • 步骤:设置一个主键
    • create sequence xxxxx;(但是没有关联表)
    • select xxx.nextval(currval) from dual(伪表);
    • insert into table(id,xx,xx,xx) values (xxxxx.nextval,aaa,aaa);--实现自增!
  • 索引:加速数据存储
    • 创建索引:
      • 单例索引:单个列。比如经常要查名字:create index name_index on table(name);索引是自动使用的。
      • 复合索引:多个列。create index xxzz_index on table(xx,zz);复合索引查询是有顺序的,得按照xx,zz的顺序查询,不能zz,xx。除非再建一个复合索引。
  • PL/SQL(procedure language/sql过程语言,过程化扩展)
    • 语法:
declare
  (常量和变量的定义)
  pname varchar2(15);--pname 是变量名,一定要有分号;
  pasl number(9,2);
  age number(3) :=  20;  --也可以直接赋值
  emprec emp.ename%type --引用赋值,把emp表中的ename的类型赋给emprec
  prec  myemp%rowtype;   --记录型变量,对应java中对象类型的变量
begin
  select *  into prec from myemp t where t.empo = 0999;
  dbms_output.put_line(prec.ename || '   ' ||prec.sal);  --记录型变量可以直接点出来属性值
  select t.ename into emprec  from emp t where t.empno = 7777; --引用赋值,into的用法
  panme :=  'zangsna'     --   :=是赋值
  dbms_output.put_line('hello world'); -- 输出打印函数
exception

end;

  • if语句
declare
  pno number(4) := #  -- 可以手动赋值
begin
  if pno < 5 then
    dbms_output.put _line('xxxxx');
  elsif pno  > 5 then
    dbms_output.put _line('xxx1221xx');
  else dbms_output.put _line('xxx11xx');
  end if;
end;
  • LOOP循环语句
declare
  total number(4) := 0;
begin
  while total <= 100 loop
    total := total +1;
   end loop;
end;
declare -- 这种最常用的循环方式
  total number(4) := 0;
begin
  loop
      exit when total = 100;
      total := total +1;
   end loop;
end;
declare --适合连续的数值遍历
  total number(4) := 0;
begin
   for total in 1..100  loop  --从1到100
  dbms_output.put_line(total);
   end loop;
end;
  • 游标 cursor:类似集合,存储 查询返回的多条数据
    • 步骤:
      • 打开游标: open c1;
      • 取一行:fetch c1 into pjob (pjob 要与emp表中job类型一致: pjob emp.empjob%type;
      • 关闭 : close c1
      • 结束: ecit when c1%notfound
declare
  prec emp%rowtype; -- 记录型变量
  cursor c1 is select * from emp; -- 定义游标
begin
  open c1;
    loop
        fetch c1 into prec; --从游标取值,之后,游标会自动下移一个
        exit when c1%notfound;
       dbms_output.put_line(prec.empno || '    ' ||prec.ename);
    end loop;
  close c1; --关闭游标
end;
  • 有update记得要commit
--带有参数的游标
declare 
cursor c1(dno myemp.deptno%type) is select * from myemp t where t.deptno = dno;
prec myemp%rowtype;
begin
  open c1(10); -- 打开游标,10是传参
  loop
    fetch c1 into prec;
    exit when c1%notfound;
    update myemp t set t.sal = t.asl + 1000 wheret.empno = prec.empno;
 end loop;
close c1;
commit; --因为只update一条,所以commit可以放在后面
end; 
  • 例外(处理异常)
decalre 
  pnum number(4) := 5;
  cursor c1 id select *from emp t where t.deptno = 50;
  no_data exception;  --自定义异常
begin
  open c1;
  loop
      fetch c1 into prec;
      if c1%notfound then
            raise no_data; --抛出异常,用raise!
      end if;
  end loop

  pnum := pnum/0;  -- 发生异常
exception
  when no_data then
      dbms_output.put_line('自定义的异常抛出');
  when zero_divide then
    dbms_output.put_line('被0除');
  when ..... then .....
    ............
end;
  • 存储过程:一组完成特定功能的sql句子(高性能)
create or replace procedure helloworld
as
begin
  dbms_output.put_line('xxxxx');
end;
  • 调用存储过程
begin
  helloworld;
end;  
declare --带有输入,输出参数的存储过程
  create or replace procedure addsal(pno in myemp.empno%type,ysal out number) as
--定义变量
  prec myemp%rowtype;
  psal emp.sal%type;
  
begin
  select *  into prec from myemp t where t.empno = pno;
  update myemp t set t.sal  = t.sal + 100 where t.empno = pno;
end;--最后在调用存储过程时,输入pno,就可以了。一般在调用时进行commit,不在存储过程内部进行commit;
  • 通过pl/sql程序调用存储过程
decalre  
 ysal number;
begin
   countysal(222,ysal); --(输入,输出)
   dbms_output.put_line(ysal);
end;
  • 存储函数 ,不太用,建议使用存储过程
create or replace function xxxx(输入参数) return 数据类型 is
begin
  return (变量名);
end xxxx;
  • 触发器:可以绑定在 增删改 上面,也就是 触发器 监听这这三个动作
create or replace trigger insertpt
before insert on person  --person是表名
begin   
  dbms_output.put_line('ssssssssss');
end insertpt;
create or replace trigger insertpt  --有条件的触发器
before insert on person  --person是表名
declare 
  cruday varchar2(10);--定义字符串 要给长度!
begin   
  select  to_char(sysdate,'day')  into cruday  from dual;
  if cruday = '星期三' then
      raise_application_erro(-20001,'星期三不插入数据');
  end if;
end insertpt;
  • :new和:old用法 :new是之后, :old是之前
create or replace trigger xxx
  before update of sal on myemp -- sal是列名
  for each row
begin
  if :new.sal <= :old.sal then
      raise_application_error(-20002,'涨工资后不能比之前低');
  end if;
end xxx;

你可能感兴趣的:(2020-08-24oracle学习)