输入一个数字,根据这个数是奇数还是偶数
如果这个数是奇数,则打印出 这个数的3次方的结果,比如 3 ,则打印出9 ,5 则打印出 125
如果这个数是偶数,则打印出 这个数的2次方的结果,比如 2 ,则打印出4 ,10则打印出 100
如果是 0 的话 ,则打印出 1024
解题方法:
DECLARE
X NUMBER(10) := &请输入一个数字;
SQ NUMBER(10);
BEGIN
IF X = 0 THEN
SQ := 1024;
ELSIF MOD(X, 2) = 1 THEN
SQ := POWER(X, 3);
ELSE
SQ := POWER(X, 2);
END IF;
DBMS_OUTPUT.PUT_LINE(X || ' ' || SQ);
END;
方法二:
DECLARE
X NUMBER(10) :=&输入正整数;
BEGIN
IF X=0 THEN
DBMS_OUTPUT.put_line ('输入数字是 :'|| X || ' 1024');
ELSIF MOD(X,2) != 0 THEN
DBMS_OUTPUT.put_line ('输入数字是 :'|| X || '是一个奇数'||'它的三次方为 :'|| POWER(X,3));
ELSIF MOD(X,2) = 0 THEN
DBMS_OUTPUT.put_line ('输入数字是 :'|| X || '是一个偶数'||'它的二次方为 :'|| POWER(X,2));
END IF ;
END;
输入 三个大于0的数 ,a , b, c 判断 这2个数作为边长能否组成三角形
如果 两边之和大于第三边 则打印出这三个数可以组成三角形。 – 条件1
满足条件1的情况下
如果 2边相等,则打印 组成等腰三角形
如果 两三边相等,则打印出这是一个等边三角形
否则 打印出 无法组成三角形。
解题方法一:
DECLARE
A NUMBER(7) := &请输入边长A;
B NUMBER(7) := &请输入边长B;
C NUMBER(7) := &请输入边长C;
BEGIN
IF (A + B) <= C OR (A + C) <= B OR (B + C) <= A THEN
DBMS_OUTPUT.PUT_LINE('无法组成三角形');
ELSIF A = B AND A = C THEN
DBMS_OUTPUT.PUT_LINE('这是一个等边三角形'); -- 判断等边和等腰的情况下,优先判断等边
ELSIF A = B OR B = C OR A = C THEN
DBMS_OUTPUT.PUT_LINE('这是一个等腰三角形'); -- 如果先判断等腰三角形,那么就无法判断出等边三角形了。
ELSE
DBMS_OUTPUT.PUT_LINE('组成一个普通三角形');
END IF;
END;
解题方法二:
DECLARE
a NUMBER(8) :=&请输入一个正整数a;
b NUMBER(8) :=&请输入一个正整数b;
c NUMBER(8) :=&请输入一个正整数c;
BEGIN
IF (a+b>c AND a+c>b AND b+c>a)AND (a=b AND a=c AND b=c) THEN
dbms_output.put_line('这三个数可以组成等边三角形');
ELSIF (a+b>c AND a+c>b AND b+c>a) AND (a=b OR a=c OR b=c) THEN
dbms_output.put_line('这三个数可以组成等腰三角形');
ELSIF a+b>c AND a+c>b AND b+c>a THEN
dbms_output.put_line('这三个数可以组成三角形');
ELSE
dbms_output.put_line('这三个数无法组成三角形');
END IF;
END;
100-1000之间的所有奇数之和
解题方法一:
DECLARE
x NUMBER(10) :=101;
y NUMBER(10) :=0;
BEGIN
WHILE x<1000 LOOP
y :=x+y;
x :=x+2;
END LOOP;
dbms_output.put_line(y);
END;
方法二:
DECLARE
x NUMBER(10) :=101;
y NUMBER(10) :=0;
BEGIN
FOR x IN 100 .. 1000 LOOP
IF MOD(x,2)=1 THEN
y:=y+x;
END IF;
END LOOP;
dbms_output.put_line(y);
END;
解题方法三:
DECLARE
SUMJ NUMBER(10);
S NUMBER(8);
J NUMBER(8) ;
BEGIN
FOR S IN 100 .. 1000 LOOP
IF MOD(S,2) != 0 THEN DBMS_OUTPUT.put_line('结果是:'||S);
J := S;
SUMJ := J + SUMJ;
END IF;
END LOOP;
DBMS_OUTPUT.put_line('结果是:'||SUMJ);
END;
求100…999之间的所有水仙花数(个位数的3次方 + 十位数的3次方 + 百位数的三次方 = 这个数值本身)
最佳解题方法:
DECLARE
x NUMBER(1);
y NUMBER(1);
z NUMBER(1);
BEGIN
FOR x IN 1..9 LOOP -- 百位
FOR y IN 0..9 LOOP -- 十位
FOR z IN 0..9 LOOP --个位
IF POWER(x,3)+POWER(y,3)+POWER(z,3) =x*100+y*10+z
THEN dbms_output.put_line(x*100+y*10+z);
END IF;
END LOOP;
END LOOP;
END LOOP;
END;
解题方法二:
DECLARE
X NUMBER(10):=100;
a NUMBER(2);
b NUMBER(2);
c NUMBER(2);
BEGIN
WHILE X <=999 LOOP
a:=TRUNC(X/100);
b:=TRUNC((X-a*100)/10);
c:= X-a*100-b*10;
IF X=POWER(a,3)+POWER(b,3)+POWER(c,3)
THEN DBMS_OUTPUT.PUT_LINE(X);
END IF;
X:=X+1;
END LOOP;
END;
要求:sno能被3整除,gender为男,其余为女
sno 被3整除余1,姓张;被3整除余2,姓王;能被3整除,姓李
解题方法:
BEGIN
FOR X IN 1..100 LOOP
INSERT INTO STU
VALUES (X ,
CASE WHEN MOD(X,3) = 0 THEN '李'||X
WHEN MOD(X,3) = 1 THEN '张'||X
ELSE '王'||X END ,
DECODE(MOD(X,3) ,0,'男','女'));
END LOOP;
COMMIT;
END ;
解题方法二:
CREATE TABLE STU (SNO NUMBER(10),
SNAME VARCHAR2(10),
GENDER VARCHAR2(10));
SELECT * FROM STU;
DECLARE
x NUMBER(5) :=1;
BEGIN
FOR x IN 1..100 LOOP
IF MOD(x,3) = 0 THEN
INSERT INTO STU (SNO,GENDER)VALUES(x,'男');
ELSE INSERT INTO STU (SNO,GENDER)VALUES(x,'女');
END IF;
IF MOD(x,3)=1
THEN UPDATE STU SET sname='张' WHERE sno = x;
ELSIF MOD(X,3)=2
THEN UPDATE STU SET SNAME='王' WHERE SNO=x;
ELSE
UPDATE STU SET SNAME='李' WHERE SNO=x;
END IF ;
END LOOP;
END;
输入一个数,判断它的奇偶性, 打印出 您输入的数字是 xx,它是一个 奇/偶数
解题方法:
--SELECT MOD(4,2) FROM DUAL;
DECLARE
X NUMBER(10) :=&请输入一个正整数 ;
BEGIN
IF MOD(X,2) = 0 THEN
DBMS_OUTPUT.PUT_LINE('您输入的数字是:'|| X ||',它是一个 偶数');
ELSE
DBMS_OUTPUT.PUT_LINE('您输入的数字是:'|| X ||',它是一个 奇数');
END IF ;
END ;
根据员工的入职时间打印出员工的 转正日期和社保缴纳如期,
如果入职日期是10号之前,则当月缴纳,反之则次月开始缴纳,打印出 社保缴纳的 年和月
如果是12月10号之后日志的员工,次月缴纳时,为次年的1月份。
解题方法一:
SELECT TO_CHAR(TO_DATE('20191211','YYYY/MM/DD'),'YYYY-MM') ,
TO_CHAR(ROUND(TO_DATE('20191211','YYYY/MM/DD')+5,'MM'),'YYYY-MM') FROM DUAL
DECLARE
CURSOR c_emp
IS
SELECT e.hiredatE ,
to_char(add_months(e.hiredate,6),'yyyy-mm-dd') 转正日期,
to_char(ROUND(E.hiredate + 5 ,'MM'),'yyyy-mm') 社保缴纳日期
FROM emp e;
v_cemp c_emp%ROWTYPE;
BEGIN
FOR v_cemp IN c_emp LOOP
dbms_output.put_line('入职日期:'||to_char(v_cemp.hiredate,'YYYY/MM/DD')||' '
||v_cemp.转正日期||' '||v_cemp.社保缴纳日期);
END LOOP;
END;
解题方法二:
DECLARE
CURSOR C_EMP IS
SELECT E.HIREDATE,
ADD_MONTHS(E.HIREDATE,6) ZZDATE,
/*TO_CHAR(E.HIREDATE,'DD') DD,*/
ROUND(E.HIREDATE,'MM')NEXTMM,
TRUNC(E.HIREDATE,'MM')DMM,
TO_NUMBER(TO_CHAR(E.HIREDATE,'DD')) DD
FROM EMP E;
V_CEMP C_EMP%ROWTYPE;
BEGIN
FOR V_CEMP IN C_EMP LOOP
IF V_CEMP.DD > 10 THEN
DBMS_OUTPUT.PUT_LINE('入职时间: '||to_char(V_CEMP.HIREDATE,'yyyy/mm/dd') ||' '||'转正时间:'|| to_char(V_CEMP.ZZDATE,'yyyy/mm/dd')
||' 购买社保时间:'|| TO_CHAR(V_CEMP.NEXTMM,'YYYY/MM'));
ELSIF V_CEMP.DD <=10 THEN
DBMS_OUTPUT.PUT_LINE('入职时间: '||to_char(V_CEMP.HIREDATE,'yyyy/mm/dd') ||' '||'转正时间:'|| to_char(V_CEMP.ZZDATE,'yyyy/mm/dd')
||' 购买社保时间:'|| TO_CHAR(V_CEMP.DMM,'YYYY/MM'));
END IF;
END LOOP;
END;
打印出各个部门的人数(包括部门编号为40),打印结果为:
部门10的员工:
AAA
…
部门20的员工:
XXX
…
部门30的员工:
XXX
…
部门40的员工:
DECLARE
CURSOR C_ED(P_DEPTNO NUMBER) IS --定义游标
SELECT wm_concat(E.ENAME) ENAME ,
COUNT(EMPNO)RS
FROM EMP E,DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO
AND E.DEPTNO = D.DEPTNO;
V_CED C_ED%ROWTYPE;--定义游标变量
BEGIN
DBMS_OUTPUT.PUT_LINE('部门10的员工');
FOR V_CED IN C_ED(10) LOOP
DBMS_OUTPUT.PUT_LINE(V_CED.ENAME||' 人数 :'||V_CED.RS);
END LOOP;
DBMS_OUTPUT.PUT_LINE('部门20的员工');
FOR V_CED IN C_ED(20) LOOP
DBMS_OUTPUT.PUT_LINE(V_CED.ENAME||' 人数 :'||V_CED.RS);
END LOOP;
DBMS_OUTPUT.PUT_LINE('部门30的员工');
FOR V_CED IN C_ED(30) LOOP
DBMS_OUTPUT.PUT_LINE(V_CED.ENAME||' 人数 :'||V_CED.RS);
END LOOP;
DBMS_OUTPUT.PUT_LINE('部门40的员工');
FOR V_CED IN C_ED(40) LOOP
DBMS_OUTPUT.PUT_LINE(V_CED.ENAME||' 人数 :'||V_CED.RS);
END LOOP;
END ;
打印出各个部门的员工(包括部门编号为40),打印结果为:
部门10的员工:
AAA
…
部门20的员工:
XXX
…
部门30的员工:
XXX
…
部门40的员工:
左外关联
DECLARE
CURSOR C_DEPT IS
SELECT DEPT.DEPTNO ,
COUNT(EMP.EMPNO) CT
FROM DEPT LEFT JOIN EMP
ON EMP.DEPTNO = DEPT.DEPTNO
GROUP BY DEPT.DEPTNO
ORDER BY DEPT.DEPTNO;
CURSOR C_EMP IS
SELECT DEPTNO,
ENAME,
COUNT(1) OVER(PARTITION BY DEPTNO) CT
FROM EMP;
V_CDEPT C_DEPT%ROWTYPE;
V_CEMP C_EMP%ROWTYPE;
BEGIN
FOR V_CDEPT IN C_DEPT LOOP
DBMS_OUTPUT.PUT_LINE('部门' || V_CDEPT.DEPTNO || '的员工:');
DBMS_OUTPUT.PUT_LINE( ' 人数为'||V_CDEPT.CT);
FOR V_CEMP IN C_EMP LOOP
IF V_CEMP.DEPTNO = V_CDEPT.DEPTNO THEN
DBMS_OUTPUT.PUT_LINE(' ' || V_CEMP.ENAME);
END IF;
END LOOP;
END LOOP;
END;
**右外关联**
DECLARE
CURSOR C_ED IS
SELECT D.DEPTNO, COUNT(E.DEPTNO) RS
FROM EMP E
RIGHT JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
GROUP BY D.DEPTNO;
V_CED C_ED%ROWTYPE;
BEGIN
FOR V_CED IN C_ED LOOP
DBMS_OUTPUT.PUT_LINE(V_CED.DEPTNO || ' ' || V_CED.RS);
END LOOP;
END;
按照salgrade表中的标准,给员工加薪,1:5%,2:4%,3:3%,4:2%,5:1%,打印出每个人,加薪前后的工资。
参考答案:
DECLARE
CURSOR C_ES IS
SELECT E.ENAME,
E.SAL,
S.GRADE,
DECODE(S.GRADE, 1,1.05 * E.SAL,
2,1.04 * E.SAL,
3,1.03 * E.SAL,
4,1.02 * E.SAL,
5,1.01 * E.SAL) NSAL
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;
V_CES C_ES%ROWTYPE;
BEGIN
FOR V_CES IN C_ES LOOP
DBMS_OUTPUT.PUT_LINE(V_CES.ENAME || ' ' || V_CES.SAL || ' ' ||V_CES.GRADE|| ' ' ||V_CES.NSAL);
END LOOP;
END;
编写一个PL/SQL程序块,从emp表中对名字以"A"或"S"开始的所有雇员
按他们基本薪水的10%给他们加薪,
打印出员工的姓名,薪水,加薪后的薪水。
参考答案:
DECLARE
CURSOR c_emp
IS
SELECT e.ename,
e.sal,
E.SAL*1.1 nsal
FROM emp e
WHERE E.ename LIKE 'A%' OR E.ename LIKE 'S%';
v_cemp c_emp%ROWTYPE;
BEGIN
FOR v_cemp IN c_emp LOOP
dbms_output.put_line(v_cemp.ename||' '||v_cemp.sal||' '||v_cemp.nsal);
END LOOP;
END;
建个目标表 EMP_SALES (DEPTNO ,DNAME ,SAL_L1,SAL_L2,SAL_L3,mark) SAL_L1 ~ SAL_L3 分别对应工资排名前1~3
检查字段,要求使用 序列实现。
编写存储过程,使用全量同步的方式,更新目标表 EMP_SALES
CREATE TABLE EMP_SALES (
DEPTNO VARCHAR2(20),
DNAME VARCHAR2(20),
SAL_L1 NUMBER(7,2),
SAL_L2 NUMBER(7,2),
SAL_L3 NUMBER(7,2),
MARK NUMBER(10));
CREATE SEQUENCE SE1 /*INCREMENT BY 1 START WITH 1*/;
CREATE OR REPLACE PROCEDURE SP_SALES
IS
V_MARK NUMBER(10);
BEGIN
V_MARK := SE1.NEXTVAL; -- MARK 检查字段
DELETE FROM EMP_SALES WHERE 1=1;
INSERT INTO EMP_SALES
(DEPTNO,
DNAME,
SAL_L1,
SAL_L2,
SAL_L3,
MARK) -- MARK 检查字段
SELECT DEPTNO,
MAX(DNAME),
MAX(DECODE(RN, 1, SAL)) SAL_L1,
MAX(DECODE(RN, 2, SAL)) SAL_L2,
MAX(DECODE(RN, 3, SAL)) SAL_L3,
V_MARK
FROM (SELECT D.DEPTNO,
D.DNAME,
E.SAL,
ROW_NUMBER() OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL DESC) RN
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO)
GROUP BY DEPTNO;
COMMIT;
END;
BEGIN
SP_SALES;
END;
假设有100块钱,打算买100只鸡,公鸡一只5元,母鸡一只3元,小鸡3只1元,
请问100块钱刚好花完,每种鸡至少买1只,每种鸡各可以买多少只?
通过存储过程 ,打印出所有可能的组合。
参考答案:
CREATE OR REPLACE PROCEDURE SP_J IS
V_GJ NUMBER(2); V_MJ NUMBER(2); V_XJ NUMBER(2);
BEGIN
FOR V_GJ IN 1 .. 20 LOOP
FOR V_MJ IN 1 .. 33 LOOP
FOR V_XJ IN 3 .. 100 LOOP
IF V_GJ + V_MJ + V_XJ = 100 /*数量*/
AND V_GJ * 5 + V_MJ * 3 + V_XJ/3 = 100 /*价格*/
THEN DBMS_OUTPUT.PUT_LINE(V_GJ || ' ' || V_MJ || ' ' || V_XJ);
END IF;
END LOOP;
END LOOP;
END LOOP;
END SP_J;
BEGIN
SP_J;
END;
创建存储过程,根据输入的入职时间范围,
打印出 在这个时间内 各地区工资前2名的员工的姓名,入职时间,工资
CREATE OR REPLACE PROCEDURE SP_D_EMP(P_1 VARCHAR2,
P_2 VARCHAR2)
IS
CURSOR C_EMP
IS
SELECT *
FROM(SELECT D.LOC,
E.HIREDATE,
E.ENAME,
E.SAL,
DENSE_RANK() OVER(PARTITION BY D.LOC ORDER BY E.SAL DESC) RN FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.HIREDATE BETWEEN TO_DATE(P_1, 'YYYY-MM-DD') AND TO_DATE(P_2, 'YYYY-MM-DD')) X WHERE X.RN <= 2;
V_CEMP C_EMP%ROWTYPE;
BEGIN
FOR V_CEMP IN C_EMP LOOP
DBMS_OUTPUT.PUT_LINE(V_CEMP.LOC || ' ' || TO_CHAR(V_CEMP.HIREDATE, 'YYYY-MM-DD') || ' ' || V_CEMP.ENAME || ' ' || V_CEMP.SAL || ' ' || V_CEMP.RN);
END LOOP;
END;
BEGIN
SP_D_EMP('1980-01-01', '1981-06-06');
END;
创建一个存储过程,以员工号和部门号作为参数,修改员工所在的部门为所输入的部门号。??
如果修改成功,则显示“员工由……号部门调入调入……号部门”; – ① 原部门 新部门,
如果不存在该员工,则显示?? – ② 判断员工编号或者部门要输入正确,否则就不会判断 ① 条件
“员工号不存在,请输入正确的员工号。”;
如果不存在该部门,则显示??
“该部门不存在,请输入正确的部门号。”。
CREATE OR REPLACE PROCEDURE SP_EMPNO_DEPT(P_EMPNO IN OUT NUMBER,
P_DEPTNO IN NUMBER)
IS
V_EMPNO NUMBER(4);
V_DEPTNO1 NUMBER(2);
V_DEPTNO2 NUMBER(2);
V_CTEMPNO NUMBER(20);
V_CTDNO NUMBER(20);
BEGIN
SELECT COUNT(1)
INTO V_CTEMPNO
FROM EMP
WHERE EMPNO = P_EMPNO;
IF V_CTEMPNO = 0
THEN DBMS_OUTPUT.PUT_LINE('员工号不存在,请输入正确的员工号。');
ELSE
SELECT COUNT(1)
INTO V_CTDNO
FROM DEPT
WHERE DEPTNO = P_DEPTNO;
IF V_CTDNO = 0
THEN DBMS_OUTPUT.PUT_LINE('该部门不存在,请输入正确的部门号。');
ELSE
SELECT DEPTNO
INTO V_DEPTNO1
FROM EMP
WHERE EMPNO = P_EMPNO;
UPDATE EMP SET DEPTNO = P_DEPTNO WHERE EMPNO = P_EMPNO;
SELECT DEPTNO /*,EMPNO*/
INTO V_DEPTNO2 /*,V_EMPNO*/
FROM EMP
WHERE EMPNO = P_EMPNO;
END IF;
END IF;
DBMS_OUTPUT.PUT_LINE('员工' || P_EMPNO || '由' || V_DEPTNO1 || '号部门调入调入' || V_DEPTNO2 || '号部门');
END;
调用存储过程
DECLARE V_EMPNO NUMBER(4) := 7788;
BEGIN
SP_EMPNO_DEPT(V_EMPNO, 40);
END;
SELECT * FROM EMP WHERE EMPNO = 7788;
– 输入员工的姓名,打印出员工的工作和工资;
– 输入部门编号,打印出部门的最高,最低,平均工资
– 输入员工的工号 ,打印出员工的姓名,工资,工资等级
– 输入员工的工号,打印出员工所在部门的最高工资。
– 输入员工的姓名,打印出员工的姓名,月薪,年薪
------------------------------------------------------------------------------------------------------------------
– 使用 %TYPE 的方式实现,输入一个 员工编号,打印出 员工的工作和提成。
– 使用 %ROWTYPE 实现,输入员工的姓名,打印出 员工的部门名称和所在部门人数。
– 使用 %ROWTYPE 实现,输入员工的编号,打印出员工所在部门工资排名第二的员工的姓名和工资。
– 使用 %ROWTYPE 实现,输入员工的编号,打印出 员工姓名,部门名称,工资等级
– 使用 %ROWTYPE 实现,不输入任何信息,调用PLSQL块,则打印出 员工表中 工资第四高的员工姓名,工资,以及排名。
------------------------------------------------------------------------------------------------------------------
– 接收员工的姓名,打印出员工的部门名称,工资。
– 接受员工的姓名,打印出该员工所在部门的名称,最高工资和最低工资。
– 接受员工的部门编号,打印出员工所在部门经理的 姓名,工作,工资。
– 接受一个员工的姓名,打印出名字长度跟该员工相同员工的 人数,最高工资,平均工资(保留2位小数)。
– 接受员工的工资等级,打印出该工资等级中工资最高的员工姓名,工资,工资等级
– 查出部门人数为空的部门的部门编号,部门名称。
–输入员工编号,如果员工的工资高于公司平均工资,则加薪10% ,反之加薪20%,打印出公司平均工资,员工的工资,加薪后的工资。
–输入一个数,判断它的奇偶性, 打印出 您输入的数字是 xx,它是一个 奇/偶数。
–输入员工的姓名,如果员工的工资等级是1 , 则给员工加薪1000,工资等级是 2 加 1500 ,
–等级为3 加2000 ,等级为4 加 2500 ,等级为5 加5000. 打印出 员工的姓名 ,工资,工资等级,加薪后的工资。
–编写一个程序块,根据输入的编号对emp表中对雇员按照他的基本薪水sal的10%加薪.所增加后的薪水大于5000,输出信息’不予加薪‘;
输入员工编号,
如果员工的工资高于公司平均工资,则加薪10% ,反之加薪20%,
打印出公司平均工资,员工的工资,加薪后的工资。
输入员工的姓名,如果员工的工资等级是1 , 则给员工加薪1000,工资等级是 2 加 1500 ,
等级为3 加2000 ,等级为4 加 2500 ,等级为5 加5000. 打印出 员工的姓名 ,工资,工资等级,加薪后的工资。
–输入员工的编号,打印出跟该员工在同一个部门的其余员工的姓名,工作,工资,部门编号。
–输入一个工资等级编号,打印出该工资等级的所有员工的姓名,工资,工资等级
编写一个程序块,将emp表中前5人的名字,及其出的工资等级(salgrade)显示出来
– 1 编写存储过程检查如果已经雇佣该雇员超过60个月,则给他额外加薪3000.
– 2 传入一个数值(IN),把工资大于这个数值的员工姓名输出
– 3 创建一个存储过程,以员工号为参数(IN OUT),输出该员工的工资
– 4 创建一个存储过程,以部门号为参数(OUT),输出入职日期最早的10个员工的姓名,入职日期
– 5 创建一个存储过程,以前多少名的数为参数,输入工资最高的前几个(参数值)员工的信息。
------------------------------------------------------------------------------------------------------------------