1 将默认的serveroutput打开 set serveroutput on;
  --  注释一行
  /*  ... */  注释多行
2 输出一条HelloWorld语句:
 begin 
   dbms_output.put_line('HelloWorld!');
 end;
 /
  即可看到在屏幕上输出了HelloWorld!(boolean类型不能在屏幕上打印)
3 declare(变量声明)
  规则:
 1 变量名不能使用保留字,如from、select等(oracle保留字挺多)
 2 第一个字符必须是字母(一般约定以 v_ 开头)
 3 最多包含30个字符
 4 不要与数据库的表或者列同名
 5 一行只能声明一个变量
  类型:
 binary_integer: 整数,主要用来计数而不是用来表示字段类型
 number : 数字类型
 char : 定长字符串
 varchar2 : 变长字符串
 date : 日期
 long : 长字符串,最长2GB
 boolean : 布尔类型,可为true,false,null值,默认null,所以应该初始化
  eg: 
 declare
  v_name varchar2(20);
 begin
  v_name := 'myname'; //  := 是赋值语句,与pascal语言相同
  dbms_output.put_line(v_name);
 end;
 /
 即可看到在屏幕上输出了myname
 
  使用%type属性(可以将程序绑定在某张表的某个字段的类型):
    eg: v_empno emp.empno%type;(v_empno的类型和emp表的empno字段的类型相同,这样当表的 
 类型改变时,可以不必要变得程序了)
  使用%rowtype属性(可以将程序绑定在某张表的某一记录)
 
 复合类型:
  Table变量类型(数组)
 eg:
    declare
      type type_table_emp_empno(类型名) is table(是一表)  of emp.empno% type index by binary_integer(下标类型);//声明为Table类型
  v_empnos type_table_emp_empno; //用上面声明的类型声明变量
    begin
     v_empnos(0) := 2322;
  v_empnos(1) := 2344;
  v_empnos(-1) := 2388;//允许下标为负
  dbms_output.put_line(v_empnos(-1));
    end;
    /
 
 
4 exception(too_many_rows\no_data_found等)
 v_num number := 0;
  begin
 v_num := 2/v_num;
 dbms_output.put_line(v_num);
  exception
  when others then
 dbms_output.put_line('error!');
  end;
  /
 会看到屏幕输出error!即捕获到异常
 
5 sql语句的运用
  select语句:
  eg:
 declare
  v_ename emp.ename%type;
  v_sal emp.sal%type;
 begin
  select ename,sal inot v_ename,v_sal from emp where empno = 10;(必须有   且只有一条记录)
  dbms_output.put_line(v_ename || ' ' || v_sal);
 end;
 /
 
 declare
  v_emp emp%rowtype;
 begin
  select * into v_emp from emp where empno = 10;
  dbms_output.put_line(v_emp.ename);
 end;
 /
  insert语句(insert,update,delete语句与sql差不多,看下面例子):
 declare
  v_deptno dept.deptno%type := 50;
  v_dname dept.dname%type := 'aaaa';
  v_loc dept.loc%type := 'sh';
 begin
  insert into dept values (v_deptno, v_name, v_loc);
  commit;
 end;
 /
  DDL语句:
    eg:
 begin
   execute immediate 'create table T(nnn varchar2(20) default ''aaa'')';
 end ;
 /
  控制语句:
    eg(like if):
 declare
  v_sal emp.sal%type;
 begin
  select sal into v_sal from emp where empno = 10;
   if(v_sal < 1200) then
   dbms_output.put_line('low');
   elsif(v_sal < 2000) then
   dbms_output.put_line('middle');
   else
   dbms_output.put_line('high');
   end if;
 end;
 /
    eg(like do...while):
 declare
  i binary_integer := 1;
 begin
   loop
   dbms_output.put_line(i);
   i := i + 1;
    exit when (i >= 11);
   end loop;
 end;
 /
    eg(like while):
 declare
  i binary_integer := 1;
 begin
   while j < 11 loop
   dbms_output.put_line(i);
   i := i + 1;
   end loop;
 end;
 /
    eg(for):
 begin
   for k in 1..10 loop
   dbms_output.put_line(k);
   end loop;
  for k in reverse 1..10 loop
   dbms_output.put_line(k);
  end loop;
 end;
 /
