oracle函數及存儲過程

計算一個數的兩倍後返回
  CREATE OR REPLACE FUNCTION f_double
  (
  v_number NUMBER
  )
  RETURN NUMBER
  IS
  v_num NUMBER;
  BEGIN
  v_num :=v_number*2;
  RETURN v_num;
  END;

 

--刪除指定工號的員工,如果該員工所在部門人數少於3,則不能刪除
  CREATE OR REPLACE PROCEDURE sp_del
  (
  p_number emp.empno%TYPE
  )
  IS
  v_count NUMBER;
  BEGIN
  SELECT COUNT(*) INTO v_count FROM emp WHERE deptno=(
  SELECT deptno FROM emp WHERE empno=p_number
  );
  IF (v_count<3) THEN
  raise_application_error(-20093,'該部門人數太少');
  ELSE
  EXECUTE IMMEDIATE 'DELETE FROM emp WHERE empno='||p_number;
  --COMMIT;
  END IF;
  END;
  SELECT * FROM emp;
  CALL sp_del(7839);
  SELECT * FROM dept

 

1、存儲過程和函數的區別。
(1)、存儲過程是作爲PL/SQL語句執行,而函數是作爲表達式的一部分調用;
(2)、存儲過程在規格說明中不包含return語句,而在函數的規格說明這包含return子句;
(3)、存儲過程不返回值,而函數必須返回值;
(4)、在存儲過程中可以包含return語句,但不返回任何值,他只表示退出存儲過程,而函數中必須包含一個return語句;
2、觸發器分爲事前觸發和事後觸發,這兩種觸發有何區別。語句級觸發和行級觸發有何區別。
事前觸發是在數據沒有寫入數據庫時就觸發,而事後觸發是在把數據寫入數據庫後再觸發
語句級觸發值所有的相同的語句只觸發一次,而行級觸發是每執行一條語句就觸發一次。
3、根據students表(stuID,stuName,stuSex,stuAge,stuTel)編寫一個存儲過程,將students表中的學生ID號傳遞給這一過程,並向調用應用程序返回學生的姓名和電話號碼。再編寫一個具有過程調用的匿名塊。
存儲過程
create or replace procedure pro_stu(id in number,stuname out varchar2,
stutel out varchar2) as
begin
select A.stuname,A.stutel into stuname,stutel from students A
where A.stuid=id;
end pro_stu;
匿名塊:
declare
stuid number(3);
stuname varchar2(12);
stutel varchar2(15);
begin
stuid:=&stuid;
pro_stu(stuid,stuname,stutel);
DBMS_OUTPUT.PUT_LINE('姓名:' || stuname);
DBMS_OUTPUT.PUT_LINE('電話:' || stutel);
EXCEPTION
when NO_DATA_FOUND then
DBMS_OUTPUT.PUT_LINE('未找到符合條件的數據!!');
end;
4、在顯示遊標上可以執行哪些操作?舉例說明每一種語句的作用。
*聲明遊標
*打開遊標
*提取遊標
*關閉遊標
5、集合運算符INTERSECT的用途是什麼?
可以用來查詢兩個查詢結果中相同的部分
6、找出與John Smith在相同的部門工作的僱員信息。
select A.* from employee A where deptid =(
select B.deptid from employee B where B.fname='john' and B.lname='smith') and
A.fname<>'john' and A.lname<>'smith'
7、通過一個外部連接,顯示僱員名和部門信息。
select A.fname||'--'||A.lname as 僱員名,B.* from employee A,dept B
where A.deptid(+)=B.deptid;
8、抽取Employee表中按FNAME的字母順序的第2條記錄開始的3條記錄的SQL語句。
select A.lname from (select rownum as rn, B.* from employee B order by
B.fname) A where rn>=2 and rn<5
9、INSERT ALL和INSERT FIRST語句的用途是什麼?
Insert all 是向所以符合條件的表中插入數據;
Insert first 當有多個符合條件的時只向第一個中插入數據
10、使用多層子查詢顯示FINANCE部門的僱員的親屬信息。
select A.* from Dependent A where A.employeeid in(
select B.employeeid from employee B where B.deptid in(
select C.deptid from dept C where C.detpname='Finance'))
11、編寫一個PL/SQL 程序,包括兩個變量,分別用於姓和名,顯示完整的姓名,姓和名之間用逗號和空格分隔開。
declare
familyname employee.fname%type;
name employee.lname%type;
cursor cur_emp is
select A.fname,A.lname from employee A where 1 = 1;
begin
open cur_emp;
fetch cur_emp into familyname,name;
while cur_emp%FOUND
loop
DBMS_OUTPUT.PUT_LINE('員工的姓名爲:'||familyname||', '||name);
fetch cur_emp into familyname,name;
end loop;
end;
12、使用for循環,以相反的順序顯示10~1。
declare
begin
for num in reverse 1 .. 10
loop
DBMS_OUTPUT.PUT_LINE(num);
end loop;
end;
13、編寫一個PL/SQL塊,要求用戶輸入第一個數字、第二個數字和算術運算符(+、-、*、/)。如果運算符無效,則拋出並處理一個用戶定義的異常。如果第二個數字是零,而且運算符是/,則處理ZERO_DIVIDE預定義的服務器異常。

