-- 感觉有用点个赞呗^v^

select * from emp;

drop view persin_vw;--删除视图

create table emp as select * from scott.emp;  --复制scott用户下的emp表

--视图:视图就是封装了一条复杂的查询语句
create view emp_vw as 
select * from emp e where e.deptno = 20;    --创建一个视图,视图显示的是编号为20的全部员工

select * from emp_vw e;      --创建好的视图,可以进行查询

create or replace view emp_vw as 
select * from emp e where e.deptno = 10;    --创建一个视图,如果存在相同名称的则会覆盖,如果没有,创建

create or replace view emp_vm as
select * from emp e where e.deptno = 20 with read only;   --创建一个只读视图

--索引:可以加快查询速度,但会降低增删改速度
--单列索引,建立在一列上的索引
create index eid on emp(ename);  --eid:索引名,   emp:表名,   ename:列名
--复合索引:建立在多个列上
create index pid_pname on person(pid,pname);
--索引的使用规则
             /*
             在大表上建立索引才有意义
             在where子句后面或者是连接条件上的字段上建立索引
             表中数据频繁增删改,不建议进行添加索引
             */

--plsql基本语法
--为职工涨工资,每人涨 10%的工资。
update emp set sal=sal*1.1;      
--按职工的职称长工资,总裁涨 1000元,经理涨800 元,其他人员涨 400 元。无法用一条sql进行操作,借助plsql
                /*语法结构
                  declare
                    说明部分 (变量说明,游标申明,例外说明 〕
                  begin
                    语句序列 (DML 语句〕…
                  exception
                    例外处理语句
                  End;
                */
--定义变量: 变量名 变量类型
varl number(2);
psal char(15);

--定义常量
married constant boolean := true;        -- :=  表示赋值
--引用型变量
myname emp.ename%type;      --引用emp表中ename的类型
--使用into进行赋值
declare

  emp_name emp.ename%type;          --定义一个变量emp_name 类型和emp表中的ename数据类型是一样的
begin
  select e.ename into emp_name from emp e where e.empno = 7369;   --查询emp表中empno=7369的ename,将值赋值给
  dbms_output.put_line(emp_name);      --打印显示变量中的值
end;

--记录型变量
emp_mytype emp%rowtype;         --可以记录emp表的一行类型
--记录变量分量的引用
emp_rec.ename:='ADAMS';
--例子
declare
  p emp%rowtype;
begin
  select * into p from emp e where e.empno = 7369;      
  dbms_output.put_line(p.ename || '的工资为' || p.sal);     -- || 表示连接符号
end;

--if分支
--语法1:如果从控制台输入 1 则输出我是 1
declare
  pnum number := #
begin
  if pnum = 1 then
    dbms_output.put_line('我是' || pnum);
  end if;
end;
--语法2:如果从控制台输入 1 则输出我是 1否则输出我不是 1
declare
  pnum number := #
begin
  if pnum = 1 then
    dbms_output.put_line('我是' || pnum);
  else
    dbms_output.put_line('我不是1');
  end if;
end;
--语法3:判断人的不同年龄段 18岁以下是未成年人,18岁以上 40以下是成年人,40以上是老年人
declare
  pnum number := #
begin
  if pnum < 18 then
    dbms_output.put_line('未成年');
  elsif pnum >= 18 and pnum < 40 then
    dbms_output.put_line('成年人');
  elsif pnum >= 40 then
    dbms_output.put_line('老年人');
  end if;
end;
--LOOP循环分支
--使用语法 1 输出 1 到10 的数字
declare
  step number :=1;    --变量,赋予初始值1
begin
  while step <=10 loop
    dbms_output.put_line(step);
    step := step+1;   --没循环一次,+1
  end loop;
end;
--使用语法 2 输出 1 到10 的数字
declare
  step number := 1;
begin
  loop
    exit when step > 10;
    dbms_output.put_line(step);
    step := step+1;
  end loop;
end;
--使用语法 3 输出 1 到10 的数字
declare
  step number := 1;
begin
  for step in 1..10
    loop
      dbms_output.put_line(step);
    end loop;
end;

--游标cursor
--语法:CURSOR 游标名 [ (参数名 数据类型,参数名 数据类型,...)] IS SELECT 语句;
cursor c1 is select ename from emp;
--游标的使用步骤
       /*
          1.打开游标: open c1  打开游标执行查询
          2.取一行游标的值    fetch c1 into pjob;    取一行到变量中
          3.关闭游标: close c1; 关闭游标,释放资源
          4.游标的结束方式exit when c1%notfound
       */
--使用游标方式输出 emp 表中的员工编号和姓名
declare
   cursor pc is select * from emp;    --创建一个游标
   pemp emp%rowtype;                  --定义一个记录型变量
