经典plsql例子
plsql建表 基本语句

plsql建表基本语句在PL/SQL中,创建表的基本语句是使用CREATE TABLE命令。
以下是创建表的基本语法:sqlCREATE TABLEtable_name (column1 datatype[constraint],column2 datatype[constraint],column3 datatype[constraint],...);其中,table_name是表的名称,column1, column2, column3等是表中的列名,datatype是列的数据类型,constraint是可选的约束条件。
以下是一个示例,展示如何在PL/SQL中创建一个简单的表:sqlCREATE TABLE employees (employee_id NUMBER PRIMARYKEY,first_name VARCHAR2(50),last_name VARCHAR2(50),hire_date DATE,salary NUMBER(8,2) CHECK(salary > 0));在上面的示例中,我们创建了一个名为employees的表,包含了五个列:employee_id、first_name、last_name、hire_date和salary。
每个列都有相应的数据类型,并且为employee_id列设置了主键约束,为salary列设置了检查约束,确保工资大于0。
请注意,PL/SQL通常用于Oracle数据库的存储过程和函数,而创建表的语句实际上是在SQL部分执行的。
在Oracle SQL Developer 等工具中,可以直接执行上述SQL语句来创建表。
如果你需要在PL/SQL块中执行DDL语句(如CREATE TABLE),你可以使用动态SQL (例如EXECUTE IMMEDIATE语句)来实现。
plsql实现矩阵相乘

plsql实现矩阵相乘PL/SQL是一种结构化查询语言,用于管理Oracle数据库中的数据。
它是一种功能强大的编程语言,可以用于开发复杂的数据库应用程序。
在本文中,我们将探讨如何使用PL/SQL实现矩阵相乘。
矩阵相乘是一种常见的数学运算,它用于将两个矩阵相乘得到一个新的矩阵。
矩阵相乘的规则是,第一个矩阵的列数必须等于第二个矩阵的行数。
结果矩阵的行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。
我们可以使用PL/SQL编写一个函数来实现矩阵相乘。
首先,我们需要定义两个输入参数,分别代表两个矩阵。
这两个矩阵可以用二维数组来表示。
然后,我们需要定义一个输出参数,用于存储结果矩阵。
接下来,我们可以使用嵌套循环来计算结果矩阵的每一个元素。
外层循环用于遍历结果矩阵的行,内层循环用于遍历结果矩阵的列。
在每次迭代中,我们可以使用另外两个嵌套循环来计算结果矩阵的每一个元素。
这两个嵌套循环分别用于遍历第一个矩阵的行和第二个矩阵的列。
在每次迭代中,我们可以使用一个变量来存储结果矩阵的当前元素。
然后,我们可以使用另外两个变量来计算该元素的值。
第一个变量可以用于遍历第一个矩阵的列,第二个变量可以用于遍历第二个矩阵的行。
在每次迭代中,我们可以使用这两个变量来获取第一个矩阵中的当前元素和第二个矩阵中的当前元素,并将它们相乘。
然后,我们可以将结果累加到结果矩阵的当前元素上。
当所有的迭代完成后,我们可以返回结果矩阵作为输出参数。
这样,我们就完成了矩阵相乘的计算。
下面是一个使用PL/SQL实现矩阵相乘的示例代码:```plsqlCREATE OR REPLACE FUNCTION matrix_multiplication (matrix1 IN SYS.ODCINUMBERLIST,matrix2 IN SYS.ODCINUMBERLIST) RETURN SYS.ODCINUMBERLIST ISrows1 NUMBER := matrix1.COUNT;cols1 NUMBER := matrix1(1).COUNT;rows2 NUMBER := matrix2.COUNT;cols2 NUMBER := matrix2(1).COUNT;result SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST();BEGINIF cols1 <> rows2 THENRAISE_APPLICATION_ERROR(-20001, 'The number of columns in the first matrix must be equal to the number of rows in the second matrix.');END IF;FOR i IN 1..rows1 LOOPresult.EXTEND;FOR j IN 1..cols2 LOOPresult(ST) := 0;FOR k IN 1..cols1 LOOPresult(ST) := result(ST) + matrix1(i)(k) * matrix2(k)(j);END LOOP;END LOOP;END LOOP;RETURN result;END;/```在上面的代码中,我们使用了一个名为`SYS.ODCINUMBERLIST`的数据类型来表示矩阵。
第13章plsql命名对象13道题

