- 論壇徽章:
- 0
|
PostgreSQL PL/pgSQL虛擬機(jī)實(shí)現(xiàn)
閆華 postgres_fan@yahoo.com.cn
1前言
PostgreSQL是當(dāng)今最為先進(jìn)的開(kāi)源數(shù)據(jù)庫(kù)管理系統(tǒng),PL/pgSQL是PostgreSQL中最重要的過(guò)程語(yǔ)言,它類似于Oracle的PL/SQL,用戶可以用它來(lái)創(chuàng)建觸發(fā)器和用戶自定義函數(shù)。
PostgreSQL使用一個(gè)虛擬機(jī)來(lái)運(yùn)行PL/pgSQL函數(shù),該虛擬機(jī)是解釋型的虛擬機(jī),沒(méi)有類似于機(jī)器語(yǔ)言的指令集,在編譯過(guò)程結(jié)束以后,直接以語(yǔ)法樹(shù)為基礎(chǔ)運(yùn)行PL/pgSQL函數(shù)。
2 PL/pgSQL簡(jiǎn)介
PL/pgSQL 是塊結(jié)構(gòu)的語(yǔ)言。完整的函數(shù)定義必須是一個(gè)塊。
下面是一個(gè)用PL/pgSQL編寫(xiě)的函數(shù)的實(shí)例:
CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30
quantity := 50;
--
-- Create a subblock
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80
RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
END;
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50
RETURN quantity;
END;
$$ LANGUAGE plpgsql;
有關(guān)PL/pgSQL的詳細(xì)的語(yǔ)法介紹,可以去查看官方文檔,此處不再贅述。
3虛擬機(jī)工作流程
當(dāng)用戶使用CREATE FUNCTION函數(shù)創(chuàng)建一個(gè)PL/pgSQ函數(shù)以后,PostgreSQL首先編譯該函數(shù),如果沒(méi)有錯(cuò)誤,該函數(shù)的源代碼將被存放到系統(tǒng)表pg_proc中。當(dāng)用戶要執(zhí)行一個(gè)已將創(chuàng)建好的函數(shù)時(shí),PostgreSQL首先從系統(tǒng)表pg_proc取出該函數(shù)的源代碼,重新編譯源代碼,然后根據(jù)編譯生成的語(yǔ)法樹(shù),運(yùn)行該函數(shù)。因?yàn)榫幾g源代碼是一個(gè)消耗大量CPU資源的操作,PostgreSQL在啟動(dòng)以后,數(shù)據(jù)庫(kù)內(nèi)部會(huì)建立一個(gè)緩沖區(qū),其中存放編譯過(guò)的PL/pgSQ函數(shù)的語(yǔ)法樹(shù)。每次在編譯一個(gè)PL/pgSQ函數(shù)的時(shí)候,首先檢查緩沖區(qū),看看該函數(shù)是否已經(jīng)被編譯過(guò),如果已經(jīng)被編譯過(guò),則從緩沖區(qū)中直接取出它的語(yǔ)法樹(shù),這樣便可以省去重新編譯的過(guò)程,提高執(zhí)行的效率。 |
|