如何理解postgresql的存儲過程

在b/s系統(tǒng)的構(gòu)建過程中茂嗓,數(shù)據(jù)庫操作幾乎成為了一個(gè)必不可少的操作赁还。調(diào)用存儲過程實(shí)現(xiàn)數(shù)據(jù)庫操作使很多程序員使用的方法独悴,而且大多數(shù)的程序員都是能使用存儲過程就使用存儲過程耸袜,很少直接使用sql語句扇谣,所以存儲過程是很有用而且很重要的昧捷。

存儲過程簡介

存儲過程的定義:完成一定功能的可重復(fù)調(diào)用的程序

簡單的說,存儲過程是由一些sql語句和控制語句組成的被封裝起來的過程罐寨,它駐留在數(shù)據(jù)庫中靡挥,可以被客戶應(yīng)用程序調(diào)用,也可以從另一個(gè)過程或觸發(fā)器調(diào)用鸯绿。它的參數(shù)可以被傳遞和返回跋破。與應(yīng)用程序中的函數(shù)過程類似,存儲過程可以通過名字來調(diào)用瓶蝴,而且它們同樣有輸入?yún)?shù)和輸出參數(shù)幔烛。

根據(jù)返回值類型的不同,我們可以將存儲過程分為三類:返回記錄集的存儲過程囊蓝,返回?cái)?shù)值的存儲過程(也可以稱為標(biāo)量存儲過程)饿悬,以及行為存儲過程。顧名思義聚霜,返回記錄集的存儲過程的執(zhí)行結(jié)果是一個(gè)記錄集狡恬,典型的例子是從數(shù)據(jù)庫中檢索出符合某一個(gè)或幾個(gè)條件的記錄珠叔;返回?cái)?shù)值的存儲過程執(zhí)行完以后返回一個(gè)值,例如在數(shù)據(jù)庫中執(zhí)行一個(gè)有返回值的函數(shù)或命令弟劲;最后祷安,行為存儲過程僅僅是用來實(shí)現(xiàn)數(shù)據(jù)庫的某個(gè)功能,而沒有返回值兔乞,例如在數(shù)據(jù)庫中的更新和刪除操作汇鞭。

存儲過程的通俗解釋:你使用手機(jī)撥打A同事的手機(jī),需要一個(gè)一個(gè)號碼的輸入庸追,然后才能撥打
而如果你把這個(gè)號碼設(shè)置為快速撥號霍骄,那么你只要長按1(自己設(shè)置的數(shù)字鍵)就可以直接撥打電話了
把這個(gè)號碼設(shè)置為快速撥號的過程你就可以理解為創(chuàng)建存儲過程。

使用存儲過程的好處

相對于直接使用sql語句淡溯,在應(yīng)用程序中直接調(diào)用存儲過程有以下好處:

(1)減少網(wǎng)絡(luò)通信量读整。調(diào)用一個(gè)行數(shù)不多的存儲過程與直接調(diào)用sql語句的網(wǎng)絡(luò)通信量可能不會有很大的差別,可是如果存儲過程包含上百行sql語句咱娶,那么其性能絕對比一條一條的調(diào)用sql語句要高得多米间。

(2)執(zhí)行速度更快。有兩個(gè)原因:首先膘侮,在存儲過程創(chuàng)建的時(shí)候屈糊,數(shù)據(jù)庫已經(jīng)對其進(jìn)行了一次解析和優(yōu)化。其次琼了,存儲過程一旦執(zhí)行逻锐,在內(nèi)存中就會保留一份這個(gè)存儲過程,這樣下次再執(zhí)行同樣的存儲過程時(shí)表伦,可以從內(nèi)存中直接調(diào)用谦去。

(3)更強(qiáng)的適應(yīng)性:由于存儲過程對數(shù)據(jù)庫的訪問是通過存儲過程來進(jìn)行的,因此數(shù)據(jù)庫開發(fā)人員可以在不改動存儲過程接口的情況下對數(shù)據(jù)庫進(jìn)行任何改動蹦哼,而這些改動不會對應(yīng)用程序造成影響鳄哭。

(4) 布式工作:應(yīng)用程序和數(shù)據(jù)庫的編碼工作可以分別獨(dú)立進(jìn)行,而不會相互壓制纲熏。