(1)创建一个存储过程,以员工号为参数,输出该员工的工资。
create or replace procedure pro_showsal(p_empno employees.employee_id%type)asv_sal employees.salary%type;beginselect salary into v_sal from employeeswhere employee_id=p_empno;dbms_output.put_line(v_sal);exceptionwhen no_data_found thendbms_output.put_line('there is not such an employees');end;beginpro_showsal(100);end;(2)创建一个存储过程,以员工号为参数,修改该员工的工资。
若该员工属于10号部门,则工资增加140元;若属于20号部门,则工资增加200元;若属于30号部门,则工资增加250元;若属于其他部门,则工资增长300元。
create or replace procedure pro_updatesal(p_empno employees.employee_id%type)asv_deptno employees.department_id%type;v_inc number;beginselect department_id into v_deptno from employeeswhere employee_id=p_empno;case v_deptnowhen 10 then v_inc:=140;when 20 then v_inc:=200;when 30 then v_inc:=250;else v_inc:=300;end case;update employees set salary=salary+v_incwhere employee_id=p_empno;exceptionwhen no_data_found thendbms_output.put_line('there is not such an employees');end;(3)创建一个存储过程,以部门号为参数,输出入职日期最早的10个员工信息。
plsql case语句

plsql case语句
1. 嘿,你知道吗,PL/SQL 的 CASE 语句就像一个魔法开关!比如说,根据成绩来判断等级,成绩大于等于 90 就是“优秀”,这多神奇啊!
2. 哇塞,PL/SQL 的 CASE 语句简直太好用啦!就像走迷宫时有了明确的指引一样。
比如根据天气决定穿什么衣服,晴天就穿短袖,阴天就穿长袖。
3. 哎呀呀,PL/SQL 的 CASE 语句啊,那可是个厉害的角色!好比是一个智能的分配器。
例如根据顾客类型给予不同的优惠,会员就多给点折扣。
4. 嘿哟,PL/SQL 的 CASE 语句,这可是个宝贝呀!就如同根据不同口味选择不同的冰淇淋,喜欢甜的就选巧克力味。
5. 哇哦,PL/SQL 的 CASE 语句,它可真是神了!像根据不同的交通方式选择不同的路线一样。
比如坐公交就走这条道,打车就走那条道。
6. 哈哈,PL/SQL 的 CASE 语句,不就是像选电影类型一样嘛!爱情片就一种风格,动作片就另一种风格。
7. 哎哟喂,PL/SQL 的 CASE 语句,那可相当重要啊!就好像根据不同的节日装饰不同的房间,春节就红彤彤的。
8. 嘿嘿,PL/SQL 的 CASE 语句,这可真是个妙东西!如同根据不同
的兴趣爱好选择不同的活动,喜欢运动就去打球。
9. 呀,PL/SQL 的 CASE 语句,它的作用可大了去了!就跟根据不同的心情听不同的音乐一样,开心就听欢快的。
10. 哇,PL/SQL 的 CASE 语句,这绝对是个不可或缺的呀!好比根据不同的季节穿不同厚度的衣服,冬天就穿厚棉袄。
我觉得 PL/SQL 的 CASE 语句真的是超级实用,能让我们的编程工作变得轻松又有趣!。
plsql分页查询语句