begin
   open pc;                           --打开游标
        loop                          --循环遍历
          fetch pc into pemp;         --提取一行数据,存储到变量中
          exit when pc%notfound;      --退出条件:没有下一行之时
          dbms_output.put_line(pemp.empno || '---' || pemp.ename);  --打印
        end loop;                     --循环结束
   close pc;                          --关闭资源
end;

--按员工的工种涨工资,总裁 1000 元,经理涨 800 元其,他人员涨 400 元。
declare
  cursor p is select * from emp;
  addsal emp.sal%type;
  pemp emp%rowtype;
begin
  open p;
       loop
         fetch p into pemp;
         exit when p%notfound;
            if 
               pemp.job = 'PRESIDENT' then addsal := 1000;
               elsif pemp.job = 'MANAGER' then addsal := 800;
               else addsal := 400;
            end if; 
        end loop;
        update emp e set e.sal = e.sal + addsal where e.empno = pemp.empno;
        commit;
  close p;            
end;
--写一段PL/SQL 程序,为10号部门员工涨工资1000元。
declare
  cursor p is select * from emp;
  addsal emp.sal%type;
  pemp emp%rowtype;
begin
  open p;
    loop
      fetch p into pemp;
      exit when p%notfound;
        if 
          pemp.deptno = 10 then addsal := 1000;
          else addsal := 0;
        end if;
       
    end loop;
     update emp e set e.sal = e.sal + addsal where e.deptno = pemp.deptno;
        commit;
  close p;
end;

--存储过程
/*
    存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的 SQL 语句集,
    经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
    存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
*/
/*
    创建存储过程语法:
    
    create [or replace] PROCEDURE  过程名[( 参数名 in/out  数据类型)] AS
    begin
      PLSQL 子程序体;
    End;
    --或者
    create [or replace] PROCEDURE  过程名[( 参数名 in/out  数据类型)] is
    begin
      PLSQL 子程序体;
    End;
*/
--创建一个helloword存储过程
create or replace procedure helloworld as
begin
  dbms_output.put_line('helloworld');
end;
--在plsql中调用存储过程
begin
  helloworld;
end;
--删除存储过程
drop procedure helloword;

--给指定的员工涨 指定 工资,并打印出涨前和涨后的工资
create or replace procedure addsal(eno in number, addsal in number) is
  pemp emp%rowtype;
begin
  select * into pemp from emp e where e.empno = eno;
  update emp set sal = nvl(sal,0) + addsal where empno = eno;
  dbms_output.put_line('涨工资前:' || pemp.sal || '---' || '涨工资后:' || (pemp.sal+addsal));
end;

--调用存储过程
begin
  addsal(eno => 7369,addsal => 1000);
  commit;
end;

--存储函数
/*
    create or replace function  函数名(Name in type, Name in type, ...) return  数据类型 
    is
      结果变量  数据类型;
    begin
      return( 结果变量);
    end;
*/
--使用存储函数来查询指定员工的年薪
create or replace function findsal(eno in emp.empno%type) return number is
  pemp emp%rowtype;
begin
  select * into pemp from emp e where e.empno = eno;
  return pemp.sal * 12 + nvl(pemp.comm,0);
end;
--调用存储函数
declare
  varl number;
begin
  varl := findsal(7369);
  dbms_output.put_line(varl);
end;
/*
  存储函数和存储过程的区别
  图1-1*/
--触发器
/*
  数据库触发器是一个与表相关联的、存储的 PL/SQL 程序。
  每当一个特定的数据操作语句(Insert,update,delete)在指定的表上发出时,
  Oracle 自动地执行触发器中定义的语句序列。
*/
--触发器可用于:
/*
  1. 数据确认
  2. 实施复杂的安全性检查
  3. 做审计,跟踪表上所做的数据操作等
  4. 数据的备份和同步
*/
--类型
/*
- 语句级触发器 :在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行 。
- 行级触发器:触发语句作用的每一条记录都被触发。在行级触 发器中使用 old 和 new伪记录变量, 识别值的状态。
*/
--语法
/*
CREATE [or replace] TRIGGER 触发器名
  {BEFORE | AFTER}
  {DELETE | INSERT | UPDATE [OF  列名]}
  ON 表名
  [FOR EACH ROW [WHEN( 条件) ] ]
begin
  PLSQL块
End;
*/
--插入员工后打印一句话“一个新员工插入成功”
create or replace trigger testtrigger
  after
  insert 
  on person
declare
begin
  dbms_output.put_line('一个员工插入成功');
end;
--在person表中插入数据
insert into person values(12,'songwenhui');
select * from person;

--在行级触发器中触发语句与伪记录变量的值
--图1-2



plsql索引类型都有哪些_plsql索引类型都有哪些

--判断员工涨工资之后的工资的值一定要大于涨工资之前的工资
create or replace trigger addsal
  before 
  update of sal on emp
  for each row
begin
  if :old.sal >= :new.sal 
    then raise_application_error(-20002, '涨前的工资不能大于涨后的工资');
  end if;
end;
--调用
update emp t set t.sal = t.sal - 1;  --报错