輸入一個數字,根據這個數是奇數還是偶數
如果這個數是奇數,則打印出 這個數的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;