plsql分页查询语句PL/SQL是Oracle数据库的编程语言,可以用于编写存储过程、触发器和函数等数据库对象。
在PL/SQL中,可以使用分页查询语句来实现对大量数据的分页显示,提高查询效率和用户体验。
下面列举了10个符合题目要求的PL/SQL分页查询语句。
1. 使用ROWNUM和BETWEEN关键字实现分页查询:```plsqlDECLAREv_start NUMBER := 1;v_end NUMBER := 10;BEGINSELECT *FROM (SELECT t.*, ROWNUM rFROM (SELECT * FROM table_name ORDER BY column_name) tWHERE ROWNUM <= v_end)WHERE r >= v_start;END;```2. 使用游标和FOR循环实现分页查询:```plsqlDECLARECURSOR c IS SELECT * FROM table_name ORDER BY column_name;v_start NUMBER := 1;v_end NUMBER := 10;BEGINFOR i IN v_start..v_end LOOPFETCH c INTO var1, var2, ...;EXIT WHEN c%NOTFOUND;-- 处理每一行数据END LOOP;CLOSE c;END;```3. 使用LIMIT和OFFSET子句实现分页查询:```plsqlSELECT *FROM table_nameORDER BY column_nameLIMIT 10 OFFSET 0;```4. 使用ROW_NUMBER()函数和子查询实现分页查询:```plsqlSELECT *FROM (SELECT t.*, ROW_NUMBER() OVER (ORDER BY column_name) rnFROM table_name t)WHERE rn BETWEEN 1 AND 10;```5. 使用FETCH FIRST和OFFSET子句实现分页查询:```plsqlSELECT *FROM table_nameORDER BY column_nameOFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;```6. 使用嵌套子查询和ROWNUM实现分页查询:```plsqlSELECT *FROM (SELECT t.*, ROWNUM rFROM (SELECT * FROM table_name ORDER BY column_name) tWHERE ROWNUM <= 10)WHERE r >= 1;```7. 使用游标和FETCH子句实现分页查询:```plsqlDECLARECURSOR c IS SELECT * FROM table_name ORDER BY column_name;v_start NUMBER := 1;v_end NUMBER := 10;BEGINOPEN c;FETCH c BULK COLLECT INTO var1, var2, ... LIMIT v_end;CLOSE c;FOR i IN v_start..v_end LOOP-- 处理每一行数据END LOOP;END;```8. 使用ROW_NUMBER()函数和嵌套查询实现分页查询:```plsqlSELECT *FROM (SELECT t.*, ROW_NUMBER() OVER (ORDER BY column_name) rnFROM (SELECT * FROM table_name WHERE rownum <= 10) t)WHERE rn >= 1;```9. 使用游标和WHILE循环实现分页查询:```plsqlDECLARECURSOR c IS SELECT * FROM table_name ORDER BY column_name;v_start NUMBER := 1;v_end NUMBER := 10;v_count NUMBER := 0;BEGINOPEN c;LOOPFETCH c INTO var1, var2, ...;EXIT WHEN c%NOTFOUND OR v_count >= v_end;IF v_count >= v_start THEN-- 处理每一行数据END IF;v_count := v_count + 1;END LOOP;CLOSE c;END;```10. 使用游标和LIMIT子句实现分页查询:```plsqlDECLARECURSOR c IS SELECT * FROM table_name ORDER BY column_name LIMIT 10;BEGINOPEN c;FOR i IN c LOOP-- 处理每一行数据END LOOP;CLOSE c;END;```以上是10个符合题目要求的PL/SQL分页查询语句,可以根据实际需求选择合适的方式来实现分页查询功能。
plsql union用法

plsql union用法在PL/SQL中,UNION用于合并两个或多个SELECT语句的结果集。
与SQL中的UNION类似,PL/SQL的UNION也需要确保SELECT语句具有相同数量的列,且列的数据类型相似。
PL/SQL UNION语法如下:```UNION_STATEMENT :=SELECT column_name(s)FROM table_name1UNIONSELECT column_name(s)FROM table_name2;```其中,`UNION_STATEMENT`是您需要定义的变量,用于存储UNION操作的结果。
以下是一个简单的示例:假设我们有两个表:`employeeschina`和`employeesusa`,它们都有`EID`和`EName`列。
```sql--查询中国的员工信息SELECT EID, EName FROM employeeschina--查询美国的员工信息SELECT EID, EName FROM employeesusa--使用PL/SQL UNION合并结果UNION_STATEMENT :=SELECT EID, ENameFROM employeeschinaUNIONSELECT EID, ENameFROM employeesusa;--输出合并后的结果SELECT * FROM UNION_STATEMENT;```此查询将返回一个包含两个表中所有不重复员工的列表。
如果需要包含重复值,可以使用`UNION ALL`。
请注意,当涉及到不同表之间的UNION操作时,确保表具有相同的列数和数据类型。
如果需要,可以通过在查询中使用`AS`关键字为列分配别名。
例如,如果`employeeschina`表中有一个名为`EHello`的额外列,而`employeesusa`表中没有该列,则需要对查询进行调整:```sql--查询中国的员工信息,并为EHello列分配别名SELECT EID, EName, EHello AS EHelloFROM employeeschina--查询美国的员工信息SELECT EID, ENameFROM employeesusa--使用PL/SQL UNION合并结果UNION_STATEMENT :=SELECT EID, EName, EHelloFROM employeeschinaUNIONSELECT EID, EName, ' ' AS EHelloFROM employeesusa;--输出合并后的结果SELECT * FROM UNION_STATEMENT;```这个示例将返回一个包含两个表中所有员工的列表,其中中国的员工列`EHello`被替换为空字符串。
PLSQL练习题一

