㈠ 存儲過程和函數的區別
一、含義不同
1、存儲過程:存儲過程是 sql 語句和可選控制流語句的預編譯集合,以一個名稱存儲並作為一個單元處理。
2、函數:是由一個或多個 SQL 語句組成的子程序,可用於封裝代碼以便重新使用。函數限制比較多,如不能用臨時表,只能用表變數等
二、使用條件不同
1、存儲過程:可以在單個存儲過程中執行一系列 SQL 語句。而且可以從自己的存儲過程內引用其它存儲過程,這可以簡化一系列復雜語句。
2、函數:自定義函數諸多限制,有許多語句不能使用,許多功能不能實現。函數可以直接引用返回值,用表變數返回記錄集。但是,用戶定義函數不能用於執行一組修改全局資料庫狀態的操作。
三、執行方式不同
1、存儲過程:存儲過程可以返回參數,如記錄集,函數只能返回值或者表對象。存儲過程的參數有in,out,inout三種,存儲過程聲明時不需要返回類型。
2、函數:函數參數只有in,而函數需要描述返回類型,且函數中必須包含一個有效的return語句。
㈡ SQL SERVER 中存儲過程和函數的區別
一、多數指令是相同的,包括創建和修正存儲過程的指令。二、很多細微的指令有不同,具體如下(不僅):1mysql支持enum,和set類型,sqlserver不支持2mysql不支持nchar,nvarchar,ntext類型3mysql的遞增語句是AUTO_INCREMENT,而mssql是identity(1,1)MYSQL:createtablebasic(idintkeyauto_increment,namevarchar(20));MSSQL:createtablebasic(idintidentity(1,1),namevarchar(20))4msms默認到處表創建語句的默認值表示是((0)),而在mysql裡面是不允許帶兩括弧的5mysql需要為表指定存儲類型6mssql識別符是[],[type]表示他區別於關鍵字(可選用來包含表名、欄位名),但是mysql卻是`(重音符,也就是按鍵1左邊的那個符號)7mssql支持getdate()方法獲取當前時間日期,但是mysql裡面可以分日期類型和時間類型,獲取當前日期是cur_date(),當前完整時間是now()函數8mssql不支持replaceinto語句,但是在最新的sql20008裡面,也支持merge語法9mysql支持insertintotable1sett1=『』,t2=『』,但是mssql不支持這樣寫10mysql插入多行支持這樣寫insertintotabl1values(1,1),(1,1),(1,1),(1,1),(1,1),(1,1),(1,1)MSSQL不支持11mssql不支持limit語句,是非常遺憾的,只能用top取代limt0,N,row_number()over()函數取代limitN,M12mysql在創建表時要為每個表指定一個存儲引擎類型,而mssql只支持一種存儲引擎13mysql不支持默認值為當前時間的datetime類型(mssql很容易做到),在mysql裡面是用timestamp類型14mssql裡面檢查是否有這個表再刪除,需要這樣:ifexists(select*fromdbo.sysobjectswhereid=object_id(N'uc_newpm')andOBJECTPROPERTY(id,N'IsUserTable')=1)但是在mysql裡面只需要DROPTABLEIFEXISTScdb_forums;15mysql支持無符號型的整數,那麼比不支持無符號型的mssql就能多出一倍的最大數存儲16mysql不支持在mssql裡面使用非常方便的varchar(max)類型,這個類型在mssql裡面既可做一般數據存儲,也可以做blob數據存儲17mysql創建非聚集索引只需要在創建表的時候指定為key就行,比如:KEYdisplayorder(fid,displayorder)在mssql裡面必須要:_uc_protectedmembers_username_appidondbo.uc_protectedmembers(usernameasc,appidasc)18mysqltext欄位類型不允許有默認值19mysql的一個表的總共欄位長度不超過65XXX。20一個很表面的區別就是mysql的安裝特別簡單,而且文件大小才110M(非安裝版),相比微軟這個龐然大物,安裝進度來說簡直就是..21mysql的管理工具有幾個比較好的,mysql_front,和官方那個套件,不過都沒有SSMS的使用方便,這是mysql很大的一個缺點。22mysql的存儲過程只是出現在最新的版本中,穩定性和性能可能不如mssql。23同樣的負載壓力,mysql要消耗更少的CPU和內存,mssql的確是很耗資源。24php連接mysql和mssql的方式都差不多,只需要將函數的mysql替換成mssql即可。25mysql支持date,time,year類型,mssql到2008才支持date和time。26變數賦值MYsql:變數賦值SELECT@min_price:=MIN(price),@max_price:=MAX(price)FROMshopMSsql:變數賦值SELECT@min_price=MIN(price),@max_price=MAX(price)FROMshop三、總的來說,如果是簡單的存儲過程代碼,要修改,不會太難。如果是復雜的系統,要移植會很難很難。
㈢ mysql存儲過程 和 觸發器的優缺點 問題
缺點是觸發器的缺點,
而有點是存儲過程的優點,
所以推薦使用存儲過程。
㈣ mysql 與oracle中的存儲過程及函數有什麼區別,盡可能詳細哦
本質上沒區別。只是函數有如:只能返回一個變數的限制。而存儲過程可以返回多個。而函數是可以嵌入在sql中使用的,可以在select中調用,而存儲過程不行。執行的本質都一樣。
函數限制比較多,比如不能用臨時表,只能用表變數.還有一些函數都不可用等等.而存儲過程的限制相對就比較少
由於我現在基本上是DBA的工作,因此平時也看一些資料庫方面的書籍。但是我一直對存儲過程和函數之間的區別掌握不透。我向來認為存儲過程可以實現的操作,函數也一樣可以實現。最近,剛好大學的老師給我們上SQL-Server的課程,我對這個問題的疑惑終於慢慢解開。今天晚上順便看了些網上的資料,覺得以下分析比較合理:
1. 一般來說,存儲過程實現的功能要復雜一點,而函數的實現的功能針對性比較強。
2. 對於存儲過程來說可以返回參數,而函數只能返回值或者表對象。
3. 存儲過程一般是作為一個獨立的部分來執行,而函數可以作為查詢語句的一個部分來調用,由於函數可以返回一個表對象,因此它可以在查詢語句中位於FROM關鍵字的後面。
4. 當存儲過程和函數被執行的時候,SQL Manager會到procere cache中去取相應的查詢語句,如果在procere cache里沒有相應的查詢語句,SQL Manager就會對存儲過程和函數進行編譯。
Procere cache中保存的是執行計劃 (execution plan) ,當編譯好之後就執行procere cache中的execution plan,之後SQL SERVER會根據每個execution plan的實際情況來考慮是否要在cache中保存這個plan,評判的標准一個是這個execution plan可能被使用的頻率;其次是生成這個plan的代價,也就是編譯的耗時。保存在cache中的plan在下次執行時就不用再編譯了。
存儲過程和用戶自定義函數具體的區別
存儲過程
存儲過程可以使得對資料庫的管理、以及顯示關於資料庫及其用戶信息的工作容易得多。存儲過程是 SQL 語句和可選控制流語句的預編譯集合,以一個名稱存儲並作為一個單元處理。存儲過程存儲在資料庫內,可由應用程序通過一個調用執行,而且允許用戶聲明變數、有條件執行以及其它強大的編程功能。
存儲過程可包含程序流、邏輯以及對資料庫的查詢。它們可以接受參數、輸出參數、返回單個或多個結果集以及返回值。
可以出於任何使用 SQL 語句的目的來使用存儲過程,它具有以下優點:
可以在單個存儲過程中執行一系列 SQL 語句。
可以從自己的存儲過程內引用其它存儲過程,這可以簡化一系列復雜語句。
存儲過程在創建時即在伺服器上進行編譯,所以執行起來比單個 SQL 語句快。
用戶定義函數
函數是由一個或多個 Transact-SQL 語句組成的子程序,可用於封裝代碼以便重新使用。Microsoft? SQL Server? 2000 並不將用戶限制在定義為 Transact-SQL 語言一部分的內置函數上,而是允許用戶創建自己的用戶定義函數。
可使用 CREATE FUNCTION 語句創建、使用 ALTER FUNCTION 語句修改、以及使用 DROP FUNCTION 語句除去用戶定義函數。每個完全合法的用戶定義函數名 (database_name.owner_name.function_name) 必須唯一。
必須被授予 CREATE FUNCTION 許可權才能創建、修改或除去用戶定義函數。不是所有者的用戶在 Transact-SQL 語句中使用某個函數之前,必須先給此用戶授予該函數的適當許可權。若要創建或更改在 CHECK 約束、DEFAULT 子句或計算列定義中引用用戶定義函數的表,還必須具有函數的 REFERENCES 許可權。
函數中的有效語句類型包括:
DECLARE 語句,該語句可用於定義函數局部的數據變數和游標。
為函數局部對象賦值,如使用 SET 給標量和表局部變數賦值。
游標操作,該操作引用在函數中聲明、打開、關閉和釋放的局部游標。不允許使用 FETCH 語句將數據返回到客戶端。僅允許使用 FETCH 語句通過 INTO 子句給局部變數賦值。
控制流語句。
SELECT 語句,該語句包含帶有表達式的選擇列表,其中的表達式將值賦予函數的局部變數。
INSERT、UPDATE 和 DELETE 語句,這些語句修改函數的局部 table 變數。
EXECUTE 語句,該語句調用擴展存儲過程。
在查詢中指定的函數的實際執行次數在優化器生成的執行計劃間可能不同。示例為 WHERE 子句中的子查詢喚醒調用的函數。子查詢及其函數執行的次數會因優化器選擇的訪問路徑而異
㈤ MySQL存儲函數和存儲過程的區別
區別主要在於:
1、存儲過程沒有返回值,而函數必須有返回值;
2、存儲過程的參數可以是IN、OUT、INOUT類型,而函數的參數只能是IN類型。
㈥ MySQL的存儲過程和存儲函數(UDF)的區別
背景
在上一篇推文中,我們介紹了 MySQL Group Replication 8.0.16 支持信息碎片化功能來增強大型事務處理能力。
如果您想在組復制中使用該功能,則任何組成員的版本都不能低於 8.0.16!
簡單地說就是由於低版本協議上不支持。MySQL 8.0.16 的組通訊開始支持新協議,簡稱「分段協議」,之前的版本中只有一種「壓縮協議」。
如果多個成員想加入復制組,那麼在協議匹配上遵循以下原則:
現有復制組成員和新加入成員版本相同,加入成功。
低版本成員想加入高版本的組會被驅逐,加入失敗。
高版本的成員想加入低版本的組,單獨加入成功,多個加入失敗。
一個 MySQL Server 8.0.16 實例可以成功加入使用通信協議版本 5.7.24 的組。
一個 MySQL Server 5.7.24 實例無法成功加入使用通信協議版本 8.0.16 的組。
兩個 MySQL Server 8.0.16 實例無法同時加入使用通信協議版本 5.7.24 的組。
兩個 MySQL Server 8.0.16 實例可以同時加入使用通信協議版本 8.0.16 的組。
SELECT group_replication_set_communication_protocol("8.0.15");
SELECT group_replication_get_communication_protocol(); +------------------------------------------------+ | group_replication_get_communication_protocol() | +------------------------------------------------+ | 5.7.14 | +------------------------------------------------+
例如:
新增 UDF
為了能讓高版本的復制組更便於加入低版本的成員,MySQL 8.0.16 新增兩個 UDF。
您可以使用兩個新的 UDF 命令去管理組通信協議:
1. group_replication_set_communication_protocol(new_protocol)
設置組復制通訊協議版本
填入一個所有成員都支持的版本號,即:new_protocol ≤ 所有成員的 MySQL版本。
new_protocol 格式:major.minor.patch (主版本號.次版本號.發布版本號)例如:8.0.15。
2. group_replication_get_communication_protocol()
獲取復制中最舊成員的 MySQL 版本號
獲取的版本號可能與設置的值不一致,但不一致的版本之間組復制協議是一樣的。
返回結果格式:major.minor.patch (主版本號.次版本號.發布版本號)例如:8.0.15。
以上兩個 UDF 對全部組成員有效,主機或從機上均可執行。
結論
若想使用信息碎片功能。建議將組復製成員全部升級為 8.0.16。
若組內成員版本僅有部分為 8.0.16,可以用兩個新的函數來讓高版本的成員保持與其它成員組協議一致。
㈦ 1,存儲過程和函數的區別
存儲過程和函數目的是為了 可重復地 執行操作資料庫的sql語句的集合。
區別是寫法和調用上。
寫法上:存儲過程的參數列表可以有輸入參數、輸出參數、可輸入輸出的參數;
函數的參數列表只有輸入參數,並且有return <返回值類型,無長度說明>。
返回值上:
存儲過程的返回值,可以有多個值,
函數的返回值,只有一個值。
調用方式上:
存儲過程的調用方式有:
1)、exec <過程名>;
2)、execute <過程名>;
3)、在PL/SQL語句塊中直接調用。
函數的調用方式有:
在PL/SQL語句塊中直接調用。
具體分為:
----調用FUNCTION add_three_numbers
----1. 位置表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(2,4,5));
END;
----2. 命名表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(b=>3, a=>4,c=>2));
END;
----3. 混合使用位置表示法和命名表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(3, b=>4,c=>2));
END;
----4. 排除表示法
BEGIN
dbms_output.put_line(add_three_numbers(12,c=>2));
END;
----5. sql調用表示法 --混合表示法
SELECT add_three_numbers(3, b=>4,c=>2) FROM DUAL;
----1. 該函數接受3個可選參數,返回3個數字的和
CREATE OR REPLACE FUNCTION add_three_numbers
(
a NUMBER:=0, b NUMBER:=0, c NUMBER:=0
)
RETURN NUMBER IS
BEGIN
RETURN a+b+c;
END;
存儲過程:
基本語法:
create procere <過程名>(<參數列表,無參時忽略>)
as|is
變數聲明、初始化
begin
業務處理、邏輯代碼
exception
異常捕獲、容錯處理
end <過程名>;
參數:<參數名> in|out|in out <參數類型,無長度說明> ,如:v_name varchar2
in:入參
out:出參
in out:出入參
註:as|is表示as或is
調用語法:
1)、exec <過程名>;
2)、execute <過程名>;
3)、在PL/SQL語句塊中直接調用。
例:
create or replace procere up_wap(v_param1 in out varchar2,v_param2 in out varchar2)
is
v_temp varchar2(20);
begin
dbms_output.put_line('交換前參數1:'||v_param1||' 參數2:'||v_param2);
v_temp:=v_param1;
v_param1:=v_param2;
v_param2:=v_temp;
dbms_output.put_line('交換後參數1:'||v_param1||' 參數2:'||v_param2);
exception
when others then dbms_output.put_line('There is a error when the procere up_wap executing!');
end up_wap;
/
-- 調用存儲過程
declare
v_param1 varchar2(20):='param1';
v_param2 varchar2(20):='param2';
begin
up_wap(v_param1 => v_param1,v_param2 => v_param2);
end;
/
自定義函數(function)
基本語法:
create function <函數名>(<參數列表,無參時忽略>)
return <返回值類型,無長度說明>
as|is
變數聲明、初始化
begin
業務處理、邏輯代碼
return <返回的值>;
exception
異常捕獲、容錯處理
end <函數名>;
參數:in 入參
註:只有入參的類型。
在存儲過程和自定義函數中的參數的傳遞(入參和出參)不能使用%type或%rowtype匹配,不能使用空值null,但是存儲過程可以返回空值。
例:
create function uf_select_name_by_id_test(v_id in number)
return varchar2
is
v_name t_test.t_name%type;
begin
select t_name into v_name from t_test where t_id=v_id;
return v_name;
exception
when others then dbms_output.put_line('error');
end uf_select_name_by_id_test;
/
select uf_select_name_by_id_test(1) 姓名 from al;-- select調用
declare --pl/sql語句塊調用
v_name varchar2(20);
begin
v_name:=uf_select_name_by_id_test(1);
dbms_output.put_line('name = '||v_name);
end;
/