declare
fnum number(4);
snum number(4);
oper varchar2(4);
result number(6);
nooper EXCEPTION;
begin
fnum:=&fnum;
snum:=&snum;
oper:='&oper';
result:=
case
when '+' then fnum+snum;
when '_' then fnum-snum;
when '*' then fnum*snum;
when '/' then fnum/snum;
else raise nooper;
DBSM_OUTPUT.PUT_LINE(fnum || oper|| snum||'='||result);
EXCEPTION
when nooper then
DBSM_OUTPUT.PUT_LINE('你輸入了非法操作符!!');
when
ZERO_DIVIDE then
DBMS_OUTPUT.PUT_LINE('除數不能爲零!!');
end;
14、表結構以及數據如下:
CREATE TABLE 表
(ID int, 日期 varchar2(11), 單據 char(3))
INSERT INTO 表 (ID , 日期 , 單據 ) VALUES ( 1 , '2004-08-02' , '001' );
INSERT INTO 表 (ID , 日期 , 單據 ) VALUES ( 2 , '2004-09-02' , '001' );
INSERT INTO 表 (ID , 日期 , 單據 ) VALUES ( 3 , '2004-10-02' , '002' );
INSERT INTO 表 (ID , 日期 , 單據 ) VALUES ( 4 , '2004-09-02' , '002' );
要求:設計一個查詢,返回結果如下:
ID 日期 單據
---------- ----------- ---
1 2004-08-02 001
4 2004-09-02 002
即對於每個單據號,返回日期最小的行。

15、表內容:
2005-05-09 勝
2005-05-09 勝
2005-05-09 負
2005-05-09 負
2005-05-10 勝
2005-05-10 負
2005-05-10 負

如果要生成下列結果, 該如何寫sql語句?

勝 負
2005-05-09 2 2
2005-05-10 1 2
Sql腳本:
------------------------------------------
create table #tmp(rq varchar2(10),shengfu char(2))

insert into tmp values('2005-05-09','勝')
insert into tmp values('2005-05-09','勝')
insert into tmp values('2005-05-09','負')
insert into tmp values('2005-05-09','負')
insert into tmp values('2005-05-10','勝')
insert into tmp values('2005-05-10','負')
insert into tmp values('2005-05-10','負')

select A.rq,A.負,B.勝 from (select rq, count(*) as 負 from tmp where shengfu='負' group by rq) A
join
(select rq, Count(*) as 勝 from tmp where shengfu='勝' group by rq) B
on
A.rq=B.rq

 

select rq, sum(case when shengfu='勝' then 1 else 0 end)'勝',sum(case when shengfu='負' then 1 else 0 end)'負' from tmp group by rq

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章