PLSQL练习题一PL/SQL练习题在Oracle中所有的过程都是以PL/SQL块开始的,掌握PL/SQL 对于过程的开发是非常用用处的。
PL/SQL块的定义格式:范例:使用以上的语句,创建一个简单的程序块以上一个基本的语句块已经写完了,但是里面并没有任何的输出,之所以这样,主要原因在于SQLPLUSW中的系统输出没有打开,需要通过以下的命令完成:以上是一个简单的语句块,但是在PLSQL块中也可以直接进行数据库的查询操作。
范例:要求输入一个雇员的编号,之后显示出此编号雇员的姓名·如果要想输入雇员编号的话,第八章存在一个替代变量“&”此时已经可以查询出来了,但是以上的代码是否会存在其他问题呢?如果现在输入的编号不存在则有可能返回错误信息,那么为了让代码在出现错误之后依然可以正确的使用,则可以加入异常处理的操作机制。
但是,从以上的程序中可以发现,在SQLPLUSW中输出实际上并没有真正的意义,所以显示的格式也就没有必要做任何的调整。
在PL/SQL块中也可以编写循环、判断等语句。
可以使用循环操作:LOOP,循环这个时候一个循环语句就已经编写完成了。
此循环属于先执行后判断,所以可以使用另外一种循环语句:WHILE…LOOP。
那么,此种循环操作属于先判断后执行。
在PL/SQL中也可以使用FOR循环方式PLSQL中同样存在IF语句,执行条件的分支操作。
范例:给定一个值,要求判断其是否大于10,如果大于,则显示记录大于10条但是,以上的内容都属于固定好的结果,现在要求可以将emp表中的记录数进行验证。
也可以使用if..else语句If语句上还能继续扩展,if…elseif….else….但是需要注意的是,在Oracle中的else if要换成elsif那么,下面就可以利用以上的语句完成一些的复杂功能。
要求:要求输入一个雇员编号,为此雇员增长工资,增长工作按照以下的原则进行:·10部门人员工资上涨10%·20部门人员工资上涨20%·30部门人员工资上涨30%但是所有的工资最高不超过5000。
PLSQL经典练习

