存儲過程default
1. 存儲過程禁止空參數
默認情況下,參數可為空。如果傳遞 NULL 參數值並且該參數語句中使用,而該語句中引用的列又不允許使用 NULL,則 sql Server 會產生一條錯誤信息。為了防止向不允許使用 NULL 的列傳遞 NULL 參數值,應向過程中添加編程邏輯或為該列使用默認值(使用 的 DEFAULT 關鍵字)。
2. oracle存儲過程基本語法
一:存儲過程
創建存儲過程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統許可權
刪除存儲過程,是過程的創建者或者擁有DROP ANY PROCEDURE系統許可權
修改存儲過程,則只能是過程的創建者或者擁有ALTER ANY PROCEDURE系統許可權的人
執行(或調用)存儲過程,是過程的創建者或是擁有EXECUTE ANY PROCEDURE系統許可權的人或是被擁有者授予EXECUTE許可權的人
1:語法
1)創建
CREATE[ORREPLACE]PROCEDURE存儲過程名[(參數[IN|OUT|INOUT] 數據類型...)]
{AS|IS}
[說明部分]
BEGIN
可執行部分
[EXCEPTION
錯誤處理部分]
END[過程名];
說明:
OR REPLACE 表示如果存在就覆蓋存儲過程
參數有三種形式:IN、OUT和IN OUT。則默認為IN。
關鍵字AS也可以寫成IS,後跟過程的說明部分,可以在此定義過程的局部變數。
2)刪除存儲過程:
DROP PROCEDURE 存儲過程名;
3)修改存儲過程:
ALTER PROCEDURE 存儲過程名 COMPILE;
4)執行存儲過程
EXECUTE 模式名.存儲過程名[(參數...)];
或
BEGIN
模式名.存儲過程名[(參數...)];
END;
另外:參數可以是變數、常量或表達式
要其它用戶執行存儲過程須要給其它用戶授權
GRANT EXECUTE ON 存儲過程名 TO 用戶名
2:參數說明
IN 定義一個輸入參數變數,用於傳遞參數給存儲過程
OUT 定義一個輸出參數變數,用於從存儲過程獲取數據
IN OUT 定義一個輸入、輸出參數變數,兼有以上兩者的功能
1)參數名 IN 數據類型 DEFAULT 值;
定義一個輸入參數變數,用於傳遞參數給存儲過程。
可以是常量、有值變數或表達式
DEFAULT 關鍵字為可選項,用來設定參數的默認值。如果在調用存儲過程時不指明參數,則參數變數取默認值
在存儲過程中,輸入變數接收主程序傳遞的值,但不能對其進行賦值。
2)參數名 OUT 數據類型;
定義一個輸出參數變數,用於從存儲過程獲取數據,即變數從存儲過程中返回值給主程序。
在調用存儲過程時,主程序的實際參數只能是一個變數,而不能是常量或表達式。
在存儲過程中,參數變數只能被賦值而不能將其用於賦值,而且必須給輸出變數至少賦值一次。
3)參數名 IN OUT 數據類型 DEFAULT 值;
定義一個輸入、輸出參數變數,兼有以上兩者的功能。
在調用存儲過程時,主程序的實際參數只能是一個變數,而不能是常量或表達式。
DEFAULT 關鍵字為可選項,用來設定參數的默認值。
在存儲過程中,變數接收主程序傳遞的值,同時可以參加賦值運算,也可以對其進行賦值。在存儲過程中必須給變數至少賦值一次。
補充:如果省略IN、OUT或IN OUT,則默認模式是IN。
調用它時參數個數與位置可以不一致,用以下形式調用:
EXECUTE CHANGE_SALARY(P_RAISE=>80,P_EMPNO=>7788); //=>運算符左側是參數名,右側是參數表達式
二:函數
創建函數,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統許可權
刪除函數,需要是函數的創建者或者是擁有DROP ANY PROCEDURE系統許可權的人
修改函數,需要是函數的創建者或者擁有ALTER ANY PROCEDURE系統許可權的人
執行函數,需要是函數的創建者或擁有EXECUTE ANY PROCEDURE系統許可權的人
1:語法
1)創建:
CREATE[ORREPLACE]FUNCTION函數名[(參數[IN] 數據類型...)]
RETURN數據類型
{AS|IS}
[說明部分]
BEGIN
可執行部分
RETURN(表達式)
[EXCEPTION
錯誤處理部分]
END[函數名];
說明:
參數是可選的,但只能是IN類型(IN關鍵字可以省略)。
在定義部分的RETURN 數據類型,用來表示函數的數據類型,也就是返回值的類型,不可省略。
在可執行部分的RETURN(表達式),用來生成函數的返回值,其表達式的類型應該和定義部分說明的函數返回值的數據類型一致。在函數的執行部分可以有多個RETURN語句,但只有一個RETURN語句會被執行,一旦執行了RETURN語句,則函數結束並返回調用環境。
2)刪除
DROP FUNCTION 函數名;
3)修改
ALTER PROCEDURE 函數名 COMPILE;
4)執行
變數名:=函數名(...)
三:對存儲過程 和 函數的查看(可以通過對數據字典【USER_SOURCE】的訪問來查詢存儲過程或函數的有關信息)
1:查詢某個存儲過程序內容
select TEXT from user_source WHERE NAME='存儲過程名';
2:查看數據字殿
DESCRIBE USER_SOURCE ; //命令行中
3:查看存儲過程的參數
DESCRIBE say_hello; //後面是過程名
4:查看發生編輯錯誤
SHOW ERRORS ;
5:查詢一個存儲過程或函數是否是有效狀態(即編譯成功)
SELECT STATUS FROM USER_OBJECTS WHERE OBJECT_NAME='過程名';//注意大小寫
VALID表示該存儲過程有效(即通過編譯),INVALID表示存儲過程無效或需要重新編譯。它的狀態會改變,這與它依賴外部表(表刪除修改等操作)有關系
6:查看存儲過程與表的依賴關系
SELECT REFERENCED_NAME,REFERENCED_TYPE FROM USER_DEPENDENCIES WHERE NAME='SAY_HELLO';
說明
NAME為實體名,TYPE為實體類型,REFERENCED_OWNER為涉及到的實體擁有者賬戶,REFERENCED_NAME為涉及到的實體名,REFERENCED_TYPE 為涉及到的實體類型。
問題:
如果一個用戶A被授予執行屬於用戶B的一個存儲過程的許可權,在用戶B的存儲過程中,訪問到用戶C的表,用戶B被授予訪問用戶C的表的許可權,但用戶A沒有被授予訪問用戶C表的許可權,那麼用戶A調用用戶B的存儲過程是失敗的還是成功的呢?答案是成功的。
3. 什麼是存儲過程
sql語句執行的時候要先編譯,然後執行。存儲過程就是編譯好了的一些sql語句。用的時候直接就可以用了。所以效率會高 一 存儲過程介紹 存儲過程是由流控制和SQL語句書寫的過程,這個過程經編譯和優化 後存儲在資料庫伺服器中,使用時只要調用即可。在ORACLE中,若干個 有聯系的過程可以組合在一起構成程序包。 使用存儲過程有以下的優點: * 存儲過程的能力大大增強了SQL語言的功能和靈活性。存儲過程可 以用流控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的 運算。 * 可保證數據的安全性和完整性。 # 通過存儲過程可以使沒有許可權的用戶在控制之下間接地存取數據 庫,從而保證數據的安全。 # 通過存儲過程可以使相關的動作在一起發生,從而可以維護數據 庫的完整性。 * 再運行存儲過程前,資料庫已對其進行了語法和句法分析,並給出 了優化執行方案。這種已經編譯好的過程可極大地改善SQL語句的性能。 由於執行SQL語句的大部分工作已經完成,所以存儲過程能以極快的速度執 行。 * 可以降低網路的通信量。 * 使體現企業規則的運算程序放入資料庫伺服器中,以便: # 集中控制。 # 當企業規則發生變化時在伺服器中改變存儲過程即可,無須修改 任何應用程序。企業規則的特點是要經常變化,如果把體現企業規則的運 算程序放入應用程序中,則當企業規則發生變化時,就需要修改應用程序 工作量非常之大(修改、發行和安裝應用程序)。如果把體現企業規則的 運算放入存儲過程中,則當企業規則發生變化時,只要修改存儲過程就可 以了,應用程序無須任何變化。 不同資料庫存儲過程的寫法不一,在後面的講座中將分別介紹ORACLE 和SYBASE存儲過程的用法。 二 ORACLE 的存儲過程 ORACLE 創建存儲過程的語法為: create [or replace] procere 過程名 參數1 [in|out|in out] 數據類型 [,參數2 [in|out|in out] 數據類型]... pl/sql 語句 下面舉例說明ORACLE資料庫存儲過程的寫法和用法。 可以建立一個存儲過程,每當用戶修改資料庫的重要數據時,即把 用戶的用戶名、掌諍筒僮骼嘈圖鍬枷呂矗?nbsp; create procere update_log is begin insert into update_log_tab(use_name,update_date,operation) values(user,sysdate,'update' end; 可以在恰當的位置調用這個存儲過程來記錄用戶對表的修改。例如下面在 表sal_comm上建立一個修改觸發器,每當用戶修改此表後,用戶的名稱、修改 時間和操作即被記錄在了表update_log_tab中: create trigger audit_update after update on sal_comm for each row begin update_log end --三 Sybase的存儲過程 盡管Sybase存儲過程的功能和寫法與ORACLE類似,但他們之間還是 有一定的差別。下面講述SYBASE的存儲過程。 SYBASE可以用CREATE PROCere命令生成存儲過程: CREATE PROCere 存儲過程名 [;number] [[(] @parameter_name datatype [=default] [OUTput] [, @parameter_name datatype [=default] [OUTput]]...[)]] [WITH RECOMPILE] AS SQL_statements 下面是一個查詢作者編碼、名稱和生日的存儲過程: create proc p_auths @author_code varchar(10) as select author_code, name, birthdate from auths where author_code=@author_code 下面執行過程p_auths: p_auths @author_code=A00001 在CREATE PROC語句中,可以為參數賦預設值,該值可以是任何常量。 當用戶不提供參數值時,該值便作為參數值提供給過程。
4. mysql 存儲過程 是什麼意思
用select...into語句
下面是mysql 5.0的幫助文檔的:
這個SELECT語法把選定的列直接存儲到變數。因此,只有單一的行可以被取回。
SELECT id,data INTO x,y FROM test.t1 LIMIT 1;
注意,用戶變數名在MySQL 5.1中是對大小寫不敏感的。請參閱9.3節,「用戶變數」。
重要: SQL變數名不能和列名一樣。如果SELECT ... INTO這樣的SQL語句包含一個對列的參考,並包含一個與列相同名字的局部變數,MySQL當前把參考解釋為一個變數的名字。例如,在下面的語句中,xname 被解釋為到xname variable 的參考而不是到xname column的:
CREATE PROCEDURE sp1 (x VARCHAR(5))
BEGIN
DECLARE xname VARCHAR(5) DEFAULT 'bob';
DECLARE newname VARCHAR(5);
DECLARE xid INT;
SELECT xname,id INTO newname,xid
FROM table1 WHERE xname = xname;
SELECT newname;
END;
當這個程序被調用的時候,無論table.xname列的值是什麼,變數newname將返回值『bob』。
5. 什麼是存儲過程
CREATE PROCEDURE [擁有者.]存儲過程名[;程序編號] [(參數#1,…參數#1024)] [WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION} ] [FOR REPLICATION] AS 程序行 其中存儲過程名不能超過128個字。每個存儲過程中最多設定1024個參數 (SQL Server 7.0以上版本),參數的使用方法如下: @參數名 數據類型 [VARYING] [=內定值] [OUTPUT] 每個參數名前要有一個「@」符號,每一個存儲過程的參數僅為該程序內部使用,參數的類型除了IMAGE外,其他SQL Server所支持的數據類型都可使用。 [=內定值]相當於我們在建立資料庫時設定一個欄位的默認值,這里是為這個參數設定默認值。[OUTPUT]是用來指定該參數是既有輸入又有輸出值的,也就是在調用了這個存儲過程時,如果所指定的參數值是我們需要輸入的參數,同時也需要在結果中輸出的,則該項必須為OUTPUT,而如果只是做輸出參數用,可以用CURSOR,同時在使用該參數時,必須指定VARYING和OUTPUT這兩個語句。 例子: CREATE PROCEDURE order_tot_amt @o_id int, @p_tot int output AS SELECT @p_tot = sum(Unitprice*Quantity) FROM orderdetails WHERE ordered=@o_id GO 例子說明: 該例子是建立一個簡單的存儲過程order_tot_amt,這個存儲過程根據用戶輸入的定單ID號碼(@o_id),由定單明細表 (orderdetails)中計算該定單銷售總額[單價(Unitprice)*數量(Quantity)],這一金額通過@p_tot這一參數輸出給調用這一存儲過程的程序。
編輯本段實例
資料庫存儲過程
資料庫存儲過程的實質就是部署在資料庫端的一組定義代碼以及SQL。將常用的或很復雜的工作,預先用SQL語句寫好並用一個指定的名稱存儲起來,那麼以後要叫資料庫提供與已定義好的存儲過程的功能相同的服務時,只需調用execute,即可自動完成命令。 利用SQL的語言可以編寫對於資料庫訪問的存儲過程,其語法如下: CREATE PROC[EDURE] procere_name [;number] [ {@parameter data_type} ][VARYING] [= default] [OUTPUT] ] [,...n] [WITH { RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION } ] [FOR REPLICATION] AS sql_statement [...n] [ ]內的內容是可選項,而()內的內容是必選項, 例:若用戶想建立一個刪除表tmp中的記錄的存儲過程Select_delete可寫為: Create Proc select_del As Delete tmp 例:用戶想查詢tmp表中某年的數據的存儲過程 create proc select_query @year int as select * from tmp where year=@year 在這里@year是存儲過程的參數 例:該存儲過程是從某結點n開始找到最上層的父親結點,這種經常用到的過程可以由存儲過程來擔當,在網頁中重復使用達到共享。 空:表示該結點為頂層結點 fjdid(父結點編號) 結點n 非空:表示該結點的父親結點號 dwmc(單位名稱) CREATE proc search_dwmc @dwidold int,@dwmcresult varchar(100) output as declare @stop int declare @result varchar(80) declare @dwmc varchar(80) declare @dwid int set nocount on set @stop=1 set @dwmc="" select @dwmc=dwmc,@dwid=convert(int,fjdid) from jtdw where id=@dwidold set @result=rtrim(@dwmc) if @dwid=0 set @stop=0 while (@stop=1) and (@dwid<>0) begin set @dwidold=@dwid select @dwmc=dwmc,@dwid=convert(int,fjdid) from jtdw where id=@dwidold if @@rowcount=0 set @dwmc="" else set @result=@dwmc+@result if (@dwid=0) or (@@rowcount=0) set @stop=0 else continue end set @dwmcresult=rtrim(@result) 使用exec pro-name [pram1 pram2.....]
SQL Server中執行存儲過程
sql語句執行的時候要先編譯,然後執行。存儲過程就是編譯好了的一些sql語句。用的時候直接就可以用了。 在SQL Server的查詢分析器中,輸入以下代碼: declare @tot_amt int execute order_tot_amt 1,@tot_amt output select @tot_amt 以上代碼是執行order_tot_amt這一存儲過程,以計算出定單編號為1的定單銷售金額,我們定義@tot_amt為輸出參數,用來承接我們所要的結果。
Oracle中的存儲過程
1.創建過程 與其它的資料庫系統一樣,Oracle的存儲過程是用PL/SQL語言編寫的能完成一定處理功能的存儲在資料庫字典中的程序。 語法: create [or replace] procere procere_name [ (argment [ { in| in out }] type, argment [ { in | out | in out } ] type { is | as } <類型.變數的說明> ( 注: 不用 declare 語句 ) Begin <執行部分> exception <可選的異常處理說明> end; 1.1 這里的IN表示向存儲過程傳遞參數,OUT表示從存儲過程返回參數。而IN OUT 表示傳遞參數和返回參數; 1.2 在存儲過程內的參數只能指定參數類型;不能指定長度; 1.3 在AS或IS 後聲明要用到的變數名稱和變數類型及長度; 1.4 在AS或IS 後聲明變數不要加declare 語句。 2.使用過程 存儲過程建立完成後,只要通過授權,用戶就可以在SQLPLUS 、Oracle開發工具或第三方開發工具來調用運行。Oracle 使用EXECUTE 語句來實現對存儲過程的調用。 語法: EXEC[UTE] procere_name( parameter1, parameter2…); 3.開發過程 目前的幾大資料庫廠商提供的編寫存儲過程的工具都沒有統一,雖然它們的編寫風格有些相似,但由於沒有標准,所以各家的開發調試過程也不一樣。下面編寫PL/SQL存儲過程、函數、包及觸發器的步驟如下: 3.1 編輯存儲過程源碼使用文字編輯處理軟體編輯存儲過程源碼,要用類似WORD 文字處理軟體進行編輯時,要將源碼存為文本格式。 3.2 對存儲過程程序進行解釋在SQLPLUS或用調試工具將 存儲過程程序進行解釋; 在SQL>下調試,可用start 或get 等Oracle命令來啟動解釋。如: SQL>start c:\stat1.sql 如果使用調試工具,可直接編輯和點擊相應的按鈕即可生成存儲過程。[1] 3.3 調試源碼直到正確我們不能保證所寫的存儲過程達到一次就正確。所以這里的調試是每個程序員必須進行的工作之一。在SQLPLUS下來調試主要用的方法是: 1.使用 SHOW ERROR命令來提示源碼的錯誤位置; 2.使用 USER_ERRORS 數據字典來查看各存儲過程的錯誤位置。 3.4 授權執行權給相關的用戶或角色如果調試正確的存儲過程沒有進行授權,那就只有建立者本人才可以運行。所以作為應用系統的一部分的存儲過程也必須進行授權才能達到要求。 在SQLPLUS下可以用GRANT命令來進行存儲過程的運行授權。 語法: GRANT system_privilege | role TO user | role | PUBLIC [WITH ADMIN OPTION] 或 GRANT object_privilege | ALL column ON schema.object TO user | role | PUBLIC WITH GRANT OPTION 其中: system_privilege: 系統許可權 role: 角色名 user: 被授權的用戶名 object_privilege: 所授予的許可權名字,可以是 ALTER DELETE EXECUTE INDEX INSERT REFERENCES SELECT UPDATE Column: 列名 schema: 模式名 object: 對象名 4.數據字典 USER_SOURCE 用戶的存儲過程、函數的源代碼字典 DBA_SOURCE 整個系統所有用戶的存儲過程、函數的源代碼字典 ALL_SOURCE 當前用戶能使用的存儲過程(包括其她用戶授權)、函數的源代碼字典 USER_ERRORS 用戶的存儲過程、函數的源代碼存在錯誤的信息字典
6. 如何查看存儲過程運行到哪個語句了
存儲過程(procere 過程)
SQL Server2005 的存儲過程包含一些 T-SQL 語句並以特定的名稱存儲在數據中(存儲過程也是一種資料庫對象)可以在存儲過程中聲明變數,有條件的執行及其他各項強大的程序設計功能
SQL Server2005 的存儲過程與其它育種設計語言的過程類似,同樣按以下方式運行:
(1)它能夠包含執行各種資料庫操作的語句,並且可以調用其他的存儲過程;
(2)能夠接受輸入參數,並以輸出參數的形式將多個數據值返回給調用程序(Calling Procere)或批處理(Batch);
(3)向調用程序或批處理返回一個狀態值,以表明成功或失敗(以及失敗的原因);
(4)存儲過程(Stored Proceres) 是一組為完成特定功能的SQL 語句集,經編譯後,存儲在資料庫中,用戶通過指定存儲過程的名字給出參
數(如果該存儲過程帶有參數)來執行它;
存儲過程的類型:
一、(系統存儲過程):存儲過程在運行時生成執行方式,其後在運行時執行速度很
SQL Server2005 不僅提供用戶自定義存儲過程的功能,而且也提供許多可作為工具使用的系統存儲過程;
系統存儲過程(Systerm StroedProceres) 主要存儲在master資料庫中,並以 sp_ 為前輟,並且系統存儲過程主要是從系統表中獲取信息,從而為管理員SQL Server2005提供支持。通過系統存儲過程SQL Server2005中的許多管理性或信息性的活動(如了解數據對象,資料庫信息等)都可以被有效地完成,盡管這些系統存儲過程被存儲在master資料庫中,但是仍然可以在其他 資料庫中對其進行調用,在調用時,不必在存儲過程前面加上資料庫名,而且當創建一個資料庫時,一些存儲過程會在新的資料庫中被自動創建;
系統存儲過程所能完成操作很多,如提供幫助的存儲過程
sp_helpsql 顯示關於SQL語句,存儲過程和其他主題的信息
sp_help 提供關於存儲過程或其他資料庫對象的報告
sp_helptext 顯示存儲過程和其他對象文本
sp_depends 列舉引用或依賴指定對象的所有存儲過程
sp_talbes 取得資料庫中關於表和視圖的相關信息,
sp_renameedb 更改資料庫的名稱
SQL Server2005系統存儲過程可以使用戶很容易地從系統表中提取信息,管理資料庫,並執行涉及更新系統表的其他任務
系統存儲過程中在master資料庫中創建,由系統管理員管理,所有系統存儲過程的名字均以sp_開始
如果過程以sp_前綴命名的過程在當前資料庫中找不到,SQL Server2005就在master資料庫中尋找,以sp_前綴命名的過程中引用的表如果不能在當前資料庫中解析出來,將在master資料庫查找
當前系統存儲過程的參數是保留字或對象名,且對象名由資料庫或擁有者名字限定時,整個名字必須包含在單引號中,一個用戶可以在所有資料庫中執行一個系統存儲過程的許可權,否則在任何資料庫中都不能執行系統存儲過程
二、(本地存儲過程)
本地存儲過程(Local Stored Proceres)也就是用戶自行創建並存儲在用戶資料庫中的存儲過程,一般所說的存儲過程就是指的是本地的
用戶創建的存儲過程是由用戶創建並能完成某一特定功能(如:查詢用戶所需要的數據信息)的存儲過程
三、(臨時存儲過程)
臨時存儲過程(Temporary StoredProceres)可分為以下兩種
1)本地臨時存儲過程
不論哪一個資料庫是當前資料庫,如果在創建存儲過程時,以井字型大小 (#) 作為其名稱的,第一個字元,則該存儲過程將成為一個存放在tempdb資料庫中的本地臨時存放存儲過程(如:CREATE PROCEDURE #book_proc) 本地臨時存儲過程只有創建它的連接的用戶才能夠執行它,而且一但這位用戶斷開與 sql-server的連接(也就是注銷sql-server2005)本地臨時存儲過程就會自動刪除,當然,這位用戶也可以連接期間用 DROP PROCEDURE 命令刪除他所創建的本地臨時存儲過程;
由於本地存儲過程的適用范圍僅限於創建它的連接,因此,不需擔心其名稱會和其他連接所採用的名稱相同
2)全臨時存儲過程
不論哪一個資料庫當前資料庫,只要所創建的存儲過程名稱是以兩個井字型大小(##)開始,則該存儲過程將成為一個存儲在tempdb 資料庫中的全局臨時存儲過程(例如:create procere ##book_proc) 全局臨時存儲過程一旦創建,以後連接到 SQL Server2005 的任意用戶都能執行它,而且不需要特定的許可權
當創建全局臨時存儲過程的用戶斷開與SQL Server2005的連接時,SQL Server2005將檢查是否有其他用戶在執行該全局臨時存儲過程,如果沒有,便立刻將全局臨時存儲過程刪除,如果有SQL Server2005會讓這些正在執行中的操作繼續進行,但是不允許任何用戶再執行全局臨時存儲過程,等到有未完成的操作執行完畢後,全局臨時存儲過程就會自動刪除;
由於全局臨時存儲過程能夠被所有的連接用戶使用,因些必須注意其名稱不能和其他連接所採用的名稱相同
不論創建的是本地臨時存儲過程還是全局臨時存儲過程,只要SQL Server2005一停止運行,它們將不復存在;
四(遠程存儲過程)
在SQL Server2005 中,遠程存儲過程(Remote Stored Proceres)是位於遠程伺服器上的存儲過程,通常可以使用分布式查詢和 excute 命令執行一個遠程存儲過程;
五(擴展存儲過程)
擴展存儲過程(Extended Stored Proceres)是用戶可以使用外部程序語言編寫的存儲過程,通過擴展存儲過程可以彌補SQL Server2005的不足,它在使用和執行上與一般的存儲過程完全相同;可以將參數傳遞給擴展存儲過程,擴展存儲過程也能夠返回結果和狀態值;
為了區別擴展存儲過程的名稱通常以xp_開頭,擴展存儲過程是以動態鏈接庫(DLLS)的形式存在,能讓SQL Server2005動態地裝載和執行,擴展存儲過程一定要存儲在系統資料庫 master 中
存儲過程的優點
(1) 通過本地存儲、代碼預編譯和緩存技術實現高性能的數據操作
(2) 通過用編程結構和過程實現編程框架;如果業務規則發生變化,可以通過修改存儲過程來適應新的業務規則,而不必修改客戶端的應用程 序,這樣所有調用該存儲過程的應用程序就會遵循新的業務規則;
(3) 通過隔離和加密的方法提高資料庫的安全性。資料庫可以通過得到許可權來執行存儲過程,而不必給予用戶直接訪問資料庫對象的許可權,這 些對象交收存儲過程來執行操作,另外,存儲過程可以加密,這樣用戶就無法閱讀存儲過程中的T-sql語句。這樣做將資料庫的結構和數 據庫用戶隔離開來,時一步保證數據的完整性和可靠性;
存儲過程與視圖的比較
(1) 可以在單個存儲過程執行一系列T-SQL 語句,而在視圖中只能是 select 語句
(2) 視圖不能接受參數,只能返回結果集;而存儲過程可以接受參數,包括輸入,輸出參數,並能返回單個或多個結果集以及返回值,這樣可 大大地提高應用的靈活性;
一般來說,人們將經常用到的多個表的連接查詢定義為視圖,而存儲過程完成復雜的一第列的處理,在存儲過程中也會經常用到視圖;
創建存儲過程
CREATE PROCEDURE procere_name
[WITH ENCRYPTION]
[WITH RECOMPILE]
AS
Sql_statement
其中 with encryption 對存儲過程進行加密; with recompile 對存儲過程重新編譯
例如:使用T-SQL 語句在book資料庫中創建一個名為p_book1的存儲過程 該存儲過程返回book1表中所有出版社為"中國長安"的記錄
USE book
GO
CREATE PROCEDURE p_book1
AS
SELECT * FROM book1 WHERE 出版社='中國長安'
執行存儲過程
存儲過程創建成功後,用戶可以執行存儲過程來檢查存儲過程的返回結果;基本語法如下:
exec procere_name
例如:使用T-SQL語句執行上面創建的存儲過程 運行命令如下:
USE book
GO
exec p_book1
在運行完畢後,在SQL-Server ManagementStudio 查詢窗口中返回的結果
存儲過程創建成功後可以在 SQL-Server ManagementStudio 窗口中下查看存儲過程的屬性
例如:在 SQL-Server ManagementStudio 窗口中查看存儲過程 p_book1 的屬性:
對象資源管理器-> 展開book選項-> 展開可編程性-> 右擊 p_book1選擇修改命令 就可以修改存儲過程命令屬性
帶參數的存儲過程
由於視圖沒有提供參數,對於行的篩選取只能綁定在視圖中定義,靈活性不大,而存儲過程提供了參數,大大提高了系統開發的靈活性
向存儲過程設定輸入、輸出參數主要目的是通過參數向存儲過程輸入和輸出信息來擴展存儲過程的功能,能過設定能數,可以多次使用同一存儲過程並按要求查找所需要的結果;
1、帶輸入參數的存儲過程
輸入參數是指由調用程序向存儲過程傳遞的參數,它們在創建存儲過程語句中被定義,在執行存儲過程中給出相應的變數值,為了定義輸入參數存儲過程,需要在 create procere 語句中聲明一個或多個變數作為參數;其語法格式如下:
CREATE PROCEDURE procerd_name
@parameter_name datatype=[default]
[with encryption]
[with recompile]
AS
Sql_statement
其中各項參數如下
(1) @parameter_name: 存儲過程的參數名稱,必須以符號@為前綴
(2) Datatype: 參數的數據類型
(3) Default: 參數的默認值,如果執行存儲過程時未提供該參數的變數值,則使用default值
例子:使用T-SQL語句在book數據表中創建一個名為p_book1p的存儲過程,該存儲過程能根據給定的出版社回該出版社代碼對應的book1表中的的記錄:
分析:直接把上面的例子最後面的SQL語句 select * from book1 where 出版社='中國長安' 將裡面的 「出版社='中國長安'」用變理代替為 select * from book1 where 出版社= @出版社 其中變數名 @出版社取了代值 '中國長安';由於使用了變數,所以需要定義該變數,我們把「出版社」的長度設為是20位字元串;所以在 AS 之前定義變更@出版社 varchar(20);
create procere p_book1p
@出版社 varchar(20)
AS
SELECT * FROM book1 WHERE 出版社=@出版社
執行含有輸入參數的存儲過程
1)使用參數名傳遞參數值
在執行存儲過程的語句中通過語句 @paramter_name=value 給出參數的傳遞值,當存儲過程含有多個參數時,參數值可以任意順序設定,對於允許空值和具有默認值的輸入參數可以不給出參數的傳遞值;其格式語法如下:
exec procere_name
[@paramenter_name=value]
[,....n]
例子:用參數名傳遞參數值的方法執行存儲過程p_book1p,分別查出出版社為'中國長安'和"安徽人民"書的記錄
exec p_book1p @出版社='中國長安'
go
exec p_book1p @出版社='安徽人民'
go
2) 按位置傳遞參數值
在執行存儲過程的語句中,不通過參數傳遞值面直接給出參數的傳遞值,當存儲過程含有多個輸入參數時,傳遞值的順序必須與存儲過程中定義的輸入參數順序相一致,按位置傳遞參數時,也可以忽略空值和具有默認值的參數,但不能因此破壞輸入參數的設定順序;比如:在一個含有4個參數的存儲過程中,用戶可以忽略第3和第四個參數,但無法在忽略第3個的情況下而指定第4個參數的輸入值;
語法格式如下:
exec procere_name
[value1,value2,....]
例子:用按位置傳遞參數值的方法執行存儲過程 p_book1p 分別查找出版社為「中國人口」和「內蒙人民」書的記錄
exec p_book1p '內蒙人民'
go
exec p_book1p '中國人口'
go
按位置傳遞參數值比按參數名傳遞參數值更簡捷比較適合參數值較少的情況,而按照參數名傳遞的方法使程序的可讀性增強,特別是參數數量較多時,建議用按參數名傳遞參數的方法,這樣的程序可讀性/可維護性都要好一些;
3) 帶輸出參數的存儲過程
如果需要從存儲過程中返回一個或多個值,可以通過在創建存儲過程的語句中定義輸出參數來實現,為了使用輸出參數,需要在
create procere 語句中指定 output 關鍵字 輸出語法如下: @parameter_name datatype=[defautl] OUTPUT
例如:創建存儲過程 p_book1Num 要求能根據用戶給定的出版社,統計該出版社的出書數量,並將數量以輸入變數的形式返回給用戶:
CREATE PROCEDURE p_bookNum
@出版社 var(20),@bookNum smallint output
AS
SET @BOOK1Num= --(這個裡面是給book1Num 賦值)
(
select count(*) from book1
where 出版社=@出版社
)
ptrint @book1Num
執行存儲過程p_book1Num
由於在存儲過程 p_book1Num 中使用了參數@出版社和@book1Num 所以在測試時需要先定義相應的變數,對於輸入參數@出版社需要賦值,而輸出參數 @book1Num 無需賦值,它是從存儲過程中獲得返回值供用戶進一步使用的
declare @出版社 varchar(20), @book1Num SMALLINT
set @出版社=「中國長安」
exec p_book1Num @出版社,@book1Num
說明:這里在是sql server2005 環境下進行測試的,而在進行系統開發時,往往變數的定義,賦值,使用都是在應用程序中設計的,存儲過程 p_book1Num 的 print @book1Num語句也是為了在 SQL Server2005環境中測試而設計的
刪除、修改、重命名存儲過程
修改存儲過程:是由alert 語句來完成的,語法如下:
ALTER procere procere_name
[with encryption]
[with recompile]
as
Sql_statement
例子:使用T-SQL語句修改存儲過程 p_book1p 根據用戶提供的出版社名稱進行模糊查詢並要求加密:
alter procere p_book1p
@出版社 varchar(20)
with encryption
as
select 出版社,ISBN號,定價,作者姓名
from book1,teacher
where book1.編號=teacher.編號 and 出版社 like '%@出版社%'
存儲過程的刪除:存儲過程的刪除是通過DROP語句來實現的
例如:使用T-SQL語句來刪除存儲過程p_book1
use book
go
drop procere p_book1
使用SQL-Server Management Studio窗口刪除存儲過程 p_book1p:
對象資源管理器-> 展開BOOK-> 展開可編程性-> 右鍵dbo.p_book1p->刪除 就可以了
存儲過程重命名:
對象資源管理器-> 展開BOOK-> 展開可編程性-> 右鍵dbo.p_book1p->重命名
存儲過程的重編譯處理
在存儲過程中所用的查詢只在編譯時進行優化,對資料庫進行索引或其他會影響資料庫統計的更改後,可能降低已編譯的存儲過程的效率,通過對存儲過程進行重新編譯,可以重新優化查詢;
在SQL-Server2005 中有三種方法重新編譯的方法:
1) 在創建存儲過程時使用 with recompile 子句
with recompile 子句可以指示 sql server2005 不將該存儲過程的查詢計劃保存在緩存中,而是在每次運行時重新編譯和優化,並創建新 的查詢計劃;下面是例子:
use book
go
create procere p_book1p
@出版社 varchar(20)
with recompile
as
select * from book1 where 出版社=@出版社
這種方法並不常用,因為在每次執行存儲過程時都要重新編譯,在整體上降低了存儲過程的執行速度,除非存儲過程本身是一個比較復雜,耗時的操作,編譯的時間相對於執行存儲過程時間少;
2) 在執行存儲過程時設定重新編譯選項
通過在執行存儲過程時設定重新編譯,可以讓SQL-Server2005在執行存儲過程時重新編譯該存儲過程,在這一次執行後,新的查詢計劃又被保存在緩存中;基語法格式是:
execute procere_name with recompile
以重新編譯的方式執行存儲過程p_book1p:
use book
go
execute p_book1p '中國長安'with recompile 此方法一般在存儲過程創建後,數據發生了顯著變化時使用
3) 通過系統存儲過程設定重新編譯選擇;其語法如下
exec sp_recomplie OBJECT 其中OBJECT 當前資料庫中的存儲過程,表或視圖的名稱
例子:執行下面的語句將導致book1表的觸發器和存儲過程在下次運行時將被重新編譯:
exec sp_recompile book
===========================================================================================================================
觸發器的創建和管理
概述:在SQL-Server2005資料庫系統中,存儲過程和觸發器都是SQL語句和流程式控制制語句的集合
===========================================================================================================================
7. 如何編寫存儲過程
設計存儲過程
幾乎任何可寫成批處理的 Transact-SQL 代碼都可用於創建存儲過程。
存儲過程的設計規則
存儲過程的設計規則包括:
CREATE PROCEDURE 定義本身可包括除下列 CREATE 語句以外的任何數量和類型的 SQL 語句,存儲過程中的任意地方都不能使用下列語句: CREATE DEFAULT CREATE TRIGGER
CREATE PROCEDURE CREATE VIEW
CREATE RULE
可在存儲過程中創建其它資料庫對象。可以引用在同一存儲過程中創建的對象,前提是在創建對象後再引用對象。
可以在存儲過程內引用臨時表。
如果在存儲過程內創建本地臨時表,則該臨時表僅為該存儲過程而存在;退出該存儲過程後,臨時表即會消失。
如果執行調用其它存儲過程的存儲過程,那麼被調用存儲過程可以訪問由第一個存儲過程創建的、包括臨時表在內的所有對象。
如果執行在遠程 Microsoft® SQL Server™ 2000 實例上進行更改的遠程存儲過程,則不能回滾這些更改。遠程存儲過程不參與事務處理。
存儲過程中參數的最大數目為 2100。
存儲過程中局部變數的最大數目僅受可用內存的限制。
根據可用內存的不同,存儲過程的最大大小可達 128 MB。
有關創建存儲過程的規則的更多信息,請參見 CREATE PROCEDURE。
限定存儲過程內的名稱
在存儲過程內部,如果用於諸如 SELECT 或 INSERT 這樣的語句的對象名沒有限定用戶,那麼用戶將默認為該存儲過程的所有者。在存儲過程內部,如果創建存儲過程的用戶沒有限定 SELECT、INSERT、UPDATE 或 DELETE 語句中引用的表名,那麼通過該存儲過程對這些表進行的訪問將默認地受到該過程的創建者許可權的限制。
如果有其他用戶要使用存儲過程,則用於語句 ALTER TABLE、CREATE TABLE、DROP TABLE、TRUNCATE TABLE、CREATE INDEX、DROP INDEX、UPDATE STATISTICS 和 DBCC 的對象名必須用該對象所有者的名稱限定。例如,Mary 擁有表 marytab,如果她希望其他用戶能夠執行使用該表的存儲過程,必須在該表用於上述某一條語句時對其表名進行限定。
此規則是必需的,因為運行存儲過程時將解析對象的名稱。如果未限定 marytab,而 John 試圖執行該過程,SQL Server 將查找 John 所擁有的名為 marytab 的表。
加密過程定義
如果要創建存儲過程,並且希望確保其他用戶無法查看該過程的定義,那麼可以使用 WITH ENCRYPTION 子句。這樣,過程定義將以不可讀的形式存儲。
存儲過程一旦加密其定義即無法解密,任何人(包括存儲過程的所有者或系統管理員)都將無法查看存儲過程定義。
SET 語句選項
當 ODBC 應用程序與 SQL Server 連接時,伺服器將自動設置會話的下列選項:
SET QUOTED_IDENTIFIER ON
SET TEXTSIZE 2147483647
SET ANSI_DEFAULTS ON
SET CURSOR_CLOSE_ON_COMMIT OFF
SET IMPLICIT_TRANSACTIONS OFF
這些設置將提高 ODBC 應用程序的可移植性。由於基於 DB-Library 的應用程序通常不設置這些選項,所以應在上述所列 SET 選項打開和關閉的情況下都對存儲過程進行測試。這樣可確保存儲過程始終能正確工作,而不管特定的連接在喚醒調用該存儲過程時可能設置的選項。需要特別設置其中一個選項的存儲過程,應在開始該存儲過程時發出一條 SET 語句。此 SET 語句將只對該存儲過程的執行保持有效,當該存儲過程結束時,將恢復原設置。
示例
A. 創建使用參數的存儲過程
下例創建一個在 pubs 資料庫中很有用的存儲過程。給出一個作者的姓和名,該存儲過程將顯示該作者的每本書的標題和出版商。
CREATE PROC au_info @lastname varchar(40), @firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
將出現一條說明該命令未返回任何數據也未返回任何行的消息,這表示已創建該存儲過程。
現在執行 au_info 存儲過程:
EXECUTE au_info Ringer, Anne
GO
下面是結果集:
au_lname au_fname title pub_name
--------- --------- --------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
(2 row(s) affected)
B. 創建使用參數默認值的存儲過程
下例創建一個存儲過程 pub_info2,該存儲過程顯示作為參數給出的出版商所出版的某本書的作者姓名。如果未提供出版商的名稱,該存儲過程將顯示由 Algodata Infosystems 出版的書籍的作者。
CREATE PROC pub_info2 @pubname varchar(40) = 'Algodata Infosystems'
AS
SELECT au_lname, au_fname, pub_name
FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id
JOIN titles t ON ta.title_id = t.title_id
JOIN publishers p ON t.pub_id = p.pub_id
WHERE @pubname = p.pub_name
執行未指定參數的 pub_info2:
EXECUTE pub_info2
GO
下面是結果集:
au_lname au_fname pub_name
---------------- ---------------- --------------------
Green Marjorie Algodata Infosystems
Bennet Abraham Algodata Infosystems
O'Leary Michael Algodata Infosystems
MacFeather Stearns Algodata Infosystems
Straight Dean Algodata Infosystems
Carson Cheryl Algodata Infosystems
Dull Ann Algodata Infosystems
Hunter Sheryl Algodata Infosystems
Locksley Charlene Algodata Infosystems
(9 row(s) affected)
C. 執行用顯式值替代參數默認值的存儲過程
在下例中,存儲過程 showind2 的 @table 參數默認值是 titles。
CREATE PROC showind2 @table varchar(30) = 'titles'
AS
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
列標題(例如,TABLE_NAME)可使結果更具可讀性。下面是該存儲過程顯示的 authors 表的情況:
EXECUTE showind2 authors
GO
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
authors UPKCL_auidind 1
authors aunmind 2
(2 row(s) affected)
如果用戶未提供值,則 SQL Server 將使用默認表 titles:
EXECUTE showind2
GO
下面是結果集:
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
titles UPKCL_titleidind 1
titles titleind 2
(2 row(s) affected)
D. 使用參數默認值 NULL 創建存儲過程
參數默認值可以是 NULL 值。在這種情況下,如果未提供參數,則 SQL Server 將根據存儲過程的其它語句執行存儲過程。不會顯示錯誤信息。
過程定義還可指定當不給出參數時要採取的其它某種措施。例如:
CREATE PROC showind3 @table varchar(30) = NULL
AS IF @table IS NULL
PRINT 'Give a table name'
ELSE
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
E. 使用包含通配符的參數默認值創建存儲過程
如果存儲過程將參數用於 LIKE 關鍵字,那麼默認值可包括通配符(%、_、[] 和 [^])。例如,可將 showind 修改為當不提供參數時顯示有關系統表的信息:
CREATE PROC showind4 @table varchar(30) = 'sys%'
AS SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name LIKE @table
在存儲過程 au_info 的下列變化形式中,兩個參數都有帶通配符的默認值:
CREATE PROC au_info2 @lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname
如果執行 au_info2 時不指定參數,將顯示姓以字母 D 開頭的所有作者:
EXECUTE au_info2
GO
下面是結果集:
au_lname au_fname title pub_name
-------- -------- --------------------- -------------------
Dull Ann Secrets of Silicon Val Algodata Infosystems
del Castillo Innes Silicon Val Gastrono Binnet & Hardley
DeFrance Michel The Gourmet Microwave Binnet & Hardley
(3 row(s) affected)
下例在兩個參數的默認值已定義的情況下,省略了第二個參數,因此可找到姓為 Ringer 的所有作者的書和出版商:
EXECUTE au_info2 Ringer
GO
au_lname au_fname title pub_name
--------- --------- ---------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
Ringer Albert Is Anger the Enemy? New Moon Books
Ringer Albert Life Without Fear New Moon Books
(4 row(s) affected)
8. 存儲過程如何使用
問題一:SQL 中存儲過程怎麼使用? sql存儲過程及應用
一、簡介:
存儲過程(Stored Procere), 是一組為了完成特定功能的SQL 語句,集經編譯後
存儲在資料庫中,用戶通過指定存儲過程的名字並給出參數,如果該存儲過程帶有參數來執行
它,
在SQL Server 的系列版本中,存儲過程分為兩類:系統提供的存儲過程和用戶自定義存儲過程
。
系統SP,主要存儲master 資料庫中,並以sp_為前綴並且系統存儲過程主要是從系統表中獲取
信息,從而為系統管理員管理SQL Server。用戶自定義存儲過程是由用戶創建,並能完成
某一特定功能,如:查詢用戶所需數據信息的存儲過程。
存儲過程具有以下優點
1.存儲過程允許標准組件式編程(模塊化設計)
存儲過程在被創建以後,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句,而
且數
據庫專業人員可隨時對存儲過程進行修改,但對應用程序源代碼毫無影響。因為應用程序源代
碼只包含存
儲過程的調用語句,從而極大地提高了程序的可移植性。
2.存儲過程能夠實現快速的執行速度
如果某一操作包含大量的Transaction-SQL 代碼,,或分別被多次執行,那麼存儲過程要比批處理
的
執行速度快很多,因為存儲過程是預編譯的,在首次運行一個存儲過程時,查詢優化器對其進
行分析優
化,並給出最終被存在系統表中的執行計劃,而批處理的Transaction-SQL 語句在每次運行時
都要進行
編譯和優化,因此速度相對要慢一些。
3.存儲過程能夠減少網路流量
對於同一個針對數據資料庫對象的操作,如查詢修改,如果這一操作所涉及到的Transaction-SQL
語句被組織成一存儲過程,那麼當在客戶計算機上調用該存儲過程時,網路中傳送的只是該調
用語句,否
則將是多條SQL 語句從而大大增加了網路流量降低網路負載。
4.存儲過程可被作為一種安全機制來充分利用
系統管理員通過,對執行某一存儲過程的許可權進行限制,從而能夠實現對相應的數據訪問許可權的
限
制。
二、變數
@I
三、流程式控制制語句(if else | select case | while )
Select ... CASE 實例
DECLARE @iRet INT, @PKDisp VARCHAR(20)
SET @iRet = '1'
Select @iRet =
CASE
WHEN @PKDisp = '一' THEN 1
WHEN @PKDisp = '二' THEN 2
WHEN @PKDisp = '三' THEN 3
WHEN @PKDisp = '四' THEN 4
WHEN @PKDisp = '五' THEN 5
ELSE 100
END
四、存儲過程格式
創建存儲過程
Create Proc dbo.存儲過程名
存儲過程參數
AS
執行語句
RETURN
執行存儲過程
GO
*********************************************************/
-- 變數的聲明,sql裡面聲明變數時必須在變數前加@符號
DECLARE @I INT
-- 變數的賦值,變數賦值時變數前必須加set
SET @I = 30
-- 聲明多個變數
DECLARE @s varchar(10),@a INT
-- Sql 里if語句
IF 條件 BEGIN
執行語句
END
ELSE BEGIN
......>>
問題二:為什麼要使用存儲過程? 幾個去 IBM 面試的兄弟回來抱怨:去了好幾個不同的 IBM項目組,幾乎每個面試官問到資料庫的時候都要問用沒用過存儲過程,煩人不?大家去面的程序員,又不是筆者認為,存儲過程說白了就是一堆 SQL 的合並。中間加了點邏輯控制。但是存儲過程處理比較復雜的業務時比較實用。比如說,一個復雜的數據操作。如果你在前台處理的話。可能會涉及到多次資料庫連接。但如果你用存儲過程的話。就只有一次。從響應時間上來說有優勢。也就是說存儲過程可以給我們帶來運行效率提高的好處。另外,程序容易出現 BUG數據量小的,或者和錢沒關系的項目不用存儲過程也可以正常運作。mysql 的存儲過程還有待實際測試。如果是正式項目,建議你用 sqlserver 或 oracle的存儲過程。數據與數據之間打交道的話,過程會比程序來的快的多。面試官問有沒有用存儲,實際上就是想知道前來面試的程序員到底做過數據量大的項目沒。如果是培訓出來的,或者小項目小公司出來的,對存儲肯定接觸的少了。所以,要想進大公司,沒有豐富存儲過程經驗,是不行的。錯。存儲過程不僅僅適用於大型項目,對於中小型項目,使用存儲過程也是非常有必要的。其威力和優勢主要體現在:1.存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般 SQL語句每執行一次就編譯一次,所以使用存儲過程可提高資料庫執行速度。2.當對資料庫進行復雜操作時(如對多個表進行Update,Insert,Query,Delete時),可將此復雜操作用存儲過程封裝起來與資料庫提供的事務處理結合一起使用。這些操作,如果用程序來完成,就變成了一條條的 SQL語句,可能要多次連接資料庫。而換成存儲,只需要連接一次資料庫就可以了。3.存儲過程可以重復使用,可減少資料庫開發人員的工作量。4.安全性高,可設定只有某此用戶才具有對指定存儲過程的使用權。存儲過程的缺點1:調試麻煩,但是用 PL/SQL Developer 調試很方便!彌補這個缺點。 2:移植問題,資料庫端代碼當然是與資料庫相關的。但是如果是做工程型項目,基本不存在移植問題。 3:重新編譯問題,因為後端代碼是運行前編譯的,如果帶有引用關系的對象發生改變時,受影響的存儲過程、包將需要重新編譯(不過也可以設置成運行時刻自動編譯)。4:如果在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨著用戶需求的增加會導致數據結構的變化,接著就是系統的相關問題了,最後如果用戶想維護該系統可以說是很難很難、而且代價是空前的。維護起來更加麻煩!
問題三:oracle中的存儲過程,有什麼作用,以及怎麼在代碼中使用? 樓上也不知道從哪扒下來的,一看LZ就是初學,舉點例子不行嗎?
比如建立個測試表
create table test(id int,name varchar2(10),counts int); insert into test values (1,'張三',100);insert into test values (2,'李四',200); mit;
現在給你出個題目是
查詢所有人加在一起的counts是多少
創建存儲過程
create or replace p_test --創建存儲過程,asv_counts int;--定義變數begin --開始select sum(counts) into v_counts from test;--將得到的結果放到變數里DBMS_OUTPUT.PUT_LINE(v_counts);--將結果列印輸出end;--結束
執行這種不帶輸入參數的
begin p_test;end;
然後你檢查下結果
再給你創建一個帶輸入參數的
題目是,查詢id為1的人名是什麼
create or replace p_test1(v_id int)asv_name varchar2(10);beginselect name into v_name from test where id=v_id;DBMS_OUTPUT.PUT_LINE(v_name);end;
執行時這樣
beginp_test1(1);end;
第2個我沒給你寫注釋,你看你自己應該能理解吧
補充一下,存儲過程不一定只是執行查詢,也可以做刪除或者修改等sql語句,總體來說就是幾個或N個sql語句的 *** ,來完成系統內某些特定的需求,這些需求可以是一個sql搞定的,也可以是多個sql組合的
問題四:SQL 存儲過程建立和使用方法? Sql Server的存儲過程是一個被命名的存儲在伺服器上的Transacation-Sql語句 *** ,是封裝重復性工作的一種方法,它支持用戶聲明的變數、條件執行和其他強大的編程功能。 存儲過程相對於其他的資料庫訪問方法有以下的優點: (1)重復使用。存儲過程可以重復使用,從而可以減少資料庫開發人員的工作量。 (2)提高性能。存儲過程在創建的時候就進行了編譯,將來使用的時候不用再重新編譯。一般的SQL語句每執行一次就需要編譯一次,所以使用存儲過程提高了效率。 (3)減少網路流量。存儲過程位於伺服器上,調用的時候只需要傳遞存儲過程的名稱以及參數就可以了,因此降低了網路傳輸的數據量。 (4)安全性。參數化的存儲過程可以防止SQL注入式的攻擊,而且可以將Grant、Deny以及Revoke許可權應用於存儲過程。 存儲過程一共分為了三類:用戶定義的存儲過程、擴展存儲過程以及系統存儲過程。 其中,用戶定義的存儲過程又分為Transaction-SQL和CLR兩種類型。 Transaction-SQL 存儲過程是指保存的Transaction-SQL語句 *** ,可以接受和返回用戶提供的參數。 CLR存儲過程是指對.Net Framework公共語言運行時(CLR)方法的引用,可以接受和返回用戶提供的參數。他們在.Net Framework程序集中是作為類的公共靜態方法實現的。(本文就不作介紹了) 創建存儲過程的語句如下:Code
CREATE { PROC | PROCEDURE } [schema_name.] procere_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ [ OUT [ PUT ]
] [ ,n ]
[ WITH [ ,n ]
[ FOR REPLICATION ]
AS { [;][ n ] | }
[;]
::=
[ ENCRYPTION ]
[ REPILE ]
[ EXECUTE_AS_Clause ]
::=
{ [ BEGIN ] statements [ END ] }
::=
EXTERNAL NAME assembly_name.class_name.method_name [schema_name]: 代表的是存儲過程所屬的架構的名稱 例如: Create Schema yangyang8848
Go
Create Proc yangyang8848.AllGoods
As Select * From Master_Goods
Go 執行:Exec AllGoods 發生錯誤。 執......>>
問題五:資料庫中的存儲過程怎麼用 啊!!求解..... 10分 關鍵字:procere
例子:
SQL> create [or replace] procere procere_name is
begin
--開始執行
insert into test('10001','Visket');
end;
/
以上操作就能為test表添加一條信息
執行存儲過程procere用的命令是exec
記住存儲過程中,語句結尾一定要有分號
問題六:存儲過程是多用還是少用? 做項目的時候我們有時候會面臨一個選擇,我們到底是應該多寫存儲過程還是少寫存儲過程了?這個問題的爭論也是由來已久,在不同的公司以及不同的技術負責人那裡往往會得到不同的答案。在實際項目中我們最後所採取的方式,往往不外乎以下三種方式。
第一種方式是要求所有資料庫操作不使用任何的存儲過程,所有操作都採用標准sql語句來完成,即便是一個動作需要完成多步資料庫操作,也不使用任何存儲過程,而是在程序代碼中採用事務的方式來完成;第二種方式就是就要求所有的資料庫操作都用存儲過程封裝起來,哪怕是一個最簡單的insert 操作。在程序代碼看不到一行 sql語句,如果採用分工合作的方式,程序員甚至都可以不懂sql語法。第三種方式是一般相對簡單的資料庫操作採用標准sql語句來完成,一些相對比較復雜的商務邏輯用存儲過程來完成。
當然系統如果採用了hibernate或nhibernate之類的框架,不需要寫sql語句的時候,我想還是應該屬於第三種方式,因為在開發的時候hibernate框架允許我們在適當的時候,拋開其框架自己寫存儲過程和sql語句來完成資料庫操作。其實這三種方式都各有所長,也各有不足。
第一種方式是所有的資料庫操作都採用標准sql語句來完成的方式,在程序的執行效率上是肯定不如後面兩種方式,系統如果是一個大型的ERP,這種方式就是絕對不可取的。因為在開發基本結束後,系統如果需要優化或者希望得到優化時,那對開發人員來說就是一件非常麻煩的事情了,因為優化的重點基本上都是集中資料庫操作上,開發人員所能做的就是一個個sql語句去檢查,是不是還能進一步優化,尤其是一些相對比較復雜的查詢語句是我們所檢查的重點。分頁顯示就是一個典型的存儲過程提高程序效率的例子。如果使用存儲過程來進行分頁操作,就是利用存儲過程從系統中提取我們所需要的記錄集,分頁的效率就大大提高了。反過來如果我們不用存儲過程進行分頁操作,是利用sql語句的方式把所有記錄集都讀入內存中,然後再從內存中獲取我們所需要的記錄 *** ,這樣分頁效率自然就降低了。當然利用sql語句也能得到我們所需要的記錄,而不是所有記錄,但是那樣麻煩多了,不在我們討論范圍之內。
這種方式另外還有一個不足之處,一個系統或一個項目總會或多或少地存在有一些容易變化而又復雜的商務邏輯,如果把這些復雜的商務邏輯封裝到存儲過程中,商務邏輯的變化都只涉及存儲過程變化,而與程序代碼不 *** ,那麼不用存儲過程太可惜了。
這種方式雖然有不足,但是一旦採用這種方式的話,我們如果對該項目進行資料庫移植的時候,開發人員就會覺得當時的決策人是多麼的偉大與英明。而且我們知道access和mysql的以前版本是不提供存儲過程支持的,所有一些中小項目在這個方面的選擇往往也是不得已而為之。不用存儲過程有一個優點,調試代碼的時候沒有存儲過程可是要方便很多很多的哦,所以在很多很多的項目中都是採用標準的sql語句而不使用任何的存儲過程。這可是大多程序員用標准sql而不用存儲過程的直接原因,說白了,就是嫌麻煩。
第二種方式是所有的資料庫操作全部採用存儲過程封裝的方式,如果採用這種方式,程序的執行效率相對要高,尤其面對在一些復雜的商務邏輯時候,不僅在效率方面有明顯的提高,而且當商務邏輯發生變化時,我們開發人員做相應的修改的時候,往往都不用修改程序代碼,僅僅修改存儲過程就能滿足系統變化了。
還有一個好處就是當我們開發好的一個系統後,如果發現一種模式或語言在某些方面難以滿足需求時,我們就可以很快的用兩外一種語言來重新開發,那個時候就非常方便了。比如在02年中科院下屬的一個公司就用ASP開......>>
問題七:在SQL中存儲過程的一般語法是什麼? sql server存儲過程語法
存儲過程就是作為可執行對象存放在資料庫中的一個或多個SQL命令。
定義總是很抽象。存儲過程其實就是能完成一定操作的一組SQL語句,只不過這組語句是放在資料庫中的(這里我們只談SQL Server)。如果我們通過創建存儲過程以及在ASP中調用存儲過程,就可以避免將SQL語句同ASP代碼混雜在一起。這樣做的好處至少有三個:
第一、大大提高效率。存儲過程本身的執行速度非常快,而且,調用存儲過程可以大大減少同資料庫的交互次數。
第二、提高安全性。假如將SQL語句混合在ASP代碼中,一旦代碼失密,同時也就意味著庫結構失密。
第三、有利於SQL語句的重用。
在ASP中,一般通過mand對象調用存儲過程,根據不同情況,本文也介紹其它調用方法。為了方便說明,根據存儲過程的輸入輸出,作以下簡單分類:
1. 只返回單一記錄集的存儲過程
假設有以下存儲過程(本文的目的不在於講述T-SQL語法,所以存儲過程只給出代碼,不作說明):
/*SP1*/
CREATE PROCEDURE dbo.getUserList
as
set nocount on
begin
select * from dbo.[userinfo]
end
go
以上存儲過程取得userinfo表中的所有記錄,返回一個記錄集。通過mand對象調用該存儲過程的ASP代碼如下:
'**通過mand對象調用存儲過程**
DIM Mym,MyRst
Set Mym = Server.CreateObject(ADODB.mand)
Mym.ActiveConnection = MyConStr 'MyConStr是資料庫連接字串
Mym.mandText = getUserList '指定存儲過程名
Mym.mandType = 4 '表明這是一個存儲過程
Mym.Prepared = true '要求將SQL命令先行編譯
Set MyRst = Mym.Execute
Set Mym = Nothing
存儲嘩程取得的記錄集賦給MyRst,接下來,可以對MyRst進行操作。
在以上代碼中,mandType屬性表明請求的類型,取值及說明如下:
-1 表明mandText參數的類型無法確定
1 表明mandText是一般的命令類型
2 表明mandText參數是一個存在的表名稱
4 表明mandText參數是一個存儲過程的名稱
還可以通過Connection對象或Recordset對象調用存儲過程,方法分別如下:
'**通過Connection對象調用存儲過程**
DIM MyConn,MyRst
Set MyConn = Server.CreateObject(&qu......>>
問題八:如何使用Oracle存儲過程的一個簡單例子 樓主您好
---創建表
create table TESTTABLE
(
id1 VARCHAR2(12),
name VARCHAR2(32)
)
select t.id1,t.name from TESTTABLE t
insert into TESTTABLE (ID1, NAME)
values ('1', 'zhangsan');
insert into TESTTABLE (ID1, NAME)
values ('2', 'lisi');
insert into TESTTABLE (ID1, NAME)
values ('3', 'wangwu');
insert into TESTTABLE (ID1, NAME)
values ('4', 'xiaoliu');
insert into TESTTABLE (ID1, NAME)
values ('5', 'laowu');
---創建存儲過程
create or replace procere test_count
as
v_total number(1);
begin
select count(*) into v_total from TESTTABLE;
DBMS_OUTPUT.put_line('總人數:'||v_total);
end;
--准備
--線對scott解鎖:alter user scott account unlock;
--應為存儲過程是在scott用戶下。還要給scott賦予密碼
---alter user scott identified by tiger;
---去命令下執行
EXECUTE test_count;
----在ql/spl中的sql中執行
begin
-- Call the procere
test_count;
end;
create or replace procere TEST_LIST
AS
---是用游標
CURSOR test_cursor IS select t.id1,t.name from TESTTABLE t;
begin
for Test_record IN test_cursor loop---遍歷游標,在列印出來
DBMS_OUTPUT.put_line(Test_record.id1||Test_record.name);
END LOOP;
test_count;--同時執行另外一個存儲過程(TEST_LIST中包含存儲過程test_count)
end;
-----執行存儲過程TEST_LIST
begin
TEST_LIST;
END;
---存儲過程的參數
---IN 定義一個輸入參數變數,用於傳遞參數給存儲過程
--OUT 定義一個輸出參數變數,用於從存儲過程獲取數據
---IN OUT 定義一個輸入、輸出參數變數,兼有以上兩者的功能
......>>
問題九:如何使用sql語句查看存儲過程 --下面這條語句可以查看存儲過程具體代碼exec sp_helptext 存儲過程名--下面這條語句查看資料庫中有哪些存儲過程select * from sysobjects where type='P'
問題十:存儲過程中怎麼使用row 一般分為十種情況,每種語法各不相同: 1、 創建語法create proc | procere pro_name [{@參數數據類型} [=默認值] [output], {@參數數據類型} [=默認值] [output], .... ]as SQL_statements2、 創建不帶參數存儲過程--創建存儲過程if (exists (select * from sys.objects where name = 'proc_get_student')) drop proc proc_get_studentgocreate proc proc_get_studentas select * from student;--調用、執行存儲過程exec proc_get_student;3、 修改存儲過程--修改存儲過程alter proc proc_get_studentasselect * from student;4、 帶參存儲過程--帶參存儲過程if (object_id('proc_find_stu', 'P') is not null) drop proc proc_find_stugocreate proc proc_find_stu(@startId int, @endId int)as select * from student where id between @startId and @endIdgoexec proc_find_stu 2, 4;5、 帶通配符參數存儲過程--帶通配符參數存儲過程if (object_id('proc_findStudentByName', 'P') is not null) drop proc proc_findStudentByNamegocreate proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')as select * from student where name like @name and name like @nextName;goexec proc_findStudentByName;exec proc_findStudentByName '%o%', 't%';6、 帶輸出參數存儲過程if (object_id('proc_getStudentRecord', 'P') is not null) drop proc proc_getStudentRecordgocreate proc proc_getStudentRecord( @id int, --默認輸入參數 @name varchar(20) out, --輸出參數 @age varchar(20) output--輸入輸出參數)as select @name = name, @age = age from student where id = @id and sex = @age;go-- declare @id int, @name varchar(20), @temp varchar(20)......>>