第一篇:第5章 視圖、存儲過程和用戶自定義函數復習題范文
第5章 視圖、存儲過程和用戶自定函數
1.什么是基本表?什么是視圖?兩者的區別和聯系是什么?
答:
基本表是本身獨立存在的表,在 sQL 中一個關系就對應一個表。視圖是從一個或幾個基本表導出的表。視圖本身不獨立存儲在數據庫中,是一個虛表。即數據庫中只存放視圖的定義而不存放視圖對應的數據,這些數據仍存放在導出視圖的基本表中。視圖在概念上與基本表等同,用戶可以如同基本表那樣使用視圖,可以在視圖上再定義視圖。.試述視圖的優點。
答
(l)視圖能夠簡化用戶的操作;(2)視圖使用戶能以多種角度看待同一數據;(3)視圖對重構數據庫提供了一定程度的邏輯獨立性;(4)視圖能夠對機密數據提供安全保護。.所有的視圖是否都可以更新?為什么?
答:
不是。視圖是不實際存儲數據的虛表,因此對視圖的更新,最終要轉換為對基本表的更新。因為有些視圖的更新不能惟一有意義地轉換成對相應基本表的更新,所以,并不是所有的視圖都是可更新的.4 .哪類視圖是可以更新的?哪類視圖是不可更新的?各舉一例說明。
答:基本表的行列子集視圖一般是可更新的。若視圖的屬性來自集函數、表達式,則該視圖肯定是不可以更新的。
5.教材P89習題1-5。
第二篇:SQL Sever 2005教案第13章 存儲過程及自定義函數
什么是存儲過程,在存儲在服務器上的T-SQL語句的命名集合,是封裝性任務的方法,支持變量及條件的編程。
SQL Server的存儲過程與其他編程語言中的過程(包括函數)類似,可以包含數據庫操作(調用其他過程)的編程語句,可以接受參數,可以返回狀態值以表明成功或失敗,以輸出參數的形式將多個值返回至調用過程
SQL Server支持五種類型的存儲過程:
系統存儲過程(sp_):存儲在master數據庫中。
本地存儲過程:在單獨的用戶數據庫中。
臨時存儲過程:局部的以#開頭,全局的以##開頭。
遠程存儲過程:分布式查詢支持此功能。
擴展存儲過程:在SQL Server環境外執行。
存儲過程的優點 封裝商務邏輯,若規則或策略改變只需修改存儲過程就可以直接使用,屏蔽數據庫的詳細資料,用戶不需要訪問底層數據庫和數據庫對象。提供安全機制,只需要提供存儲過程的權限而不需要提供整個數據庫中數據的一個權限。另外,存儲過程能夠通過預編譯的語句來確定執行哪一部分而不是都執行。在傳輸過程中傳輸的存儲過程而不是數據,減少了通信量,能夠實現一個較快的執行速度。
create proc liuhaoran as select price from titles where price>15 select title from titles where price<=15
在存儲過程里可以包含任何數目和類型的T-SQL語句,但不能包含create proc、create trigger、create view 執行創建存儲過程的用戶必須是sysadmin、db_owner 或 db_ddladmin角色的成員,或必須擁有 CREATE PROCEDURE 權限 存儲過程有大小的限制,最大為128M
存儲過程可以傳遞參數,創建存儲過程,定義兩個浮點型的參數,無返回值 CREATE PROCEDURE titlespro @Beginningprice float,@Endingprice float AS IF @Beginningprice IS NULL OR @Endingprice IS NULL BEGIN
print 'no price is exits'
RETURN END SELECT price FROM titles WHERE price BETWEEN @Beginningprice AND @Endingprice GO
/*執行語句,輸入兩個價格值作為參數值*/ exec titlespro 10,19
指定參數的依據和指導原則
所有的輸入參數值都應該在存儲過程開始的時候進行檢查,以盡早捕獲缺失值和非法值
應該為參數提供合適的默認值,可以未指定參數值的基礎上執行存儲過程
一個存儲過程最多可以有1024個參數
不同存儲過程可以使用相同的參數名 使用參數的指導原則
可以使用@參數=值的格式來指定參數,此方法可以按任意順序來傳遞參數
對于有默認值的參數在調用存儲過程的過程中可以不指定參數值
存儲過程可以使用輸出參數
--創建存儲過程輸入兩個輸入參數,定義一個輸出參數 CREATE PROCEDURE Mathadd @m1 int, @m2 int, @result int OUTPUT--定義輸出參數 AS SET @result=@m1+@m2 GO
調用過程如下:
declare @resultvalues int
exec mathadd 12,16,@resultvalues output--輸出參數的值賦給變量 print 'The result is: '+convert(char,@resultvalues)
存儲過程通過輸出參數向調用它的存儲過程或客戶端返回信息,通過輸出參數,存儲過程的運行結果可以保留到程序運行結束。輸出參數接受需要注意:
調用語句必須包含一個變量名,以接受返回值。
可以在T-SQL語句中使用返回變量 輸出參數可以是任意類型,除了text和image 輸出參數可以是游標
對于已經創建好的存儲過程,如果存儲過程需要修改,可以顯式地重新編譯,但應盡量少做。
在創建存儲過程之前通常會檢查此存儲過程是否存在,如果存在可以選擇刪除后重建,或改變名字
IF EXISTS(SELECT name FROM sysobjects WHERE name='author_infor' AND type='p')DROP PROCEDURE author_infor GO
修改存儲過程使用關鍵字alter
alter procedure pro_titles @values money--修改存儲過程pro_titles as select price,pub_id from titles where price=@values go
刪除存儲過程使用關鍵字drop proc,因為存儲過程屬于數據庫對象
drop procedure pro_titles
對于數據庫中的所有存儲過程或者觸發器,如果需要將其全部重新編譯,那么可以使用以下語句,EXEC sp_recompile titles--重新編譯所有的存儲過程或者觸發器
在程序中通常會出現因為運行錯誤而出現的各種錯誤提示,其大部分都不能被用戶容易讀懂,因此可以自定義錯誤信息,來提示用戶錯誤的具體原因。--自定義錯誤信息
EXEC sp_addmessage
@msgnum = 50010,---錯誤編號 @severity = 10,----嚴重級別
@msgtext = 'Customer cannot be deleted.',--錯誤文本信息 @with_log='true', @lang='us_english'
創建好自定義錯誤信息之后,就可以在程序中使用錯誤信息
--調用自定義錯誤信息
EXEC sp_addmessage 50010,10,'CustomerID not found.',@replace='replace' USE Northwind GO CREATE PROC UpdateCustomerPhone @CustomerID nchar(5)=NULL, @Phone nvarchar(24)=NULL AS IF @CustomerID IS NULL BEGIN
PRINT 'You must supply a valid CustomerID.'
RETURN END /*確認提供了合法的CustomerID */ IF NOT EXISTS(SELECT * FROM Customers WHERE CustomerID=@CustomerID)
BEGIN
RAISERROR(50010,10,1)--該客戶不存在。
RETURN
END BEGIN TRANSACTION UPDATE Customers SET Phone =@Phone WHERE CustomerID=@CustomerID /*顯示CompanyName的電話號碼已更新的消息*/ SELECT 'The phone number for'+@CustomerID +'has been updated to'+ @Phone COMMIT TRANSACTION GO
創建存儲過程的方法上面已經介紹結束,如果想要查看存儲過程的代碼,就需要使用到以下的關鍵字
--查看存儲過程
EXEC sp_helptext UpdateCustomerPhone
而對于以存在的存儲過程,在調用的過程由于某些原因需要重新命名的化,使用以下語句
--重命名存儲過程
EXEC sp_rename reptq1, newproc
用戶自定義函數部分
函數和存儲過程同樣都有輸入和輸出參數,單數輸入和輸出參數的聲明方式有些區別--創建函數 USE pubs go CREATE FUNCTION WorkYearWage(@hiredate datetime,--hiredate 表示雇傭日期
@today datetime, @per_wage money)--today 表示當前的日期per_wage 表示每一年工齡應得的工資額 RETURNS money--返回值類型 AS BEGIN DECLARE @WorkYearWage money SET @WorkYearWage =(year(@today)-year(@hiredate))*@per_wage RETURN(@WorkYearWage)--返回的變量 END--結束函數定義 GO-
使用函數參數,當使用命名函數的時候,參數的次序不必按照在函數中聲明的次序,但必須包含所有參數,不能省略任何參數
使用函數的過程同以前學習過的系統函數的使用方法想類似,在輸出或查詢語句中使用函數名及相應的床底若干參數即可。
--使用函數
SELECT pubs.dbo.workyearwage('1991-7-1',getdate(),15)--傳參并輸出結果
As work_year_wage
在函數的返回值方面可以直接聲明返回參數,或者聲明返回值類型--計算立方體函數
CREATE FUNCTION CubicVolume(@CubeLength decimal(4,1), @CubeWidth decimal(4,1), @CubeHeight decimal(4,1))--定義輸入參數 RETURNS decimal(12,3)--定義返回值類型 AS BEGIN RETURN(@CubeLength * @CubeWidth * @CubeHeight)--返回結果 END
除特定類型的返回值之外,還可以返回表類型的結果集
--內聯表值型用戶自定義函數
CREATE FUNCTION orderfirms(@productid INT)--定義一個整型參數 RETURNS TABLE--返回值為表的結果集 AS RETURN(SELECT * FROM jobs WHERE min_lvl>@productid)--返回查詢結果 GO
或者返回值是一張臨時表
--多聲明表值型用戶自定義函數 USE Northwind go CREATE FUNCTION my_function(@regionParameter varchar(25))--定義一個函數的參數
returns @my_table TABLE--函數返回值為表的結果集,并定義表的結果集如下(city varchar(15)null, companyName varchar(40)not null, contactName varchar(30)null)AS BEGIN INSERT @my_table--從表customers中查詢數據插入到@my_table中 SELECT city,companyName,contactName FROM Customers WHERE city=@regionParameter RETURN--返回結果集 END
表值函數:
函數體內只允許如下語句:
賦值語句
流程控制語句
用于定義函數局部數據變量和游標的declare語句
Select語句,將其后的表達式將賦予函數的局部變量
游標操作,僅允許使用fetch語句通過into子句給局部變量賦值,不允許使用fetch語句將數據返回到客戶端
針對上面的例子(內嵌表值函數)需要注意的是:
return子句在括號中包含單個select語句,select語句的結果集構成函數所返回的表 函數體不由begin和end分隔
Return指定table作為返回的數據類型
不必定義返回變量的格式,因為它由return子句中的select語句的結果集的格式設置
查看創建用戶自定義函數的方式有兩種 查看特定用戶自定義函數
--查看用戶自定義函數 USE pubs go EXEC sp_helptext my_function--調用存儲過程 GO
查看所有用戶自定義函數
--通過系統表查看用戶自定義函數 use pubs go select name, type, crdate from sysobjects where type='FN'--go
當創建的用戶自定義函數需要修改時,使用如下語句
--修改函數cubicvolume函數
ALTER FUNCTION CubicVolume--這句表示聲明修改用戶自定義函數,其他語句不變
(@CubeLength decimal(4,1), @CubeWidth decimal(4,1))--定義輸入參數 RETURNS decimal(12,3)--定義返回值類型 AS BEGIN RETURN(@CubeLength * @CubeWidth)--返回結果 END 基本語法和創建的類型,只需要將create更改為alter即可
刪除存儲過程,由于存儲過程為數據庫對象因此刪除使用drop drop function cubicvolume
第三篇:NX10用戶自定義成型刀具和刀庫
基于
UGNX10.0用戶自定義成型刀具
1:首先打開圖檔-進入加工模塊-平面銑模塊(mill-planar)
注:進入任意一個加工模塊均可以
2:切換至機床視圖-選擇創建刀具
注:創建刀具類型只能選擇
mill-pianar
3:選擇刀具子類型中的-
MILL_USER_DEFINED
確定
4:用戶定義刀具對話框如下圖、加工區域會出如下刀具
通用的刀具可以通過“段數”
對話框里面的參數創建
5:例如:
A:移除所有“鍛數”里面的所有數值
B:輸入數值、每輸完一組選擇“添加新集”
點一
點二
點三
點四
點五
點六
(LL)直線長度輸入“3”(LA)直線/圓弧起始角輸入“0”
(AR)圓弧半徑輸入“0”(AS)圓弧掃掠輸入“0”
(LL)直線長度輸入“5”(LA)直線/圓弧起始角輸入“90”
(AR)圓弧半徑輸入“5”(AS)圓弧掃掠輸入“-90”
(LL)直線長度輸入“3”(LA)直線/圓弧起始角輸入“0”
(AR)圓弧半徑輸入“0”(AS)圓弧掃掠輸入“0”
(LL)直線長度輸入“6”(LA)直線/圓弧起始角輸入“90”
(AR)圓弧半徑輸入“0”(AS)圓弧掃掠輸入“0”
(LL)直線長度輸入“6”(LA)直線/圓弧起始角輸入“180”
(AR)圓弧半徑輸入“0”(AS)圓弧掃掠輸入“0”
(LL)直線長度輸入“30”(LA)直線/圓弧起始角輸入“90”
(AR)圓弧半徑輸入“0”(AS)圓弧掃掠輸入“0”
6:指定刀路跟蹤點(回轉體刀具可以不用特別指定、在車加工需要指定刀路生
成軌跡的參考點)為圓心。
7:設置刀具其他參數、描述、編號、等至此刀具創建完成、確認即可
8:將刀具創建到刀具庫.輸入庫號如:“fb20161202”選擇”刀具導入至刀具庫”確定
9:根據需要創建“刀柄”“夾持器”等相關參數最后“確定”
10:從刀具庫中調取刀具
選擇“創建刀具”—“庫”
選擇“從庫中調用刀具”—“庫類選擇”—“工具”—“確定”—可以輸入創建的庫號或直接確定
搜索到庫號后選中可以“預覽”查看是否是你想要的刀具-確定調出你要的刀具
11:從刀具庫中刪除創建錯誤刀具
退出
UG、打開
UG安裝路徑如:我安裝在D盤路徑為:D:\Program
Files\Siemens\NX
10.0\MACH\resource\library\tool\metric,文件夾內容如
下:
記事本方式打開:tool_database文件、通過記事本查找功能找到錯誤刀具庫名:
如“fb20161202”刀具
將選中部分全部刪除—保存—退出記事本
將
UG打開重新進入刀具庫-搜索“fb20161202”刀具—刀具已刪除
第四篇:Oracle創建函數和過程
ORACLE PL/SQL編程之六:把過程與函數說透(窮追猛打,把根兒都拔起!)
繼上篇:ORACLE PL/SQL編程之八:把觸發器說透 得到了大家的強力支持,感謝。接下來再下猛藥,介紹下一篇,大家一定要支持與推薦呀~!我也才有動力寫后面的。
本篇主要內容如下:
6.1 引言 6.2 創建函數 6.3 存儲過程 6.3.1 創建過程 6.3.2 調用存儲過程 6.3.3 AUTHID
6.3.4 PRAGMA AUTONOMOUS_TRANSACTION 6.3.5 開發存儲過程步驟 6.3.6 刪除過程和函數 6.3.7 過程與函數的比較
6.1 引言
過程與函數(另外還有包與觸發器)是命名的PL/SQL塊(也是用戶的方案對象),被編譯后存儲在數據庫中,以備執行。因此,其它PL/SQL塊可以按名稱來使用他們。所以,可以將商業邏輯、企業規則寫成函數或過程保存到數據庫中,以便共享。過程和函數統稱為PL/SQL子程序,他們是被命名的PL/SQL塊,均存儲在數據庫中,并通過輸入、輸出參數或輸入/輸出參數與其調用者交換信息。過程和函數的唯一區別是函數總向調用者返回數據,而過程則不返回數據。在本節中,主要介紹:
1. 創建存儲過程和函數。2. 正確使用系統級的異常處理和用戶定義的異常處理。
3. 建立和管理存儲過程和函數。
6.2 創建函數
1.創建函數
語法如下:
CREATE [OR REPLACE] FUNCTION function_name(arg1 [ { IN | OUT | IN OUT }] type1 [DEFAULT value1], [arg2 [ { IN | OUT | IN OUT }] type2 [DEFAULT value1]],......[argn [ { IN | OUT | IN OUT }] typen [DEFAULT valuen]])[ AUTHID DEFINER | CURRENT_USER ] RETURN return_type IS | AS
<類型.變量的聲明部分> BEGIN
執行部分
RETURN expression EXCEPTION 異常處理部分 END function_name;
? IN,OUT,IN OUT是形參的模式。若省略,則為IN模式。IN模式的形參只能將實參傳遞給形參,進入函數內部,但只能讀不能寫,函數返回時實參的值不變。OUT模式的形參會忽略調用時的實參值(或說該形參的初始值總是NULL),但在函數內部可以被讀或寫,函數返回時形參的值會賦予給實參。IN OUT具有前兩種模式的特性,即調用時,實參的值總是傳遞給形參,結束時,形參的值傳遞給實參。調用時,對于IN模式的實參可以是常量或變量,但對于OUT和IN OUT模式的實參必須是變量。
? 一般,只有在確認function_name函數
是新函數或是要更新的函數時,才使用OR REPALCE關鍵字,否則容易刪除有用的函數。
例1.獲取某部門的工資總和:
--獲取某部門的工資總和 CREATE OR REPLACE FUNCTION get_salary(Dept_no NUMBER, Emp_count OUT NUMBER)RETURN NUMBER IS
V_sum NUMBER;BEGIN
SELECT SUM(SALARY), count(*)INTO V_sum, emp_count FROM EMPLOYEES WHERE DEPARTMENT_ID=dept_no;RETURN v_sum;EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('你需要的數據不存在!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END get_salary;
2.函數的調用
函數聲明時所定義的參數稱為形式參數,應用程序調用時為函數傳遞的參數稱為實際參數。應用程序在調用函數時,可以使用以下三種方法向函數傳遞參數:
第一種參數傳遞格式:位置表示法。
即在調用時按形參的排列順序,依次寫出實參的名稱,而將形參與實參關聯起來進行傳遞。用這種方法進行調用,形參與實參的名稱是相互獨立,沒有關系,強調次序才是重要的。
格式為:
argument_value1[,argument_value2 …]
例2:計算某部門的工資總和:
DECLARE
V_num NUMBER;V_sum NUMBER;BEGIN
V_sum :=get_salary(10, v_num);DBMS_OUTPUT.PUT_LINE('部門號為:10的工資總和:'||v_sum||',人數為:'||v_num);END;
第二種參數傳遞格式:名稱表示法。
即在調用時按形參的名稱與實參的名稱,寫出實參對應的形參,而將形參與實參關聯起來進行傳遞。這種方法,形參與實參的名稱是相互獨立的,沒有關系,名稱的對應關系才是最重要的,次序并不重要。
格式為:
argument => parameter [,…]
其中:argument 為形式參數,它必須與函數定
義時所聲明的形式參數名稱相同parameter 為實際參數。
在這種格式中,形勢參數與實際參數成對出現,相互間關系唯一確定,所以參數的順序可以任意排列。例3:計算某部門的工資總和:
DECLARE
V_num NUMBER;V_sum NUMBER;BEGIN
V_sum :=get_salary(emp_count => v_num, dept_no => 10);DBMS_OUTPUT.PUT_LINE('部門號為:10的工資總和:'||v_sum||',人數為:'||v_num);END;
第三種參數傳遞格式:組合傳遞。
即在調用一個函數時,同時使用位置表示法和名稱表示法為函數傳遞參數。采用這種參數傳遞方法時,使用位置表示法所傳遞的參數必須放在名稱表示法所傳遞的參數前面。也就是說,無論函數具有多少個參數,只要其中有一個參數使用名稱表示法,其后所有的參數都必須使用名稱表示法。
例4:
CREATE OR REPLACE FUNCTION demo_fun(Name VARCHAR2,--注意VARCHAR2不能給精度,如:VARCHAR2(10),其它類似 Age INTEGER, Sex VARCHAR2)RETURN VARCHAR2 AS
V_var VARCHAR2(32);BEGIN
V_var := name||':'||TO_CHAR(age)||'歲.'||sex;RETURN v_var;END;
DECLARE
Var VARCHAR(32);BEGIN
Var := demo_fun('user1', 30, sex => '男');DBMS_OUTPUT.PUT_LINE(var);
Var := demo_fun('user2', age => 40, sex => '男');DBMS_OUTPUT.PUT_LINE(var);
Var := demo_fun('user3', sex => '女', age => 20);DBMS_OUTPUT.PUT_LINE(var);END;
無論采用哪一種參數傳遞方法,實際參數和形式參數之間的數據傳遞只有兩種方法:傳址法和傳值法。所謂傳址法是指在調用函數時,將實際參數的地址指針傳遞給形式參數,使形式參數和實際參數指向內存中的同一區域,從而實現參數數據的傳遞。這種方法又稱作參照法,即形式參數參照實際參數數據。輸入參數均采用傳址法傳遞數據。傳值法是指將實際參數的數據拷貝到形式參數,而不是傳遞實際參數的地址。默認時,輸出參數和輸入/輸出參數均采用傳值法。在函數調用時,ORACLE將實際參數數據拷貝到輸入/輸出參數,而當函數正常運行退出時,又將輸出形式參數和輸入/輸出形式參數數據拷貝到實際參數變量中。
3.參數默認值
在CREATE OR REPLACE FUNCTION 語句中聲明函數參數時可以使用DEFAULT關鍵字為輸入參數指定默認值。
例5:
CREATE OR REPLACE FUNCTION demo_fun(Name VARCHAR2, Age INTEGER, Sex VARCHAR2 DEFAULT '男')RETURN VARCHAR2 AS
V_var VARCHAR2(32);BEGIN
V_var := name||':'||TO_CHAR(age)||'歲.'||sex;RETURN v_var;END;
具有默認值的函數創建后,在函數調用時,如果沒有為具有默認值的參數提供實際參數值,函數將使用該參數的默認值。但當調用者為默認參數提供實際參數時,函數將使用實際參數值。在創建函數時,只能為輸入參數設置默認值,而不能為輸入/輸出參數設置默認值。
DECLARE
var VARCHAR(32);BEGIN
Var := demo_fun('user1', 30);DBMS_OUTPUT.PUT_LINE(var);
Var := demo_fun('user2', age => 40);DBMS_OUTPUT.PUT_LINE(var);
Var := demo_fun('user3', sex => '女', age => 20);
DBMS_OUTPUT.PUT_LINE(var);END;6.3 存儲過程
6.3.1 創建過程
建立存儲過程
在 ORACLE SERVER上建立存儲過程,可以被多個應用程序調用,可以向存儲過程傳遞參數,也可以向存儲過程傳回參數.創建過程語法:
CREATE [OR REPLACE] PROCEDURE procedure_name([arg1 [ IN | OUT | IN OUT ]] type1 [DEFAULT value1], [arg2 [ IN | OUT | IN OUT ]] type2 [DEFAULT value1]],......[argn [ IN | OUT | IN OUT ]] typen [DEFAULT valuen])[ AUTHID DEFINER | CURRENT_USER ] { IS | AS } <聲明部分> BEGIN
<執行部分> EXCEPTION <可選的異常錯誤處理程序> END procedure_name;
說明:相關參數說明參見函數的語法說明。
例6.用戶連接登記記錄;
CREATE TABLE logtable(userid VARCHAR2(10), logdate date);
CREATE OR REPLACE PROCEDURE logexecution IS BEGIN
INSERT INTO logtable(userid, logdate)VALUES(USER, SYSDATE);END;
例7.刪除指定員工記錄;
CREATE OR REPLACE PROCEDURE DelEmp(v_empno IN employees.employee_id%TYPE)AS
No_result EXCEPTION;BEGIN
DELETE FROM employees WHERE employee_id = v_empno;IF SQL%NOTFOUND THEN RAISE no_result;END IF;DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'的員工已被刪除!');EXCEPTION WHEN no_result THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:你需要的數據不存在!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END DelEmp;
例8.插入員工記錄:
CREATE OR REPLACE PROCEDURE InsertEmp(v_empno in employees.employee_id%TYPE, v_firstname in employees.first_name%TYPE, v_lastname in employees.last_name%TYPE, v_deptno in employees.department_id%TYPE)AS
empno_remaining EXCEPTION;PRAGMA EXCEPTION_INIT(empno_remaining,-1);/*-1 是違反唯一約束條件的錯誤代碼 */ BEGIN
INSERT INTO EMPLOYEES(EMPLOYEE_ID, FIRST_NAME, LAST_NAME, HIRE_DATE,DEPARTMENT_ID)VALUES(v_empno, v_firstname,v_lastname, sysdate, v_deptno);DBMS_OUTPUT.PUT_LINE('溫馨提示:插入數據記錄成功!');EXCEPTION WHEN empno_remaining THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:違反數據完整性約束!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END InsertEmp;
例9.使用存儲過程向 departments表中插入數據。CREATE OR REPLACE PROCEDURE insert_dept(v_dept_id IN departments.department_id%TYPE, v_dept_name IN departments.department_name%TYPE, v_mgr_id IN departments.manager_id%TYPE, v_loc_id IN departments.location_id%TYPE)IS
ept_null_error EXCEPTION;PRAGMA EXCEPTION_INIT(ept_null_error,-1400);ept_no_loc_id EXCEPTION;PRAGMA EXCEPTION_INIT(ept_no_loc_id,-2291);BEGIN
INSERT INTO departments(department_id, department_name, manager_id, location_id)VALUES
(v_dept_id, v_dept_name, v_mgr_id, v_loc_id);DBMS_OUTPUT.PUT_LINE('插入部門'||v_dept_id||'成功');EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
RAISE_APPLICATION_ERROR(-20000, '部門編碼不能重復');WHEN ept_null_error THEN
RAISE_APPLICATION_ERROR(-20001, '部門編碼、部門名稱不能為空');WHEN ept_no_loc_id THEN
RAISE_APPLICATION_ERROR(-20002, '沒有該地點');END insert_dept;
/*調用實例一: DECLARE ept_20000 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20000,-20000);ept_20001 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20001,-20001);ept_20002 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20002,-20002);BEGIN insert_dept(300, '部門300', 100, 2400);insert_dept(310, NULL, 100, 2400);insert_dept(310, '部門310', 100, 900);EXCEPTION WHEN ept_20000 THEN DBMS_OUTPUT.PUT_LINE('ept_20000部門編碼不能重復');WHEN ept_20001 THEN DBMS_OUTPUT.PUT_LINE('ept_20001部門編碼、部門名稱不能為空');WHEN ept_20002 THEN DBMS_OUTPUT.PUT_LINE('ept_20002沒有該地點');WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('others出現了其他異常錯誤');END;
調用實例二: DECLARE ept_20000 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20000,-20000);ept_20001 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20001,-20001);ept_20002 EXCEPTION;PRAGMA EXCEPTION_INIT(ept_20002,-20002);BEGIN insert_dept(v_dept_name => '部門310', v_dept_id => 310, v_mgr_id => 100, v_loc_id => 2400);insert_dept(320, '部門320', v_mgr_id => 100, v_loc_id => 900);EXCEPTION WHEN ept_20000 THEN DBMS_OUTPUT.PUT_LINE('ept_20000部門編碼不能重復');WHEN ept_20001 THEN DBMS_OUTPUT.PUT_LINE('ept_20001部門編碼、部門名稱不能為空');WHEN ept_20002 THEN DBMS_OUTPUT.PUT_LINE('ept_20002沒有該地點');WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('others出現了其他異常錯誤');END;*/
6.3.2 調用存儲過程
存儲過程建立完成后,只要通過授權,用戶就可以在SQLPLUS、ORACLE開發工具或第三方開發工具中來調用運行。對于參數的傳遞也有三種:按位置傳遞、按名稱傳遞和組合傳遞,傳遞方法與函數的一樣。ORACLE 使用EXECUTE 語句來實現對存儲過程的調用:
EXEC[UTE] procedure_name(parameter1, parameter2…);
例10: EXECUTE logexecution;
例11:查詢指定員工記錄;
CREATE OR REPLACE PROCEDURE QueryEmp(v_empno IN employees.employee_id%TYPE, v_ename OUT employees.first_name%TYPE, v_sal OUT employees.salary%TYPE)AS BEGIN
SELECT last_name || last_name, salary INTO v_ename, v_sal FROM employees WHERE employee_id = v_empno;DBMS_OUTPUT.PUT_LINE('溫馨提示:編碼為'||v_empno||'的員工已經查到!');EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:你需要的數據不存在!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END QueryEmp;--調用
DECLARE
v1 employees.first_name%TYPE;v2 employees.salary%TYPE;BEGIN
QueryEmp(100, v1, v2);DBMS_OUTPUT.PUT_LINE('姓名:'||v1);DBMS_OUTPUT.PUT_LINE('工資:'||v2);QueryEmp(103, v1, v2);DBMS_OUTPUT.PUT_LINE('姓名:'||v1);DBMS_OUTPUT.PUT_LINE('工資:'||v2);QueryEmp(104, v1, v2);DBMS_OUTPUT.PUT_LINE('姓名:'||v1);DBMS_OUTPUT.PUT_LINE('工資:'||v2);END;
例12.計算指定部門的工資總和,并統計其中的職工數量。
CREATE OR REPLACE PROCEDURE proc_demo(dept_no NUMBER DEFAULT 10, sal_sum OUT NUMBER, emp_count OUT NUMBER)IS BEGIN
SELECT SUM(salary), COUNT(*)INTO sal_sum, emp_count FROM employees WHERE department_id = dept_no;EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:你需要的數據不存在!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END proc_demo;
DECLARE V_num NUMBER;V_sum NUMBER(8, 2);BEGIN
Proc_demo(30, v_sum, v_num);DBMS_OUTPUT.PUT_LINE('溫馨提示:30號部門工資總和:'||v_sum||',人數:'||v_num);Proc_demo(sal_sum => v_sum, emp_count => v_num);DBMS_OUTPUT.PUT_LINE('溫馨提示:10號部門工資總和:'||v_sum||',人數:'||v_num);END;
在PL/SQL 程序中還可以在塊內建立本地函數和過程,這些函數和過程不存儲在數據庫中,但可以在創建它們的PL/SQL 程序中被重復調用。本地函數和過程在PL/SQL 塊的聲明部分定義,它們的語法格式與存儲函數和過程相同,但不能使用CREATE OR REPLACE 關鍵字。
例13:建立本地過程,用于計算指定部門的工資總和,并統計其中的職工數量;
DECLARE V_num NUMBER;V_sum NUMBER(8, 2);PROCEDURE proc_demo(Dept_no NUMBER DEFAULT 10, Sal_sum OUT NUMBER, Emp_count OUT NUMBER)IS BEGIN
SELECT SUM(salary), COUNT(*)INTO sal_sum, emp_count FROM employees WHERE department_id=dept_no;EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('你需要的數據不存在!');WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);END proc_demo;--調用方法: BEGIN
Proc_demo(30, v_sum, v_num);DBMS_OUTPUT.PUT_LINE('30號部門工資總和:'||v_sum||',人數:'||v_num);Proc_demo(sal_sum => v_sum, emp_count => v_num);DBMS_OUTPUT.PUT_LINE('10號部門工資總和:'||v_sum||',人數:'||v_num);END;
6.3.3 AUTHID 過程中的AUTHID 指令可以告訴ORACLE,這個過程使用誰的權限運行.默任情況下,存儲過程會作為調用者的過程運行,但是具有設計者的特權.這稱為設計者權利運行.
例14:建立過程,使用
Connect HR/qaz DROP TABLE logtable;CREATE table logtable(userid VARCHAR2(10), logdate date);
CREATE OR REPLACE PROCEDURE logexecution AUTHID DEFINER IS BEGIN
INSERT INTO logtable(userid, logdate)VALUES(USER, SYSDATE);END;
GRANT EXECUTE ON logexecution TO PUBLIC;
CONNECT / AS SYSDBA GRANT CONNECT TO testuser1 IDENTIFIED BY userpwd1;
CONNECT testuser1/userpwd1 INSERT INTO HR.LOGTABLE VALUES(USER, SYSDATE);EXECUTE HR.logexecution
AUTOID DEFINER; CONNECT HR/qaz SELECT * FROM HR.logtable;
例15:建立過程,使用
CONNECT HR/qaz
CREATE OR REPLACE PROCEDURE logexecution AUTHID CURRENT_USER IS BEGIN
INSERT INTO logtable(userid, logdate)VALUES(USER, SYSDATE);END;
GRANT EXECUTE ON logexecution TO PUBLIC;
CONNECT testuser1/userpwd1 INSERT INTO HR.LOGTABLE VALUES(USER, SYSDATE);EXECUTE HR.logexecution
AUTOID CURRENT_USER;
6.3.4 PRAGMA AUTONOMOUS_TRANSACTION
ORACLE8i 可以支持事務處理中的事務處理的概念.這種子事務處理可以完成它自己的工作,獨立于父事務處理進行提交或者回滾.通過使用這種方法,開發者就能夠這樣的過程,無論父事務處理是提交還是回滾,它都可以成功執行.
例16:建立過程,使用自動事務處理進行日志記錄;
DROP TABLE logtable;
CREATE TABLE logtable(Username varchar2(20), Dassate_time date, Mege varchar2(60));
CREATE TABLE temp_table(N number);
CREATE OR REPLACE PROCEDURE log_message(p_message varchar2)AS PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
INSERT INTO logtable VALUES(user, sysdate, p_message);COMMIT;END log_message;BEGIN
Log_message(‘About to insert into temp_table‘);
INSERT INTO temp_table VALUES(1);Log_message(‘Rollback to insert into temp_table‘);
ROLLBACK;END;
SELECT * FROM logtable;SELECT * FROM temp_table;
例17:建立過程,沒有使用自動事務處理進行日志記錄;
CREATE OR REPLACE PROCEDURE log_message(p_message varchar2)AS BEGIN
INSERT INTO logtable VALUES(user, sysdate, p_message);COMMIT;END log_message;BEGIN
Log_message('About to insert into temp_table');INSERT INTO temp_table VALUES(1);Log_message('Rollback to insert into temp_table');ROLLBACK;END;
SELECT * FROM logtable;SELECT * FROM temp_table;
6.3.5 開發存儲過程步驟
開發存儲過程、函數、包及觸發器的步驟如下:
6.3.5.1 使用文字編輯處理軟件編輯存儲過程源碼 使用文字編輯處理軟件編輯存儲過程源碼,要用類似WORD 文字處理軟件進行編輯時,要將源碼存為文本格式。
6.3.5.2 在SQLPLUS或用調試工具將存儲過程程序進行解釋
在SQLPLUS或用調試工具將存儲過程程序進行解釋;
在SQL>下調試,可用START 或GET 等ORACLE命令來啟動解釋。如: SQL>START c:stat1.sql
如果使用調式工具,可直接編輯和點擊相應的按鈕即可生成存儲過程。
6.3.5.3 調試源碼直到正確
我們不能保證所寫的存儲過程達到一次就正確。所以這里的調式是每個程序員必須進行的工作之一。在SQLPLUS下來調式主要用的方法是:
? 使用 SHOW ERROR命令來提示源碼的錯誤位置;
? 使用 user_errors 數據字典來查看各存儲過程的錯
誤位置。
6.3.5.4 授權執行權給相關的用戶或角色
如果調式正確的存儲過程沒有進行授權,那就只有建立者本人才可以運行。所以作為應用系統的一部分的存儲過程也必須進行授權才能達到要求。在SQL*PLUS下可以用GRANT命令來進行存儲過程的運行授權。
GRANT語法:
GRANT system_privilege | role TO user | role | PUBLIC [WITH ADMIN OPTION]
GRANT object_privilege | ALL ON schema.object TO user | role | PUBLIC [WITH GRANT OPTION]
--例子:
CREATE OR REPLACE PUBLIC SYNONYM dbms_job FOR dbms_job
GRANT EXECUTE ON dbms_job TO PUBLIC WITH GRANT OPTION
6.3.5.5 與過程相關數據字典
USER_SOURCE, ALL_SOURCE, DBA_SOURCE, USER_ERRORS, ALL_PROCEDURES,USER_OBJECTS,ALL_OBJECTS,DBA_OBJECTS
相關的權限:
CREATE ANY PROCEDURE DROP ANY PROCEDURE
在SQL*PLUS 中,可以用DESCRIBE 命令查看過程的名字及其參數表。
DESC[RIBE] Procedure_name;
6.3.6 刪除過程和函數
1.刪除過程
可以使用DROP PROCEDURE命令對不需要的過程進行刪除,語法如下:
DROP PROCEDURE [user.]Procudure_name;
2.刪除函數
可以使用DROP FUNCTION 命令對不需要的函數進行刪除,語法如下:
DROP FUNCTION [user.]Function_name;
--刪除上面實例創建的存儲過程與函數 DROP PROCEDURE logexecution;DROP PROCEDURE delemp;DROP PROCEDURE insertemp;DROP PROCEDURE fireemp;DROP PROCEDURE queryemp;DROP PROCEDURE proc_demo;DROP PROCEDURE log_message;DROP FUNCTION demo_fun;DROP FUNCTION get_salary;
6.3.7 過程與函數的比較
使用過程與函數具有如下優點:
1、共同使用的代碼可以只需要被編寫和測試一次,而被需要該代碼的任何應用程序(如:.NET、C++、JAVA、VB程序,也可以是DLL庫)調用。
2、這種集中編寫、集中維護更新、大家共享(或重用)的方法,簡化了應用程序的開發和維護,提高了效率與性能。
3、這種模塊化的方法,使得可以將一個復雜的問題、大的程序逐步簡化成幾個簡單的、小的程序部分,進行分別編寫、調試。因此使程序的結構清晰、簡單,也容易實現。
4、可以在各個開發者之間提供處理數據、控制流程、提示信息等方面的一致性。
5、節省內存空間。它們以一種壓縮的形式被存儲在外存中,當被調用時才被放入內存進行處理。并且,如果多個用戶要執行相同的過程或函數時,就只需要在內存中加載一個該過程或函數。
6、提高數據的安全性與完整性。通過把一些對數據的操作放到過程或函數中,就可以通過是否授予用戶有執行該過程或的權限,來限制某些用戶對數據進行這些操作。
過程與函數的相同功能有:
1、都使用IN模式的參數傳入數據、OUT模式的參數返
回數據。
2、輸入參數都可以接受默認值,都可以傳值或傳引導。
3、調用時的實際參數都可以使用位置表示法、名稱表示
法或組合方法。
4、都有聲明部分、執行部分和異常處理部分。
5、其管理過程都有創建、編譯、授權、刪除、顯示依賴
關系等。
使用過程與函數的原則:
1、如果需要返回多個值和不返回值,就使用過程;如果只需要返回一個值,就使用函數。
2、過程一般用于執行一個指定的動作,函數一般用于計算和返回一個值。
3、可以SQL語句內部(如表達式)調用函數來完成復雜的計算問題,但不能調用過程。所以這是函數的特色。
第五篇:6.用戶自定義控件中 Control Type Def 和 Strict Type Def的區別
為了解釋清楚,先定義一下要用到的概念。我們把以.ctl 文件名定義的控件叫做用戶自定義控件,把通過拖拽或打開這個.ctl 文件在 VI 上生成的控件叫做實例。
LabVIEW 的用戶自定義控件包括了三種定義形式:打開一個.ctl 文件,在它上方的“control”下拉條中有三個選擇,分別是無關聯控件(Control)、類型定義(Type Def.)或者嚴格類型定義(Strict Type Def.)。
無關聯控件是指這個控件與它的實例之間沒有任何關聯。例如,你制作了一個漂亮的按鈕控件保存在.ctl 文件中。需要用到它時,通過拖拽或打開這個.ctl 文件就可以在 VI 中生成這個用戶自定義控件的一個實例。這個實例一旦生成,就和原用戶自定義控件無任何關聯了。無論是你修改這個實例,還是修改原用戶自定義控件,都不會對另一方產生任何影響。
類型定義控件是指實例控件與用戶自定義控件的空間類型是相關聯的。比如,你的用戶自定義控件是一個數值型控件,那么它的所有實例控件也都是數值型的。如果我們在.ctl 文件中把用戶自定義控件的類型改為字符串,那么它已有的所有實例都將自動變成字符串類型。
有時候,只是類型相關聯還不夠。比如對于 Ring(Enum,Combo Box)這類的控件來說,如果在用戶自定義控件中添加了一項內容(item),一般總是希望它所有的實例也同時添加這一選項。如果使用類型定義控件,因為控件類型沒變,還是 Ring,實例們是不會自動跟隨更新的。這時就需要使用嚴格類型定義控件。選擇嚴格類型定義后,不但實例與用戶自定義控件的類型是相關聯的,其他一些控件屬性,比如顏色等等,也是相關聯的。
使用嚴格類型定義時有一點容易被誤解:嚴格類型定義只是與實例控件相關聯,由它生成的實例常量的屬性是不與之關聯的。實例常量是指通過拖拽或生成常量等方法,在程序框圖上生成的一個與.ctl 文件相關聯的常量。比如在 Ring 型用戶自定義控件中添加了一項內容,相關的實例常量是不會發生任何改變的。很多人按常理想,認為常量也應當自動更新,但事實上不行。這也是我不采用它做常量定義的原因之
一。(參見:在 LabVIEW 中使用常量定義)