由以上的分析可以看到妆丘,在應(yīng)用程序中使用存儲過程是很有必要的。

存儲過程的定義規(guī)范

一局劲,存儲過程的格式

Create or replace function 過程名(參數(shù)名 參數(shù)類型,…..) returns 返回值類型 as
                   $body$
 
                            //聲明變量
                            Declare
                            變量名變量類型勺拣;
                            如:
                            flag Boolean;
 
                            變量賦值方式(變量名類型 :=值;)
                            如:
                            str  text :=值; / str  text;  str :=值鱼填;
 
                            Begin
                                     函數(shù)體药有;
 
                             return 變量名; //存儲過程中的返回語句
 
                            End;
                   $body$
         Language plpgsql;

二,變量類型
有整數(shù)類型(Smallint,Int等)愤惰,浮點(diǎn)類型(float)苇经,時(shí)間類型(date,time,timestamp,interval),還有其他特殊類型比如inet宦言,point等扇单。
三,連接字符
Postgresql存儲過程中的連接字符使用的是"||"
四奠旺,控制結(jié)構(gòu)
使用LOOP蜘澜,EXIT,CONTINUE响疚,WHILE鄙信, 和FOR 語句,可以控制PL/pgSQL 函數(shù)重復(fù)一系列命令稽寒。需要使用的時(shí)候請查詳細(xì)資料扮碧。
五趟章,異常捕獲

EXCEPTION
WHEN 錯誤碼(如:STRING_DATA_RIGHT_TRUNCATION:字串?dāng)?shù)據(jù)右邊被截?cái)啵?THEN
        /**后臺打印錯誤信息*/
        RAISE NOTICE '錯吳信息';

或者錯誤碼為UNDEFINED_TABLE時(shí)可以執(zhí)行創(chuàng)建表的操作然后在入數(shù)據(jù)杏糙。

存儲過程的示例

例子1

/**
批量插入一批數(shù)據(jù),經(jīng)緯度字段值要滿足中國地理位置上的經(jīng)緯度范圍蚓土;
注:時(shí)間不能指定為同一時(shí)間宏侍,否則會掃描全表,導(dǎo)致性能低下蜀漆。下列腳本未考慮時(shí)間的分段谅河,采用的一個(gè)時(shí)間點(diǎn)。
*/
create or replace function intobatch() returns integer as
$body$
declare
    skyid integer;
    lot float;
         lat float;
         sex varchar;
         level integer;
         ctime int :=1325404914;
         num integer :=0;
         total integer :=0;
    begin
                   lot='73.6666666';
                   lat='3.8666666';
                   FOR skyid IN 404499817 ..404953416 loop
                             if(lot > 135.0416666) then
             lot=73.6666666;
                             end if;
                        if(lat > 53.5500000) then
             lat=3.8666666;
                             end if;
                             if(skyid%2 <> 0) then
                                                        sex='1';
                                                        level=0;
                             else
                                                        sex='2';
                                                        level=1;
                             end if;
 
                            INSERT INTO user_last_location(user_id,app_id,lonlat,sex,accurate_level,lonlat_point,create_time)
 
VALUES(skyid,2934,ST_GeomFromText('POINT('||lot||' '||lat||')',4326),sex,level,POINT(lot,lat),to_timestamp(ctime));
                           
                            lot=lot+0.1;
                            lat=lat+0.1;
                            skyid=skyid+1;
                           
        end loop;        
                   return skyid;  
    end
$body$
languageplpgsql;
 
SELECT *from intobatch();

例子2:此例子是審計(jì)的生產(chǎn)環(huán)境的例子

