PL/SQL----pl/sql块

PL/SQL


```sql
DECLARE
   ---声明部分

BEGIN
   ---执行部分  ---必选
   
  EXCEPTION
    ---异常处理部分
END;

/
DECLARE



```sql
BEGIN
  DBMS_OUTPUT.PUT_LINE('HELLO WORLD');
  DBMS_OUTPUT.PUT('HELLO');
END;
/

BEGIN 
  DBMS_OUTPUT.PUT('HELLO');
  DBMS_OUTPUT.NEW_LINE;
  DBMS_OUTPUT.PUT('WMJ');
  DBMS_OUTPUT.NEW_LINE;
END;
/
BEGIN
  DBMS_OUTPUT.PUT_LINE('HELLO ORACLE');
  DBMS_OUTPUT.PUT_LINE('员工SMITH的工资是800元每月');\
END;
/
BEGIN
  DBMS_OUTPUT.PUT_LINE('员工SMITH的工资是800元每月');
END;

/




```sql
DECLARE
V_NAME1  VARCHAR2(100);
V_NAME2 VARCHAR2(100);
V_NAME3 NUMBER(10);
BEGIN
V_NAME1:='你好,李焕英!';
V_NAME2:='hello';
V_NAME3:='123';
  DBMS_OUTPUT.PUT_LINE(V_NAME1);
  DBMS_OUTPUT.PUT_LINE(V_NAME2);
  DBMS_OUTPUT.PUT_LINE(V_NAME3);
END;

/

BEGIN
  DBMS_OUTPUT.PUT_LINE('海绵宝宝:你好,派大星');
  DBMS_OUTPUT.PUT_LINE('派大星:你好,海绵宝宝');
END;
/

BEGIN
  DBMS_OUTPUT.PUT_LINE('    *     *   ');
  DBMS_OUTPUT.PUT_LINE('  *^^^ * ^^^*   ');
  DBMS_OUTPUT.PUT_LINE(' *^^^^^^^^^^^*');
  DBMS_OUTPUT.PUT_LINE('  *^^^^^^^^^*   ');
  DBMS_OUTPUT.PUT_LINE('    *^^^^^*   ');
  DBMS_OUTPUT.PUT_LINE('       *   ');
END;
BEGIN
  DBMS_OUTPUT.PUT_LINE('     $$    $$      ');
  DBMS_OUTPUT.PUT_LINE('  $$     $     $$  ');
  DBMS_OUTPUT.PUT_LINE('$                 $');
  DBMS_OUTPUT.PUT_LINE('$                 $');
  DBMS_OUTPUT.PUT_LINE('  $$           $$  ');
  DBMS_OUTPUT.PUT_LINE('     $$     $$     ');
  DBMS_OUTPUT.PUT_LINE('         $         ');
END;

在PL/SQL程序中,DML操作可以直接运行。
DML操作需要在程序中运行COMMIT命令才能自动提交!

SELECT * FROM EMP;

CREATE TABLE EMP_0419 AS SELECT * FROM EMP;
---备份表emp_0419
SELECT * FROM EMP_0419;
--查询备份表emp_0419
---DML语句
BEGIN
  DELETE FROM EMP WHERE DEPTNO=10;
  COMMIT;
  ---清理emp表中10号部门的数据
  INSERT INTO EMP SELECT * FROM EMP_0419 WHERE DEPTNO=10;
  COMMIT;
  ---从备份表中把10号部门的数据局恢复
  UPDATE EMP SET SAL=SAL/2 WHERE DEPTNO=30;
  COMMIT;
  ---把30号部门的薪资调整为原来的2倍
  
END; 
CREATE TABLE EMP1 AS SELECT * FROM EMP;
SELECT * FROM EMP1;
SELECT * FROM EMP  ;

SELECT *  FROM EMP_20210330;
MERGE INTO EMP A
USING  EMP_20210330 B
ON(A.EMPNO=B.EMPNO)
WHEN MATCHED THEN
  UPDATE
  SET A.ENAME=B.ENAME,A.JOB=B.JOB,
      A.MGR=B.MGR,A.HIREDATE=B.HIREDATE,
      A.SAL=B.SAL,A.COMM=B.COMM,
      A.DEPTNO=B.DEPTNO
WHEN NOT MATCHED THEN
  INSERT(A.ENAME,A.JOB,A.MGR,A.HIREDATE,A.SAL,A.COMM,A.DEPTNO)
  VALUES(B.ENAME,B.JOB,B.MGR,B.HIREDATE,B.SAL,B.COMM,B.DEPTNO);

执行部分-DDL操作 在PL/SQL中,DDL不能直接操作,需要借助EXECUTE命令来实现。 EXECUTE IMMEDIATE
‘SQL语句’ ; 其中SQL语句可以是DML语句也可以是DDL语句
PL/SQL程序运行时,ORACLE会首先检查程序的合理性,如若有语法等问题,程序将不予执行。

---DDL语句
BEGIN
  EXECUTE IMMEDIATE 'CREATE TABLE EMP2 AS SELECT * FROM EMP';
  ---备份emp表
  EXECUTE IMMEDIATE 'TRUNCATE TABLE EMP2';
  ---清空emp表
  EXECUTE IMMEDIATE 'INSERT INTO EMP2 SELECT * FROM  EMP WHERE DEPTNO =30';
 
  ---从备份表中恢复数据
  
END;
SELECT * FROM EMP2;

合法性检查是在程序运行之前,不是在程序运行过程中 但是写在EXECUTE命令中的SQL,会避开最初的合法检查,
等到该EXECUTE命令真正运行时,会检查该EXECUTE命令携带的SQL的合法性

声明部分

声明基本都是由两部分组成:名称和类型,类似于建表语句中声明每一个字段,每个量要有自己的名字(也称标识符),同时还要有自己的属性(含数据类型与精度)。

声明部分-定义变量和常量

变量与常量都必须在声明部分完成声明,而后在执行部分中,变量与常量都只能被使用,但不能被定义。

DECLARE
   A NUMBER(4) := 30 ;      --部门编号
   
BEGIN
   UPDATE EMP_0419 SET SAL=100 WHERE DEPTNO=A;
   COMMIT;
   DBMS_OUTPUT.PUT_LINE(A||'部门薪资已更新');
   A := 10;  ---赋值
   DELETE FROM EMP_0419 WHERE DEPTNO =A;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
   COMMIT;
   DBMS_OUTPUT.PUT_LINE(A||'部门数据已经删除');
   /*A=10;*/ ---判断(条件)
   A :=20;
   UPDATE EMP_0419 SET SAL=5 WHERE DEPTNO=A;
   COMMIT;
   DBMS_OUTPUT.PUT_LINE(A||'部门薪资已更新');
END;


特殊数据类型:
1)%TYPE

DECLARE 
  V_ENAME EMP.ENAME%TYPE;
BEGIN
  SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO=7369;
  ---把查到的值ENAME放到V_ENAME中
  DBMS_OUTPUT.PUT_LINE(V_ENAME);
END;
DECLARE 
  V_ENAME EMP.ENAME%TYPE;
BEGIN
  SELECT ENAME,SAL,HIREDATE INTO V_ENAME FROM EMP WHERE EMPNO=7369;
  ---ERROR   不能把不同的数据类型放到一个里
  DBMS_OUTPUT.PUT_LINE(V_ENAME);
END;
/
DECLARE

   V_EMPNO NUMBER(4);
   V_ENAME VARCHAR2(20);
   V_JOB EMP.JOB%TYPE;

BEGIN
  SELECT EMPNO,ENAME,JOB INTO V_EMPNO,V_ENAME,V_JOB FROM EMP WHERE EMPNO=7369;
  DBMS_OUTPUT.PUT_LINE(V_EMPNO||V_ENAME||V_JOB);
END;
/

2)TYPE...DECORD
/*RECORD :*/
DECLARE
  TYPE A IS RECORD
  (V_EMPNO NUMBER(4),
   V_ENAME VARCHAR2(20),
   V_JOB EMP.JOB%TYPE);
   V_EMP A;
BEGIN
  SELECT EMPNO,ENAME,JOB INTO V_EMP FROM EMP WHERE EMPNO=7369;
  DBMS_OUTPUT.PUT_LINE(V_EMP.V_EMPNO||V_EMP.V_ENAME||V_EMP.V_JOB);
END;

3)%ROWTYPE 
DECLARE
  V_EMP  EMP%ROWTYPE;

BEGIN
  SELECT * INTO V_EMP FROM EMP WHERE EMPNO=7369;
  DBMS_OUTPUT.PUT_LINE(V_EMP.EMPNO||V_EMP.ENAME);
END;

/

DECLARE
  V_SQL VARCHAR(2000);
  V_NAME VARCHAR2(20):=UPPER('&ENAME');
  NN EMP%ROWTYPE;
  
BEGIN
  V_SQL:='SELECT * FROM EMP WHERE  ENAME='''||V_NAME||'''';
  EXECUTE IMMEDIATE V_SQL INTO NN;
  DBMS_OUTPUT.PUT_LINE(NN.EMPNO||','||NN.ENAME||','||NN.JOB||','||NN.SAL||','||NN.MGR||','||NVL(NN.COMM,0)||','||TO_CHAR(NN.HIREDATE,'YYYY/MM/DD')||','||NN.DEPTNO);
  
END;

/
DECLARE 
--声明记录类型的变量,引用EMP表中的行记录
emp_info emp1%ROWTYPE;
BEGIN
  --从emp表中取出字段值赋给记录类型
  SELECT * INTO EMP_INFO FROM EMP1 WHERE EMPNO= 7369;
  --为记录类型的变量更新新的值
  EMP_INFO.EMPNO:=7888;
  EMP_INFO.ENAME:='李焕英';
  EMP_INFO.JOB:='职员';
  EMP_INFO.SAL:='500';
 --向数据库表中插入记录类型的值
 INSERT INTO EMP1 VALUES EMP_INFO;
 COMMIT;
EXCEPTION
  WHEN OTHERS
    THEN 
      NULL;
END;
SELECT * FROM EMP1;

变量的赋值:
变量和常量在声明部分声明,不能在执行部分声明
在执行部分被使用不能定义


DECLARE 
  A NUMBER :=10;    ---A赋值为10 
  B  CONSTANT NUMBER :=20;   ---常量B赋值为20
BEGIN
  DBMS_OUTPUT.PUT_LINE(A);
  DBMS_OUTPUT.PUT_LINE(B);
END;



DECLARE 
  V_DEPTNO NUMBER :=&请输入部门编号;
  --弹出窗口,键盘输入
BEGIN
  DELETE FROM EMP_0419 WHERE DEPTNO=V_DEPTNO;  
  DBMS_OUTPUT.PUT_LINE(V_DEPTNO||号部门已删除);
END;


DECLARE 
  V_ENAME VARCHAR2(20) :=&请输入员工姓名;
  --弹出窗口,键盘输入
BEGIN
  DELETE FROM EMP_0419 WHERE ENAME=UPPER(V_ENAME);
  ---如果不用upper()则输入小写不会转化为大写
     ----小写不能被删除
  DBMS_OUTPUT.PUT_LINE(V_ENAME||员工已被删除);
END;

/

DECLARE 
  V_ENAME VARCHAR2(20) :=&请输入员工姓名;
  
BEGIN
  DBMS_OUTPUT.PUT_LINE(V_ENAME);
  V_ENAME:=UPPER(V_ENAME)
  DBMS_OUTPUT.PUT_LINE(V_ENAME);
  DELETE FROM EMP_0419 WHERE ENAME=V_ENAME;
  
  DBMS_OUTPUT.PUT_LINE(V_ENAME||员工已被删除);
END;
DECLARE 
  A VARCHAR2(20);
  
BEGIN
 /*SELECT * INTO V_EMP FROM EMP WHERE EMPNO=7369;*/
 EXECUTE IMMEDIATE 'SELECT ENAME FROM EMP WHERE EMPNO=7369' INTO A;
 DBMS_OUTPUT.PUT_LINE(A);
END;
----EXECUTE IMMEDIATE ...INTO ..赋值
---把SELECT ENAME FROM EMP WHERE EMPNO=7369 的结果赋值给 A
   
 
 

DECLARE 
  A VARCHAR2(20);
  V_SQL VARCHAR2(2000);
  
BEGIN
 /*SELECT * INTO V_EMP FROM EMP WHERE EMPNO=7369;*/
 /*EXECUTE IMMEDIATE 'SELECT ENAME FROM EMP WHERE EMPNO=7369' INTO A;*/
 V_SQL := 'SELECT ENAME  FROM EMP WHERE EMPNO=7566';
 EXECUTE IMMEDIATE V_SQL INTO A;
 DBMS_OUTPUT.PUT_LINE(A);
END;

----在V_SQL  里面不能用into
 ----在V_SQL里是一个sql语句



DECLARE 
  V_ENAME VARCHAR2(10) :='SMITH';
  V_SAL   NUMBER :=1000;
  V_SQL   VARCHAR2(1000);
  C_DEPTNO CONSTANT NUMBER :=10;

BEGIN
  SELECT SAL INTO V_SAL FROM EMP WHERE ENAME=V_ENAME;
  DBMS_OUTPUT.put_line(V_ENAME||'的工资是'||V_SAL);
  V_ENAME:='SCOTT';
  V_SQL:='SELECT SAL FROM EMP WHERE ENAME ='''||V_ENAME||'''';
  EXECUTE IMMEDIATE V_SQL INTO V_SAL;
  DBMS_OUTPUT.put_line(V_ENAME||'的工资是'||V_SAL);
  SELECT SUM(SAL) INTO V_SAL FROM EMP WHERE DEPTNO = C_DEPTNO;
  DBMS_OUTPUT.put_line(C_DEPTNO||'部门的工资是'||V_SAL);
END;

-----ERROR


DECLARE
  V_SQL VARCHAR2(2000);----动态SQL
BEGIN
  V_SQL :='DELETE FROM EMP_0419 WHERE ENAME='JAMES' ';
  -----james名字的引号与v_sql的引号分别不清
  DBMS_OUTPUT.put_line(V_SQL);
  EXECUTE IMMEDIATE V_SQL;
  COMMIT;
  
END;
SELECT * FROM EMP_0419;
DECLARE
  V_SQL VARCHAR2(2000);----动态SQL
BEGIN
  V_SQL := 'DELETE FROM EMP_0419 WHERE ENAME=''SMITH'' ';
  DBMS_OUTPUT.put_line(V_SQL);
  EXECUTE IMMEDIATE V_SQL;
  COMMIT;
  
END;
SELECT * FROM EMP_0419;
DECLARE
  V_SQL VARCHAR2(2000);
  V_ENAME VARCHAR2(20) :='&请指定员工姓名';----动态SQL
BEGIN
  --V_SQL := 'DELETE FROM EMP_0419 WHERE ENAME=''V_ENAME'' ';---不会删除数据
  V_SQL := 'DELETE FROM EMP_0419 WHERE ENAME='''||V_ENAME||'''';
  DBMS_OUTPUT.put_line(V_SQL);
  EXECUTE IMMEDIATE V_SQL;
  COMMIT;
  
END;

DELETE FROM EMP_0419 WHERE ENAME='
ALLEN
'

插入一条数据用executeimmediate

DECLARE
  V_SQL VARCHAR2(2000);

BEGIN
  V_SQL := 'INSERT INTO EMP_0419(EMPNO,ENAME,SAL) VALUES (1234,'||'''ZHANGSAN'''||',800)';
  DBMS_OUTPUT.put_line(V_SQL);
  EXECUTE IMMEDIATE  V_SQL;
  COMMIT;
END;
/

SELECT * FROM EMP_0419 FOR UPDATE;

/
DECLARE
  V_SQL VARCHAR2(2000);

BEGIN
  V_SQL := 'INSERT INTO EMP_0419(EMPNO,ENAME,SAL) VALUES (1234,''ZHANGSAN'',800)';
  DBMS_OUTPUT.put_line(V_SQL);
  EXECUTE IMMEDIATE  V_SQL;
  COMMIT;
END;

从键盘获取MAX/MIN/AVG/SUM中的一种 返回所有员工对应的最大薪资/最小薪资/平均薪资/合计薪资
统计结果按四舍五入处理到整数位 eg:输入:MAX,返回:所有员工的最大薪资是5000元
输入:AVG,返回:所有员工的平均薪资是2073元

DECLARE
  V_SAL NUMBER;
  V_SQL VARCHAR2(2000);
  V_VALUE VARCHAR2(30) :='&请输入' ;---键盘获取MAX/MIN/AVG/SUM中的一种  
BEGIN
  
  IF V_VALUE = 'MAX' THEN
    V_SQL := 'SELECT MAX(SAL) FROM EMP';
    DBMS_OUTPUT.put_line(V_SQL);
    EXECUTE IMMEDIATE V_SQL INTO V_SAL;
    DBMS_OUTPUT.put_line('所有员工的最大薪资是'||V_SAL||'元');
   ELSIF V_VALUE ='MIN' THEN 
    V_SQL := 'SELECT MIN(SAL) FROM EMP';
    DBMS_OUTPUT.put_line(V_SQL);
    EXECUTE IMMEDIATE V_SQL INTO V_SAL;
    DBMS_OUTPUT.put_line('所有员工的最小薪资是'||V_SAL||'元');
   ELSIF V_VALUE ='AVG' THEN 
    V_SQL := 'SELECT AVG(SAL) FROM EMP';
    DBMS_OUTPUT.put_line(V_SQL);
    EXECUTE IMMEDIATE V_SQL INTO V_SAL;
    DBMS_OUTPUT.put_line('所有员工的平均薪资是'||V_SAL||'元');
   ELSIF V_VALUE ='SUM' THEN
    V_SQL := 'SELECT SUM(SAL) FROM EMP';
    DBMS_OUTPUT.put_line(V_SQL);
    EXECUTE IMMEDIATE V_SQL INTO V_SAL;
    DBMS_OUTPUT.put_line('所有员工的合计薪资是'||V_SAL||CHR(13)||'元');
   END IF;
 

END;


/

DECLARE
  V_SAL NUMBER;
  V_SQL VARCHAR2(2000);
  V_VALUE VARCHAR2(30) :='&请输入';----键盘获取MAX/MIN/AVG/SUM中的一种  
BEGIN
    
 IF V_VALUE IN('MAX','MIN','AVG','SUM') THEN
    V_SQL := 'SELECT '||V_VALUE||'(SAL) FROM EMP';
    DBMS_OUTPUT.put_line(V_SQL);
    EXECUTE IMMEDIATE V_SQL INTO V_SAL;
    DBMS_OUTPUT.put_line('所有员工的'||CASE WHEN V_VALUE ='MAX' THEN  '最大'
                                            WHEN V_VALUE ='MIN' THEN  '最小'
                                            WHEN V_VALUE ='AVG' THEN  '平均'
                                            WHEN V_VALUE ='SUM' THEN  '合计'
                                        END
    ||'薪资是'||ROUND(V_SAL)||CHR(13)||'元');   ----CHR(13)  换行
  ELSE
    DBMS_OUTPUT.put_line('请输入正确的类型');
  END IF;
 

END;
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值