6 cursor(isopen,notfound,found,rowcount四个属性)
     eg:
 declare
  cursor c is
   select * from emp;(让游标指向这张表的第一条记录,尚未打开,没加载        内存)
  v_emp c%rowtype;(v_emp存储游标中的一条记录)
 begin
  open c;
     fetch c into v_emp;(拿到一条记录放入v_emp中,游标自动下移一格)
     exit when (c%notfound);
    dbms_output.put_line(v_emp.ename);//打印ename的所有的属性值,顺序不能颠倒
  close c;(用完游标后,释放内存)
 end;
 /
     eg:
 declare
  cursor c is
   select * from emp;
  v_emp c%rowtype;
 begin
  open c;
     fetch c into v_emp;
  while (c%found) loop;
    dbms_output.put_line(v_emp.ename);
   fetch c into v_emp;
  end loop;
  close c;
 end;
 /
     eg:
 declare
  cursor c is
   select * from emp;
  v_emp c%rowtype;
 begin
  for v_emp in c loop;(自动打开、关闭、fetch,所以不易出错,常用)
    dbms_output.put_line(v_emp.ename);
  end loop;
 end;
 /

     eg:
 declare
  cursor c(v_deptno emp.deptno%type, v_jop emp.job%type)(函数游标)
  is
   select ename,sal from emp where deptno = v_deptno and job = v_job;
  --v_temp c%rowtype;//不需要声明
 begin
  for v_temp in c(30,'clerk') loop
   dbms_output.put_line(v_temp.ename);
  end loop;
 end;
 /
      eg(可更新的游标):
 delcare
  crosor c
  is
   select * from emp2 for update;
  --v_temp c%rowtype;
 begin
  for v_temp in c loop;
   if(v_temp.sal < 2000) then
    update emp2 set sal = sal * 2 where current of c;//更新当前     游标指向的记录
   elsif (v_tmp.sal = 5000) then
    delete from emp2 where current of c;
   end if;
  end loop;
  commit;
 end;
 /
7 存储过程(带名字的pl_sql语言)
  create or replace procedure p
  is
  corsor c is
   select * from emp2 for update;
 begin
  for v_temp in c loop;
   if(v_temp.sal < 2000) then
    update emp2 set sal = sal * 2 where current of c;//更新当前游标指向的记录
   elsif (v_tmp.sal = 5000) then
    delete from emp2 where current of c;
   end if;
  end loop;
  commit;
 end;
  执行时用 exec p; 或
      begin
      p;
      end;
带参数的存储过程:
     eg:
  create or replace procedure p
   (v_a in number, v_b number, v_ret out number,v_temp in out number)
 is
 begin
  if (v_a > v_b) then
   v_ret := v_a;
  else
   v_ret := v_b;
  end if;
   v_temp := v_temp +1;
 end;
 /
   使用:
 declare
  v_a number := 3;
  v_b number := 4;
  v_ret number;
  v_temp number := 5;
 begin
  p(v_a, v_b, v_ret, v_a);  
  dbms_output.put_line(v_ret);
  dbms_output.put_line(v_temp);
 end;
 /
 如果出现警告,编译错误时,可用 show error来查看错误源(即使有语法错误,过程仍然会被创建)

8 函数:
 create or replace function sal_tax //创建一个函数,一个数值参数和一个数值返回值
   (v_sal number)
 return number
 is
 begin
  if(v_sal < 2000) then
   return 0.10;
  elsif(v_sal < 2750) then
   return 0.15;
  else
   return 0.20;
  end if;
 end;
 /
  使用: select lower(ename), sal_tax(sal) from emp;//定义的函数和‘系统’函数调用方法相同
9 触发器:
  eg:
 //创建表
 cretae table emp2_log
 (
 uname varchar2(20),
 action varchar2(10),
 actime date
 );
 //触发器
  create or replace trigger trig
     after insert or delete or update on emp2 (for each row(每有一个操作就触发一次))
 begin
  if inserting then
   insert into emp2_log values(user,'insert',sysdate);
  eslif updating then
   insert into emp2_log values(user,'update',sysdate);
  esl if deleting then
   insert into emp2_log values(user,'delete',sysdate);
  end if;
 end;
 /
  此时查看emp2_log表时就可看到对emp2执行操作的记录

 触发器的副作用:
 当dept表中的deptno被其他表参考时,如果要更新deptno的值,可强制用触发器实现:
 create or replace trigger trig
  after update on dept
  for each row
 begin
  update emp set deptno = :NEW.deptno where deptno = :OLD.deptno;
 end;
 /
 此时更新deptno不会报违反完整性约束的错了:
 update dept set deptno = 77 where deptno = 10; 可看到已更新一行的提示