PLSQL经典练习/*====================================== ===================PL/SQL编程====================================== ===================*/--先把scott里面的表弄到test表空间里面来CREATE TABLE EMP ASSELECT * FROM SCOTT.EMP;CREATE TABLE DEPT ASSELECT * FROM SCOTT.DEPT;/*上机1*/--(1)计算King所交税金DECLAREV_SHUIJIN NUMBER; --应交税金V_SAL SCOTT.EMP.SAL%TYPE; --工资C_QIZHENDIAN CONSTANT NUMBER :=3500;BEGINSELECT SAL INTO V_SAL FROM SCOTT.EMP WHERE ENAME='KING';IF (V_SAL-C_QIZHENDIAN)<=1500 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.03-0;ELSIF (V_SAL-C_QIZHENDIAN)>1500 AND (V_SAL-C_QIZHENDIAN)<=4500 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.1-105;ELSIF (V_SAL-C_QIZHENDIAN)>4500 AND (V_SAL-C_QIZHENDIAN)<=9000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.2-555;ELSIF (V_SAL-C_QIZHENDIAN)>9000 AND (V_SAL-C_QIZHENDIAN)<=35000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.25-1005;ELSIF (V_SAL-C_QIZHENDIAN)>35000 AND (V_SAL-C_QIZHENDIAN)<=55000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.3-2755;ELSIF (V_SAL-C_QIZHENDIAN)>55000 AND (V_SAL-C_QIZHENDIAN)<=80000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.35-5505;ELSIF (V_SAL-C_QIZHENDIAN)>80000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.45-13505;END IF;DBMS_OUTPUT.PUT_LINE('KING所交的税金是:'||V_SHUIJIN);END;--(2)根据员工scott入职的时间修改发放奖金列,大于等于6年的奖金为2000,小于6年的奖金是1500DECLAREV_SCOTT_HIREDATE EMP.HIREDATE%TYPE; --SCOTT的入职时间V_COMM NUMBER; --奖金BEGINSELECT HIREDATE INTO V_SCOTT_HIREDATE FROM EMP WHERE ENAME='SCOTT';IF (SYSDATE-V_SCOTT_HIREDATE)>=365*6 THENV_COMM:=2000;ELSEV_COMM:=1500;END IF;--开始修改UPDATE EMP SET COMM=V_COMM WHERE ENAME='SCOTT';IF SQL%ROWCOUNT>0 THENDBMS_OUTPUT.PUT_LINE('修改成功!');ELSEDBMS_OUTPUT.PUT_LINE('修改失败!');END IF;END;--(3)查询scott相应的工资级别并显示所在部门名称,薪水,和所在的级别DECLAREV_SCOTT_SAL EMP.SAL%TYPE; --scott的工资V_JIBIE NUMBER; --级别V_DEPTNAME DEPT.DNAME%TYPE; --部门名称BEGINSELECT SAL,DNAME INTO V_SCOTT_SAL,V_DEPTNAME FROM EMP E JOIN DEPT DON E.DEPTNO=D.DEPTNOWHERE ENAME='SCOTT';IF V_SCOTT_SAL>700 AND V_SCOTT_SAL<=3200 THENV_JIBIE:=1; --第一级别ELSIF V_SCOTT_SAL>3200 AND V_SCOTT_SAL<=4400 THEN V_JIBIE:=2; --第二级别ELSIF V_SCOTT_SAL>4400 AND V_SCOTT_SAL<=5000 THEN V_JIBIE:=3; --第三级别ELSIF V_SCOTT_SAL>5000 AND V_SCOTT_SAL<=7000 THEN V_JIBIE:=4; --第四级别ELSIF V_SCOTT_SAL>7000 AND V_SCOTT_SAL<=10000 THENV_JIBIE:=5; --第五级别END IF;DBMS_OUTPUT.PUT_LINE('SCOTT所在的部门是:'||||',薪水是:'||V_SCOTT_SAL||',所在的级别是:第'||V_JIBIE||'级别');END;--(4)位员工scott增加工资,每次增加100,直到增加到10000为止DECLAREV_SCOTT_SAL EMP.SAL%TYPE; --SCOTT的工资BEGINSELECT SAL INTO V_SCOTT_SAL FROM EMP WHERE ENAME='SCOTT';LOOP--增加工资V_SCOTT_SAL:=V_SCOTT_SAL+100;EXIT WHEN V_SCOTT_SAL>=10000;END LOOP;--修改scott的工资UPDATE EMP SET SAL=V_SCOTT_SAL WHERE ENAME='SCOTT';IF SQL%ROWCOUNT>0 THENDBMS_OUTPUT.PUT_LINE('增加成功!');ELSEDBMS_OUTPUT.PUT_LINE('增加失败!');END IF;END;/*上机2 预定义异常公司通过emp表维护职员记录,用以接收职员编号并检索职员姓名,*/DECLAREV_ENAME VARCHAR2(4);BEGINSELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO=&EMPNO;DBMS_OUTPUT.PUT_LINE('已找到'||V_ENAME);EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('对不起,没有该职员!');WHEN VALUE_ERROR THENDBMS_OUTPUT.PUT_LINE('职员名称太长!');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('出现其他的异常!');END;/*上机3自定义异常、||输入员工编号,工资,部门编号,||如果部门代码是10,且工资低于10000,更新员工的工资是10000||如果部门代码是10,工资高于10000,显示消息“工资不低于10000”||如果部门代码不是10则不显示*/DECLAREV_EMPNO EMP.EMPNO%TYPE; --员工编号V_DEPTNO EMP.DEPTNO%TYPE; --部门编号V_SAL EMP.SAL%TYPE; --工资V_ENAME EMP.ENAME%TYPE; --姓名V_V_EMPNO EMP.EMPNO%TYPE; --输入员工编号V_V_DEPTNO EMP.DEPTNO%TYPE; --输入部门编号V_V_SAL EMP.SAL%TYPE; --输入工资E_ERROR_DEPTNO EXCEPTION; --自定义异常(部门编号不是10)E_ERROR_EMPNO EXCEPTION; --自定义异常(找不到该员工) V_COUNT NUMBER; --声明一个记录数BEGIN--输入员工编号V_EMPNO:=&V_V_EMPNO;--输入工资V_SAL:=&V_VSAL;--输入部门编号V_DEPTNO:=&V_V_DEPTNO;IF V_DEPTNO=10 THEN--在进行二次判断(输入员工编号)IF V_SAL<10000 THEN--判断输入的员工编号是否存在,不存在的话报异常,存在的话继续SELECT COUNT(*) INTO V_COUNT FROM EMP WHERE EMPNO=V_DEPTNO;IF V_COUNT!=1 THENRAISE E_ERROR_EMPNO; --报异常ELSE--更新工资为1000UPDATE EMP SET SAL=10000 WHERE EMPNO=V_EMPNO; IF SQL%ROWCOUNT>0 THENDBMS_OUTPUT.PUT_LINE('更新成功');ELSEDBMS_OUTPUT.PUT_LINE('更新失败');END IF;END IF;ELSIF V_SAL>10000 THENDBMS_OUTPUT.PUT_LINE('工资不低于10000!!');END IF;ELSERAISE E_ERROR_DEPTNO;END IF;EXCEPTIONWHEN E_ERROR_DEPTNO THENDBMS_OUTPUT.PUT_LINE('部门代码不是10!!');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('出现其他异常,请自行解决'); END;------------------------------------------------------SELECT * FROM EMP;DECLAREV_NAME EMP.ENAME%TYPE;E_ERROR EXCEPTION;V_COUNT NUMBER; --记录数BEGINSELECT COUNT(*) INTO V_COUNT FROM EMP WHERE EMPNO=7901;IF (V_COUNT=1) THENDBMS_OUTPUT.PUT_LINE(V_NAME);ELSERAISE E_ERROR;END IF;EXCEPTIONWHEN E_ERROR THENDBMS_OUTPUT.PUT_LINE('没有记录!');/*when no_data_found thenDBMS_OUTPUT.PUT_LINE('找不到!');*/END;-------------------------------------------------------------DECLAREV_NAME VARCHAR2(10);E_ERROR EXCEPTION;BEGINIF V_NAME IS NULL THENRAISE E_ERROR;ELSEDBMS_OUTPUT.PUT_LINE();END IF;EXCEPTIONWHEN E_ERROR THENDBMS_OUTPUT.PUT_LINE('没有记录!');END;/*//上机4使用游标*/--(1)计算公司应交税金的总额DECLAREV_SHUIJIN NUMBER; --应交税金V_SAL SCOTT.EMP.SAL%TYPE; --工资V_SUM NUMBER(10):=0; --总税金C_QIZHENDIAN CONSTANT NUMBER :=3500;CURSOR CURSOR_SAL ISSELECT SAL FROM EMP; --所有的员工的工资BEGINOPEN CURSOR_SAL;LOOPFETCH CURSOR_SAL INTO V_SAL;--把所有的工资放在V_SAL里面EXIT WHEN CURSOR_SAL%NOTFOUND;IF (V_SAL-C_QIZHENDIAN)<=1500 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.03-0;ELSIF (V_SAL-C_QIZHENDIAN)>1500 AND (V_SAL-C_QIZHENDIAN)<=4500 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.1-105;ELSIF (V_SAL-C_QIZHENDIAN)>4500 AND (V_SAL-C_QIZHENDIAN)<=9000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.2-555;ELSIF (V_SAL-C_QIZHENDIAN)>9000 AND (V_SAL-C_QIZHENDIAN)<=35000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.25-1005;ELSIF (V_SAL-C_QIZHENDIAN)>35000 AND (V_SAL-C_QIZHENDIAN)<=55000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.3-2755;ELSIF (V_SAL-C_QIZHENDIAN)>55000 AND (V_SAL-C_QIZHENDIAN)<=80000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.35-5505;ELSIF (V_SAL-C_QIZHENDIAN)>80000 THENV_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.45-13505;END IF;V_SUM:=V_SUM+V_SHUIJIN;END LOOP;CLOSE CURSOR_SAL; --关闭游标DBMS_OUTPUT.PUT_LINE(V_SUM);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('出现异常!');END;--(2)根据员工入职时间修改所有员工发放奖金,大于6年的+2000,小于的1500+DECLAREV_COMM M%TYPE; --奖金CURSOR CURSOR_EMP_COMM ISSELECT HIREDATE FROM EMP FOR UPDATE;BEGINFOR CUR1 IN CURSOR_EMP_COMM LOOPIF (SYSDATE-CUR1.HIREDATE)>=365*6 THENV_COMM:=2000;ELSEV_COMM:=1500;END IF;--开始修改UPDATE EMP SET COMM=V_COMM WHERE CURRENT OF CURSOR_EMP_COMM;IF SQL%ROWCOUNT>0 THENDBMS_OUTPUT.PUT_LINE('更新成功');ELSEDBMS_OUTPUT.PUT_LINE('更新失败');END IF;END LOOP;EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('出现异常!');END;--(3)显示员工姓名,所在部门名称,薪水,所在级别DECLAREC_DNAME CONSTANT VARCHAR2(20):='SALES'; --销售部门V_JIBIE NUMBER; --级别CURSOR CURSOR_EMP ISSELECT ENAME,DNAME,SAL FROM EMP EJOIN DEPT D ON E.DEPTNO=D.DEPTNOWHERE DNAME=C_DNAME;BEGINFOR C1 IN CURSOR_EMP LOOPIF C1.SAL>700 AND C1.SAL<=3200 THENV_JIBIE:=1; --第一级别ELSIF C1.SAL>3200 AND C1.SAL<=4400 THENV_JIBIE:=2; --第二级别ELSIF C1.SAL>4400 AND C1.SAL<=5000 THENV_JIBIE:=3; --第三级别ELSIF C1.SAL>5000 AND C1.SAL<=7000 THENV_JIBIE:=4; --第四级别ELSIF C1.SAL>7000 AND C1.SAL<=10000 THENV_JIBIE:=5; --第五级别ELSEV_JIBIE:=0; --没有级别END IF;DBMS_OUTPUT.put_line(C1.ENAME||'在'||C1.DNAME||'部门,'||'薪水是'||C1.SAL||'在第'||V_JIBIE||'级别');END LOOP;EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('出现异常!');END;/*上机5 存储过程*/--(1)根据输入的员工编号,删除相应的员工CREATE OR REPLACE PROCEDURE DEL_EMPNAME(ENO EMP.EMPNO%TYPE, --输入员工的编号ON_FLAG OUT NUMBER, --执行状态,-1失败,1成功0异常ON_MSG OUT VARCHAR --提示信息)ISE_ERROR EXCEPTION; --异常信息BEGINDELETE FROM EMP WHERE EMPNO=ENO; IF SQL%NOTFOUND THENRAISE E_ERROR;ELSEON_FLAG:=1; --执行成功ON_MSG:='删除成功!';END IF;EXCEPTIONWHEN E_ERROR THENON_FLAG:=0; --执行成功ON_MSG:='删除失败!';WHEN OTHERS THENON_FLAG:=0;ON_MSG:='出现异常!';END;DROP PROCEDURE DEL_EMPNAME;--调用存储过程DECLAREV_EMPNO NUMBER;ENO NUMBER(5);ON_FLAG NUMBER(1);ON_MSG VARCHAR(20);BEGINENO:=&EMPNO; --输入编号DEL_EMPNAME(ENO,ON_FLAG,ON_MSG); DBMS_OUTPUT.PUT_LINE(ON_FLAG); DBMS_OUTPUT.PUT_LINE(ON_MSG); END;--(2)创建输出参数为薪水集合的存储过程,调用并显示所有员工的薪水。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
setserveroutput on;--计算两个整数的和与这两个整数的差的商declareaint:=100;bint:=200;c number;beginc:=(a+b)/(a-a);dbms_output.put_line(c);exceptionwhenzero_divide thendbms_output.put_line('除数不能为零!');end;/declareNum_sal number; --声明一个数值变量Var_ename varchar2(20); --声明一个字符串变量beginselect ename,sal into Var_ename,Num_sal from scott.emp where empno=7369; --检索指定的值并保存在变量中dbms_output.put_line(Var_ename||'的工资是'||Num_sal); --输出变量的值end;/--简单的插入一条语句create or replace procedure pro1 isbegininsert into scott.emp(empno,ename)values(1111,'1111');end;/exec pro1;select * from scott.emp;--删除一条语句(传参)create procedure pro2(in_empno number) isbegindelete from emp where empno=in_empno;end;/--简单的插入一条语句(传参)create or replace procedure pro3(in_empnonumber,in_ename varchar2) isbegininsert into scott.emp(empno,ename)values(in_empno,in_ename);end;/declare--定义变量的格式是变量名称变量的类型v_enamevarchar2(8);beginselect ename into v_ename from emp where empno=&empno; --将查询到的值存入v_ename变量中--输出v_enamedbms_output.put_line('雇员名是'||v_ename);end;/--将上面的块改成过程create procedure pro4(v_in_empno number) isv_enamevarchar2(8);beginselectename into v_ename from emp where empno=v_in_empno;dbms_output.put_line('雇员名是'||v_ename);end;/--编写一个过程,实现输入雇员名,新工资可以修改雇员的工资create procedure pro5(in_ename in varchar2,in_newsal in number) isbeginupdateemp set sal=in_newsal where ename = in_ename;end;/--编写一个过程,可以接受id和薪水,更新薪水,如果id不存在,需要在exception中捕获,并给出提示!create or replace procedure pro6(in_empnonumber,in_sal number) isv_enamevarchar2(32);v_empno number;beginselect empno into v_empno from emp where empno = in_empno; --此条语句为了实现在exception中可以抛出no_data_foundupdateemp set sal = in_sal where empno = in_empno;exceptionwhenno_data_found thendbms_output.put_line('您输入的编号有误!');end;/--编写一个函数,可以根据接受用户名并返回用户的年薪create or replace function fun1(in_ename varchar2)return number is--定义一个变量来接受年薪v_annual_sal number;beginselect (sal+nvl(comm,0))*13 into v_annual_sal from emp where ename=in_ename; returnv_annual_sal;end;select fun1('SMITH') from dual;--定义一个包,该包有一个过程,该过程可以接收用户名和新的薪水(将用于通过用户名去更新薪水),--还有一个函数,该函数可以接受一个用户名(将用于实现得到该用户的年薪是多少)create or replace package mypackage1 is--声明一个过程procedure pro1(in_ename varchar2,in_newsal number);--声明一个函数function fun1(in_ename varchar2) return number;end;/--编写一个包体的案例create or replace package body mypackage1 is--实现过程procedure pro1(in_ename varchar2,in_newsal number) isbeginupdateemp set sal=in_newsal where ename = in_ename;end;--实现函数function fun1(in_ename varchar2) return number isv_annual_sal number;begin select(sal+nvl(comm,0))*13 into v_annual_sal from emp where ename=in_ename;returnv_annual_sal;end;end;/--输入员工的工号,显示雇员姓名、工资、个人所得税(税率为0.03)create or replace procedure pro7(in_empno in number) isv_tax_rate number(3,2):=0.03;v_ename varchar(32);v_sal number;v_pay number;beginselectename,sal into v_ename,v_sal from emp where empno=in_empno;v_pay:=v_tax_rate*v_sal;dbms_output.put_line(v_ename||'工资是='||v_sal||'个人所得税是:='||v_pay); end;/--使用%type定义数据create or replace procedure pro7(in_empno in number) isv_tax_rate number(3,2):=0.03;v_enameemp.ename%type;v_salemp.sal%type;v_pay number;beginselectename,sal into v_ename,v_sal from emp where empno=in_empno;v_pay:=v_tax_rate*v_sal;dbms_output.put_line(v_ename||'工资是='||v_sal||'个人所得税是:='||v_pay); end;/--使用pl/sql复合类型(record),编写一个过程可以接受一个用户编号,并显示该用户的名字,薪水,工作岗位。
create or replace procedure pro8(in_empno in number) is--定义一个记录数据类型type my_record1 is record(v_enameemp.ename%type,v_salemp.sal%type,v_jobemp.job%type);--定义一个变量,该变量的类型是my_record1v_emp_record my_record1;beginselectename,sal,job into v_emp_record from emp where empno=in_empno;dbms_output.put_line('姓名是:'||v_emp_record.v_ename||'工作是:'||v_emp_record.v_job||'工资是:'||v_emp_record.v_sal);end;/declare type my_table1 is table of emp.ename%type index by binary_integer;my_table my_table1; --定义一个变量my_table1类型beginselectename into my_table(0) from emp where empno = 7369;dbms_output.put_line('员工名:'||my_table(0));end;-- 说明:my_table1是pl/sql表的类型-- emp.ename%type指定表元素的类型和长度-- my_table是pl/sql表变量-- sp_table(0)则表示下标为0的元素--使用pl/sql编写一个过程,可以输入部门编号,并显示该部门所有员工姓名和工资。
create or replace procedure pro9(in_deptno number) is--先定义一个游标变量类型typezxp_emp_cursor is ref cursor;--定义一个游标变量v_emp_cursorzxp_emp_cursor;--定义两个变量v_enameemp.ename%type;v_salemp.sal%type;v_empnoemp.empno%type;begin--执行语句open v_emp_cursor for select ename,sal,empno from emp where deptno=in_deptno;--取出游标中的数据loopfetchv_emp_cursor into v_ename,v_sal,v_empno;--判断当前游标是否到达最后exit when v_emp_cursor%notfound;--输出dbms_output.put_line('雇员编号'||v_empno||'用户名:'||v_ename||'薪水:'||v_sal);end loop;--关闭游标closev_emp_cursor;end;/--流程控制部分--编写一个过程,可以输入一个雇员名,如果该雇员的工资低于2000,就给该雇员工资增加10%。