-- 存儲過程
CREATE OR REPLACE FUNCTION audit_event_partition_trigger()
RETURNS TRIGGER AS $$
DECLARE date_text TEXT;
DECLARE end_date_text TEXT;
DECLARE insert_statement TEXT;
BEGIN
    SELECT to_char(NEW.time_event, 'YYYY_MM_DD') INTO date_text;
    SELECT to_char(NEW.time_event + INTERVAL '1 DAY', 'YYYY_MM_DD') INTO end_date_text;
    insert_statement := 'INSERT INTO audit_event_' || date_text || ' VALUES($1.*)';
    EXECUTE insert_statement USING NEW;
    RETURN NULL;
    EXCEPTION
    WHEN UNDEFINED_TABLE
    THEN
        EXECUTE 
            'CREATE TABLE IF NOT EXISTS audit_event_'  || date_text || '(CHECK ( time_event >= ''' || date_text || ''' AND  time_event < '''|| end_date_text ||''' )) INHERITS (audit_event)';
        RAISE NOTICE 'CREATE NON-EXISTANT TABLE audit_event_%', date_text;
        EXECUTE
            'CREATE INDEX audit_event_' ||  date_text || '_event_msg_body ON audit_event_'  || date_text || ' USING gin(event_msg_body gin_trgm_ops); ' 
            || 'CREATE INDEX audit_event_' || date_text || '_gid ON audit_event_'  || date_text || ' USING btree(gid);' 
            || 'CREATE INDEX audit_event_' || date_text || '_id ON audit_event_'  || date_text || ' USING btree(id);' 
            || 'CREATE INDEX audit_event_' || date_text || '_module ON audit_event_'  || date_text || ' USING btree(module);' 
            || 'CREATE INDEX audit_event_' || date_text || '_access_time ON audit_event_'  || date_text || ' USING btree(access_time);' 
            || 'CREATE INDEX audit_event_' || date_text || '_mid ON audit_event_'  || date_text || ' USING btree(mid);' 
            || 'CREATE INDEX audit_event_'  || date_text || '_time_event ON audit_event_' || date_text || ' USING btree(time_event);';
        EXECUTE insert_statement USING NEW;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql

這個(gè)是由觸發(fā)器來引發(fā)執(zhí)行的存儲過程:

DROP TRIGGER IF EXISTS auto_insert_into_audit_event_tbl_partiton ON audit_event;
CREATE TRIGGER  auto_insert_into_audit_event_tbl_partiton BEFORE INSERT OR UPDATE ON  audit_event  
FOR EACH ROW
EXECUTE PROCEDURE audit_event_partition_trigger()

reference
對存儲過程的一些理解
簡單通俗的解釋一下存儲過程是干什么的
分表分庫設(shè)計(jì)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末确丢,一起剝皮案震驚了整個(gè)濱河市绷耍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鲜侥,老刑警劉巖褂始,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異描函,居然都是意外死亡崎苗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門舀寓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胆数,“玉大人,你說我怎么就攤上這事互墓”啬幔” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵篡撵,是天一觀的道長判莉。 經(jīng)常有香客問我齿诞,道長,這世上最難降的妖魔是什么骂租? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任祷杈,我火速辦了婚禮,結(jié)果婚禮上渗饮,老公的妹妹穿的比我還像新娘但汞。我一直安慰自己,他們只是感情好互站,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布私蕾。 她就那樣靜靜地躺著,像睡著了一般胡桃。 火紅的嫁衣襯著肌膚如雪踩叭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天翠胰,我揣著相機(jī)與錄音容贝,去河邊找鬼。 笑死之景,一個(gè)胖子當(dāng)著我的面吹牛斤富,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锻狗,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼满力,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了轻纪?” 一聲冷哼從身側(cè)響起油额,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刻帚,沒想到半個(gè)月后潦嘶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡我擂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年衬以,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片校摩。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡看峻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衙吩,到底是詐尸還是另有隱情互妓,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站冯勉,受9級特大地震影響澈蚌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灼狰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一宛瞄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧交胚,春花似錦份汗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熬词,卻和暖如春旁钧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背互拾。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工歪今, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摩幔。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓彤委,卻偏偏與公主長得像鞭铆,于是被迫代替她去往敵國和親或衡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法车遂,類相關(guān)的語法封断,內(nèi)部類的語法,繼承相關(guān)的語法舶担,異常的語法坡疼,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)衣陶,斷路器柄瑰,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    Joyyx閱讀 8,325評論 0 16
  • 靜語輕楓閱讀 687評論 0 1
  • 這個(gè)月明顯感覺自己松懈下來了,到今天28號剪况,只寫了9篇文章 相比上個(gè)月的22篇教沾,少了一半還多,還好有我們的007行...
    少東閱讀 1,456評論 1 2