新聞中心
怎么寫mysql數(shù)據(jù)庫(kù)延遲級(jí)聯(lián)刪除命令
使用 bcc 工具觀測(cè) MySQL:1)dbstat功能:將 MySQL/PostgreSQL 的查詢延遲匯總為直方圖
清水河網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,清水河網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為清水河1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的清水河做網(wǎng)站的公司定做!
語法:
dbstat [-h] [-v] [-p [PID [PID ...]]] [-m THRESHOLD] [-u] [-i INTERVAL] ? ? ? ? ? ? ?{mysql,postgres}
選項(xiàng):
{mysql,postgres} ? ? ? ? ? ? ? ? ? ? ? ? ? # 觀測(cè)哪種數(shù)據(jù)庫(kù)-h, --help ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 顯示幫助然后退出-v, --verbose ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 顯示BPF程序-p [PID [PID ...]], --pid [PID [PID ...]] ?# 要觀測(cè)的進(jìn)程號(hào),空格分隔-m THRESHOLD, --threshold THRESHOLD ? ? ? ?# 只統(tǒng)計(jì)查詢延遲比此閾值高的-u, --microseconds ? ? ? ? ? ? ? ? ? ? ? ? # 以微秒為時(shí)間單位來顯示延遲(默認(rèn)單位:毫秒)-i INTERVAL, --interval INTERVAL ? ? ? ? ? # 打印摘要的時(shí)間間隔(單位:秒)
示例:
# 使用 sysbench 在被觀測(cè)數(shù)據(jù)庫(kù)上執(zhí)行 select[root@liuan tools]# dbstat mysql -p `pidof mysqld` -uTracing database queries for pids 3350 slower than 0 ms...^C[14:42:26] ? ? query latency (us)
2)dbslower
功能:跟蹤 MySQL/PostgreSQL 的查詢時(shí)間高于閾值
語法:
dbslower [-h] [-v] [-p [PID [PID ...]]] [-x PATH] [-m THRESHOLD] ? ? ? ? ? ? ? ? {mysql,postgres}
參數(shù):
{mysql,postgres} ? ? ? ? ? ? ? ? ? ? ? ? ? # 觀測(cè)哪種數(shù)據(jù)庫(kù) -h, --help ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 顯示幫助然后退出 -v, --verbose ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 顯示BPF程序 -p [PID [PID ...]], --pid [PID [PID ...]] ?# 要觀測(cè)的進(jìn)程號(hào),空格分隔 -m THRESHOLD, --threshold THRESHOLD ? ? ? ?# 只統(tǒng)計(jì)查詢延遲比此閾值高的 -x PATH, --exe PATH ? ? ? ? ? ? ? ? ? ? ? ?# 數(shù)據(jù)庫(kù)二進(jìn)制文件的位置
示例:
# 使用sysbench在被觀測(cè)數(shù)據(jù)庫(kù)上執(zhí)行update_index [root@liuan tools]# dbslower mysql -p `pidof mysqld` -m 2 Tracing database queries for pids 3350 slower than 2 ms... TIME(s) ? ? ? ?PID ? ? ? ? ?MS QUERY 1.765087 ? ? ? 3350 ? ? ?2.996 UPDATE sbtest1 SET k=k+1 WHERE id=963 3.187147 ? ? ? 3350 ? ? ?2.069 UPDATE sbtest1 SET k=k+1 WHERE id=628 5.945987 ? ? ? 3350 ? ? ?2.171 UPDATE sbtest1 SET k=k+1 WHERE id=325 7.771761 ? ? ? 3350 ? ? ?3.853 UPDATE sbtest1 SET k=k+1 WHERE id=5955. 使用限制
bcc 基于 eBPF 開發(fā)(需要 Linux 3.15 及更高版本)。bcc 使用的大部分內(nèi)容都需要 Linux 4.1 及更高版本。
"bcc.usdt.USDTException: failed to enable probe 'query__start'; a possible cause can be that the probe requires a pid to enable" 需要 MySQL 具備 Dtrace tracepoint。
mongod穩(wěn)定嗎?還是postgresql穩(wěn)定
mongodb很多企業(yè)都在用,是非常成熟的技術(shù),沒有不穩(wěn)定的說法,是非關(guān)系庫(kù)
postgresql我沒見到企業(yè)用過,是關(guān)系庫(kù)
兩者適用場(chǎng)景不一樣,但都很穩(wěn)定
mongodb不適用的場(chǎng)景如下:
1)要求高度事務(wù)性的系統(tǒng)。
2)傳統(tǒng)的商業(yè)智能應(yīng)用。
3)復(fù)雜的跨文檔(表)級(jí)聯(lián)查詢
SQL中的問題
1. 檢查約束
檢查約束是最常見的約束類型。它允許你聲明在某個(gè)字段里的數(shù)值必須使一個(gè)布爾表達(dá)式為真。比如,要強(qiáng)制一個(gè)正數(shù)的產(chǎn)品價(jià)格,你可以用:
CREATE TABLE products ( product_no integer, name text, price numeric CHECK (price 0) );
如你所見,約束定義在數(shù)據(jù)類型之后,就好像缺省值定義一樣。缺省值和約束可以按任意順序排列。一個(gè)檢查約束由一個(gè)關(guān)鍵字 CHECK 后面跟一個(gè)放在圓括弧里的表達(dá)式組成。檢查約束表達(dá)式應(yīng)該包含受約束的字段,否則這個(gè)約束就沒什么意義了。
你還可以給這個(gè)約束取一個(gè)獨(dú)立的名字。這樣就可以令錯(cuò)誤信息更清晰,并且在你需要修改它的時(shí)候引用這個(gè)名字。語法是:
CREATE TABLE products ( product_no integer, name text, price numeric CONSTRAINT positive_price CHECK (price 0) );
因此,要聲明一個(gè)命名約束,使用關(guān)鍵字 CONSTRAINT 后面跟一個(gè)標(biāo)識(shí)符(作為名字),然后再跟約束定義。如果你不用這個(gè)方法聲明約束,那么系統(tǒng)會(huì)自動(dòng)為你選擇一個(gè)名字。
一個(gè)檢查約束也可以引用多個(gè)字段。假設(shè)你存儲(chǔ)一個(gè)正常價(jià)格和一個(gè)折扣價(jià),并且你想保證折扣價(jià)比正常價(jià)低。
CREATE TABLE products ( product_no integer, name text, price numeric CHECK (price 0), discounted_price numeric CHECK (discounted_price 0), CHECK (price discounted_price) );
頭兩個(gè)約束看上去很面熟。第三個(gè)使用了一個(gè)新的語法。它沒有附著在某個(gè)字段上,而是在逗號(hào)分隔的字段列表中以一個(gè)獨(dú)立行的形式出現(xiàn)。字段定義和約束定義可以按照任意順序列出。
我們稱頭兩個(gè)約束是"字段約束",而第三個(gè)約束是"表約束"(和字段定義分開寫)。字段約束也可以寫成表約束,而反過來很可能不行,因?yàn)橄到y(tǒng)假設(shè)字段約束只引用它所從屬的字段。PostgreSQL 并不強(qiáng)制這條規(guī)則,但是如果你希望自己的表定義可以和其它數(shù)據(jù)庫(kù)系統(tǒng)兼容,那么你最好還是遵循這條規(guī)則。上面的例子也可以這么寫:
CREATE TABLE products ( product_no integer, name text, price numeric, CHECK (price 0), discounted_price numeric, CHECK (discounted_price 0), CHECK (price discounted_price) ); 或者是
CREATE TABLE products ( product_no integer, name text, price numeric CHECK (price 0), discounted_price numeric, CHECK (discounted_price 0 AND price discounted_price) );
這只是風(fēng)格的不同。
和字段約束一樣,我們也可以給表約束賦予名稱,方法也相同:
CREATE TABLE products ( product_no integer, name text, price numeric, CHECK (price 0), discounted_price numeric, CHECK (discounted_price 0), CONSTRAINT valid_discount CHECK (price discounted_price) );
我們還要注意的是,當(dāng)約束表達(dá)式計(jì)算結(jié)果為 NULL 的時(shí)候,檢查約束會(huì)被認(rèn)為是滿足條件的。因?yàn)榇蠖鄶?shù)表達(dá)式在含有 NULL 操作數(shù)的時(shí)候結(jié)果都是 NULL ,所以這些約束不能阻止字段值為 NULL 。要確保一個(gè)字段值不為 NULL ,可以使用下一節(jié)介紹的非空約束。
2. 非空約束
非空約束只是簡(jiǎn)單地聲明一個(gè)字段必須不能是 NULL 。下面是一個(gè)例子:
CREATE TABLE products ( product_no integer NOT NULL, name text NOT NULL, price numeric );
一個(gè)非空約束總是寫成一個(gè)字段約束。非空約束在功能上等效于創(chuàng)建一個(gè)檢查約束 CHECK (column_name IS NOT NULL) ,但在 PostgreSQL 里,創(chuàng)建一個(gè)明確的非空約束效率更高。缺點(diǎn)是你不能給它一個(gè)明確的名字。
當(dāng)然,一個(gè)字段可以有多個(gè)約束。只要一個(gè)接著一個(gè)寫就可以了:
CREATE TABLE products ( product_no integer NOT NULL, name text NOT NULL, price numeric NOT NULL CHECK (price 0) );
它們的順序無所謂。順序并不影響約束檢查的順序。
NOT NULL 約束有個(gè)相反的約束:NULL 約束。它并不意味著該字段必須是空,因?yàn)檫@樣的字段也沒用。它只是定義了該字段可以為空的這個(gè)缺省行為。在 SQL 標(biāo)準(zhǔn)里沒有定義 NULL 約束,因此不應(yīng)該在可移植的應(yīng)用中使用它。在 PostgreSQL 里面增加這個(gè)約束只是為了和其它數(shù)據(jù)庫(kù)系統(tǒng)兼容。不過,有些用戶喜歡它,因?yàn)檫@個(gè)約束可以讓他們很容易在腳本文件里切換約束。比如,你可以從下面這樣開始
CREATE TABLE products ( product_no integer NULL, name text NULL, price numeric NULL );
然后在需要的時(shí)候插入 NOT 關(guān)鍵字。
【提示】在大多數(shù)數(shù)據(jù)庫(kù)設(shè)計(jì)里,主要的字段都應(yīng)該標(biāo)記為非空。
3. 唯一約束
唯一約束保證在一個(gè)字段或者一組字段里的數(shù)據(jù)與表中其它行的數(shù)據(jù)相比是唯一的。它的語法是:
CREATE TABLE products ( product_no integer UNIQUE, name text, price numeric );
上面是寫成字段約束,下面這個(gè)則寫成表約束:
CREATE TABLE products ( product_no integer, name text, price numeric, UNIQUE (product_no) );
如果一個(gè)唯一約束引用一組字段,那么這些字段用逗號(hào)分隔列出:
CREATE TABLE example ( a integer, b integer, c integer, UNIQUE (a, c) );
這樣就聲明了特定字段值的組合在整個(gè)表范圍內(nèi)是唯一的。但是這些字段中的某個(gè)單獨(dú)值可以不必是(并且通常也確實(shí)不是)唯一的。
你也可以給唯一約束賦予一個(gè)自己定義的名字,方法與前面相同:
CREATE TABLE products ( product_no integer CONSTRAINT must_be_different UNIQUE, name text, price numeric );
通常,如果包含在唯一約束中的那幾個(gè)字段在表中有多個(gè)相同的行,就違反了唯一約束。但是在這種比較中,NULL 被認(rèn)為是不相等的。這就意味著,在多字段唯一約束的情況下,如果在至少一個(gè)字段上出現(xiàn) NULL ,那么我們還是可以存儲(chǔ)同樣的這種數(shù)據(jù)行。這種行為遵循 SQL 標(biāo)準(zhǔn),但是我們聽說其它 SQL 數(shù)據(jù)庫(kù)可能不遵循這個(gè)標(biāo)準(zhǔn)。因此如果你要開發(fā)可移植的程序,那么最好仔細(xì)些。
4. 主鍵
從技術(shù)上講,主鍵約束只是唯一約束和非空約束的組合。所以,下面兩個(gè)表定義是等價(jià)的:
CREATE TABLE products ( product_no integer UNIQUE NOT NULL, name text, price numeric ); CREATE TABLE products ( product_no integer PRIMARY KEY, name text, price numeric );
主鍵也可以約束多于一個(gè)字段;其語法類似于唯一約束:
CREATE TABLE example ( a integer, b integer, c integer, PRIMARY KEY (a, c) );
主鍵表示一個(gè)或多個(gè)字段的組合可以用于唯一標(biāo)識(shí)表中的數(shù)據(jù)行。這是定義一個(gè)主鍵的直接結(jié)果。請(qǐng)注意:一個(gè)唯一約束實(shí)際上并不能提供一個(gè)唯一標(biāo)識(shí),因?yàn)樗慌懦?NULL 。這個(gè)功能對(duì)文檔目的和客戶應(yīng)用都很有用。比如,一個(gè)可以修改行數(shù)值的 GUI 應(yīng)用可能需要知道一個(gè)表的主鍵才能唯一地標(biāo)識(shí)每一行。
一個(gè)表最多可以有一個(gè)主鍵(但是它可以有多個(gè)唯一和非空約束)。關(guān)系型數(shù)據(jù)庫(kù)理論告訴我們,每個(gè)表都必須有一個(gè)主鍵。PostgreSQL 并不強(qiáng)制這個(gè)規(guī)則,但我們最好還是遵循它。
5. 外鍵
外鍵約束聲明一個(gè)字段(或者一組字段)的數(shù)值必須匹配另外一個(gè)表中出現(xiàn)的數(shù)值。我們把這個(gè)行為稱為兩個(gè)相關(guān)表之間的參照完整性。
假設(shè)你有個(gè)產(chǎn)品表,我們可能使用了好幾次:
CREATE TABLE products ( product_no integer PRIMARY KEY, name text, price numeric );
假設(shè)你有一個(gè)存儲(chǔ)這些產(chǎn)品的訂單的表。我們想保證訂單表只包含實(shí)際存在的產(chǎn)品。因此我們?cè)谟唵伪碇卸x一個(gè)外鍵約束引用產(chǎn)品表:
CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products (product_no), quantity integer );
現(xiàn)在,我們不能創(chuàng)建任何其 product_no 沒有在產(chǎn)品表中出現(xiàn)的訂單。
在這種情況下我們把訂單表叫做引用表,而產(chǎn)品表叫做被引用表。同樣,也有引用字段和被引用字段。
你也可以把上面的命令簡(jiǎn)寫成
CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products, quantity integer );
因?yàn)槿绻鄙僮侄瘟斜淼脑?,就?huì)引用被引用表的主鍵。
一個(gè)外鍵也可以約束和引用一組字段。同樣,也需要寫成表約束的形式。下面是一個(gè)捏造出來的語法例子:
CREATE TABLE t1 ( a integer PRIMARY KEY, b integer, c integer, FOREIGN KEY (b, c) REFERENCES other_table (c1, c2) );
當(dāng)然,被約束的字段數(shù)目和類型需要和被引用字段數(shù)目和類型一致。
和平常一樣,你也可以給外鍵約束賦予自定義的名字。
一個(gè)表可以包含多于一個(gè)外鍵約束。這個(gè)特性用于實(shí)現(xiàn)表之間的多對(duì)多關(guān)系。比如你有關(guān)于產(chǎn)品和訂單的表,但現(xiàn)在你想允許一個(gè)訂單可以包含多種產(chǎn)品(上面那個(gè)結(jié)構(gòu)是不允許這么做的),你可以使用這樣的結(jié)構(gòu):
CREATE TABLE products ( product_no integer PRIMARY KEY, name text, price numeric ); CREATE TABLE orders ( order_id integer PRIMARY KEY, shipping_address text, ... ); CREATE TABLE order_items ( product_no integer REFERENCES products, order_id integer REFERENCES orders, quantity integer, PRIMARY KEY (product_no, order_id) );
注意最后的表的主鍵和外鍵是重疊的。
我們知道外鍵不允許創(chuàng)建和任何產(chǎn)品都無關(guān)的訂單。但是如果一個(gè)訂單創(chuàng)建之后其引用的產(chǎn)品被刪除了怎么辦?SQL 也允許你處理這個(gè)問題。簡(jiǎn)單說,我們有幾種選擇:
不允許刪除一個(gè)被引用的產(chǎn)品
同時(shí)也刪除訂單
其它的?
為了說明這個(gè)問題,我們對(duì)上面的多對(duì)多關(guān)系制定下面的策略:如果有人想刪除一種仍然被某個(gè)訂單引用的產(chǎn)品(通過 order_items),那么就不允許這么做。如果有人刪除了一個(gè)訂單,那么訂單項(xiàng)也被刪除。
CREATE TABLE products ( product_no integer PRIMARY KEY, name text, price numeric ); CREATE TABLE orders ( order_id integer PRIMARY KEY, shipping_address text, ... ); CREATE TABLE order_items ( product_no integer REFERENCES products ON DELETE RESTRICT, order_id integer REFERENCES orders ON DELETE CASCADE, quantity integer, PRIMARY KEY (product_no, order_id) );
限制和級(jí)聯(lián)刪除是兩種最常見的選項(xiàng)。RESTRICT 禁止刪除被引用的行。NO ACTION 的意思是如果在檢查約束的時(shí)候還存在任何引用行,則拋出錯(cuò)誤;如果你不聲明任何東西,那么它就是缺省的行為。這兩個(gè)選擇的實(shí)際區(qū)別是:NO ACTION 允許約束檢查推遲到事務(wù)的晚些時(shí)候,而 RESTRICT 不行。CASCADE 聲明在刪除一個(gè)被引用的行的時(shí)候,所有引用它的行也會(huì)被自動(dòng)刪除掉。在外鍵字段上的動(dòng)作還有兩個(gè)選項(xiàng):SET NULL 和 SET DEFAULT ,它們導(dǎo)致在被引用行刪除的時(shí)候,將引用它們的字段分別設(shè)置為 NULL 和缺省值。請(qǐng)注意這些選項(xiàng)并不能讓你逃脫被觀察和約束的境地。比如,如果一個(gè)動(dòng)作聲明 SET DEFAULT ,但是缺省值并不能滿足外鍵,那么該動(dòng)作就會(huì)失敗。
與 ON DELETE 類似的還有 ON UPDATE 選項(xiàng),它是在被引用字段修改(更新)的時(shí)候調(diào)用的,可用的動(dòng)作是一樣的。
有關(guān)更新和刪除數(shù)據(jù)的更多信息可以在章6里找到。
最后,我們應(yīng)該說明的是,一個(gè)外鍵必須要么引用一個(gè)主鍵,要么引用一個(gè)唯一約束。如果外鍵引用了一個(gè)唯一約束,那么在如何匹配 NULL 這個(gè)問題上還有一些其它的可能性。這些東西都在 CREATE TABLE 中解釋。
Postgres-存儲(chǔ)過程 return 詳解
如果返回一個(gè) 數(shù)字或者字符 比較簡(jiǎn)單,那么多行多列怎么辦呢,分為以下幾種情況【東西很多,這里只做簡(jiǎn)單列舉】
返回多行單列
又分為幾種方式
1. return next,用在 for 循環(huán)中
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOFvarcharas $$DECLARE? ? v_name varchar;BEGINforv_namein( (selectnamefromtest_result1whereid=in_id)union(selectnamefromtest_result2whereid= in_id) ) loop
RETURNNEXT v_name;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
注意
1. 循環(huán)外還有個(gè) return
2. 需要實(shí)現(xiàn)聲明 v_name
2. return query,無需 for 循環(huán)
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOFvarcharas $$DECLARE? ? v_rec RECORD;BEGINreturnquery? ( (selectnamefromtest_result1whereid=in_id)union(selectnamefromtest_result2whereid= in_id) );
return;END;$$LANGUAGE PLPGSQL;
注意:如果 返回類型為 setof,最好用如下方法
RETURNQUERYEXECUTESQL
不要這么用
executesqlinto? out;returnout;
返回多行多列
也有多種方式
1. 使用 return next 和? setof record ,需要 for 循環(huán)
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOF RECORDas $$DECLARE? ? v_rec RECORD; BEGINforv_recin( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) )loop
RETURNNEXT v_rec;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
注意
1. 讀取表的整行數(shù)據(jù)時(shí)才能用 record
2. 如果讀取的數(shù)據(jù)不是整行,需要自定義 復(fù)合數(shù)據(jù)類型,否則會(huì)報(bào)如下錯(cuò)誤
ERROR:? acolumndefinition listisrequiredforfunctions returning "record"
定義復(fù)合類型 ,示例如下
createtype myout2as (
road_num int,
freq bigint);createorreplacefunctiontest(cartext, time1text, time2text)returnssetof myout2as $$declare
array1 text[];
array2 text[];
len1 integer;
len2 integer;
x integer;
y integer;
road_str text;
car_str text;
sql text;
i myout2;
begin-- vin 號(hào)拼接selectregexp_split_to_array(car,',')into array2;
selectarray_length(array2,1)into len2;
car_str :='';
y :=1;
whiley= len2 loop
car_str :=car_str||quote_literal(array2[y])||',';
y :=y+1;
end loop;
-- sql 拼接sql :='select road_number, sum(frequency) from heat_map where date_key = '''|| time1
||'-01'' and date_key ='''|| time2
||'-20'' and vin in ('||rtrim(car_str,',')
||')group by road_number;';
--execute sql into out;foriinexecute sql loop
returnnext i;
end loop;
return;end$$ language plpgsql;
在執(zhí)行時(shí)可能會(huì)報(bào)如下錯(cuò)誤
ERROR:set-valuedfunctioncalledincontext that cannot accept aset
解決方法
select funcname(arg);--改為select*fromfuncname(arg);
2.? return query,無需 for 循環(huán)
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOF RECORDas $$DECLARE? ? v_rec RECORD;BEGINreturnquery? ( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) );
return;END;
$$
LANGUAGE PLPGSQL;
3. 使用 out 輸出參數(shù)
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger,out o_idinteger,out o_namevarchar)
RETURNSSETOF RECORDas $$DECLARE? ? v_rec RECORD;BEGINforv_recin( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) )loop
o_id? := v_rec.id;
o_name := v_rec.name;
RETURNNEXT ;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
總結(jié) - return next return query?
我們可以看到上面無論是單列多行還是多列多行,都用到了 return next 和 return query 方法
在 plpgsql 中,如果存儲(chǔ)過程返回 setof sometype,則返回值必須在 return next 或者 return query 中聲明,然后有一個(gè)不帶參數(shù)的 retrun 命令,告訴函數(shù)執(zhí)行完畢;【setof 就意味著 多行】
用法如下
RETURNNEXT expression;RETURN QUERY query;RETURNQUERYEXECUTEcommand-string[ USING expression [, ... ]];
return next 可以用于標(biāo)量和復(fù)合類型數(shù)據(jù);
return query 命令將查詢到的一條結(jié)果追加到函數(shù)的結(jié)果集中;
二者在單一集合返回函數(shù)中自由混合,在這種情況下,結(jié)果將被級(jí)聯(lián)?!居写芯俊?/p>
return query execute 是 return query 的變形,它指定 sql 將被動(dòng)態(tài)執(zhí)行;
returnqueryselectroad_number,sum(frequency)fromheat_mapgroupbyroad_number;--這樣可以sql :='select road_number, sum(frequency) from heat_map group by road_number';returnquery sql;--這樣不行
參考資料:
自定義類型并返回?cái)?shù)組
return next return query
function返回多列多行
返回結(jié)果集多列和單列的例子??
PostgreSQL存儲(chǔ)過程(1)-基于SQL的存儲(chǔ)過程
動(dòng)態(tài)SQL
postgresql, pgadmin error RETURN cannot have a parameter in function returning set
存儲(chǔ)過程輸出參數(shù)
PostgreSQL存儲(chǔ)過程(3)-流程控制語句
哪里有賣ORACLE的空間?
很少有空間或者服務(wù)器支持oracle的,因?yàn)閛racle軟件本身就要花很多錢買!可以考慮用跟oracle類似功能的postgresql的服務(wù)器空間替代。postgresql的空間也只是國(guó)外有,國(guó)內(nèi)幾乎找不到。
觸發(fā)器到底是什么意思?
一個(gè)觸發(fā)器是一種聲明,告訴數(shù)據(jù)庫(kù)應(yīng)該在執(zhí)行特定的操作的時(shí)候執(zhí)行特定的函數(shù)。 觸發(fā)器可以定義在一個(gè)INSERT,UPDATE, 或者 DELETE 命令之前或者之后執(zhí)行,要么是對(duì)每個(gè)被修改的行一次, 要么是每條 SQL 一次。 如果發(fā)生觸發(fā)器事件,那么將在合適的時(shí)刻調(diào)用觸發(fā)器的函數(shù)以處理該事件。
觸發(fā)器函數(shù)必須在創(chuàng)建觸發(fā)器之前,作為一個(gè)沒有參數(shù)并且返回trigger類型的函數(shù)定義。 (觸發(fā)器函數(shù)通過特殊的 TriggerData 結(jié)構(gòu)接收其輸入,而不是用普通函數(shù)參數(shù)那種形式。)
一旦創(chuàng)建了一個(gè)合適的觸發(fā)器函數(shù),觸發(fā)器就用 CREATE TRIGGER 創(chuàng)建。同一個(gè)觸發(fā)器函數(shù)可以用于多個(gè)觸發(fā)器。
PostgreSQL 提供按行觸發(fā)的觸發(fā)器和按語句觸發(fā)的觸發(fā)器。在按行觸發(fā)的觸發(fā)器里, 觸發(fā)器函數(shù)是為觸發(fā)觸發(fā)器的語句影響的每一行執(zhí)行一次。相比之下,一個(gè)按語句觸發(fā)的觸發(fā)器是在每執(zhí)行一次合適的語句執(zhí)行一次的, 而不管影響的行數(shù)。特別是,一個(gè)影響零行的語句將仍然導(dǎo)致任何適用的按語句觸發(fā)的觸發(fā)器的執(zhí)行。 這兩種類型的觸發(fā)器有時(shí)候分別叫做行級(jí)別的觸發(fā)器和語句級(jí)別的觸發(fā)器。
觸發(fā)器還通常分成 before 觸發(fā)器和 after 觸發(fā)器。 語句級(jí)別的 "before" 觸發(fā)器通常在語句開始做任何事情之前觸發(fā), 而語句級(jí)別的 "after" 觸發(fā)器在語句的最后觸發(fā)。 行級(jí)別的 "before" 觸發(fā)器在對(duì)特定行進(jìn)行操作的時(shí)候馬上觸發(fā), 而行級(jí)別的 "after" 觸發(fā)器在語句結(jié)束的時(shí)候觸發(fā)(但是在任何語句級(jí)別的 "after" 觸發(fā)器之前)。
按語句觸發(fā)的觸發(fā)器應(yīng)該總是返回 NULL。 如果必要,按行觸發(fā)的觸發(fā)器函數(shù)可以給調(diào)用它的執(zhí)行者返回一表數(shù)據(jù)行(一個(gè)類型為 HeapTuple 的數(shù)值), 那些在操作之前觸發(fā)的觸發(fā)器有以下選擇:
它可以返回 NULL 以忽略對(duì)當(dāng)前行的操作。 這就指示執(zhí)行器不要執(zhí)行調(diào)用該觸發(fā)器的行級(jí)別操作(對(duì)特定行的插入或者更改))。
只用于INSERT和UPDATE觸發(fā)器: 返回的行將成為被插入的行或者是成為將要更新的行。 這樣就允許觸發(fā)器函數(shù)修改被插入或者更新的行。
一個(gè)無意導(dǎo)致任何這類行為的在操作之前觸發(fā)的行級(jí)觸發(fā)器必須仔細(xì)返回那個(gè)被當(dāng)作新行傳進(jìn)來的同一行 (也就是說,對(duì)于 INSERT 和 UPDATE 觸發(fā)器而言,是 NEW 行, 對(duì)于 DELETE 觸發(fā)器而言,是 OLD 行)。
對(duì)于在操作之后觸發(fā)的行級(jí)別的觸發(fā)器,其返回值會(huì)被忽略,因此他們可以返回NULL。
如果多于一個(gè)觸發(fā)器為同樣的事件定義在同樣的關(guān)系上, 觸發(fā)器將按照由名字的字母順序排序的順序觸發(fā)。 如果是事件之前觸發(fā)的觸發(fā)器,每個(gè)觸發(fā)器返回的可能已經(jīng)被修改過的行成為下一個(gè)觸發(fā)器的輸入。 如果任何事件之前觸發(fā)的觸發(fā)器返回 NULL 指針, 那么對(duì)該行的操作將被丟棄并且隨后的觸發(fā)器不會(huì)被觸發(fā)。
通常,行的 before 觸發(fā)器用于檢查或修改將要插入或者更新的數(shù)據(jù)。 比如,一個(gè) before 觸發(fā)器可以用于把當(dāng)前時(shí)間插入一個(gè) timestamp 字段, 或者跟蹤該行的兩個(gè)元素是一致的。行的 after 觸發(fā)器多數(shù)用于填充或者更新其它表, 或者對(duì)其它表進(jìn)行一致性檢查。這么區(qū)分工作的原因是, after 觸發(fā)器肯定可以看到該行的最后數(shù)值, 而 before 觸發(fā)器不能;還可能有其它的 before 觸發(fā)器在其后觸發(fā)。 如果你沒有具體的原因定義觸發(fā)器是 before 還是 after,那么 before 觸發(fā)器的效率高些, 因?yàn)椴僮飨嚓P(guān)的信息不必保存到語句的結(jié)尾。
如果一個(gè)觸發(fā)器函數(shù)執(zhí)行 SQL 命令,然后這些命令可能再次觸發(fā)觸發(fā)器。 這就是所謂的級(jí)聯(lián)觸發(fā)器。對(duì)級(jí)聯(lián)觸發(fā)器的級(jí)聯(lián)深度沒有明確的限制。 有可能出現(xiàn)級(jí)聯(lián)觸發(fā)器導(dǎo)致同一個(gè)觸發(fā)器的遞歸調(diào)用的情況; 比如,一個(gè) INSERT 觸發(fā)器可能執(zhí)行一個(gè)命令, 把一個(gè)額外的行插入同一個(gè)表中,導(dǎo)致 INSERT 觸發(fā)器再次激發(fā)。 避免這樣的無窮遞歸的問題是觸發(fā)器程序員的責(zé)任。
在定義一個(gè)觸發(fā)器的時(shí)候,我們可以聲明一些參數(shù)。 在觸發(fā)器定義里面包含參數(shù)的目的是允許類似需求的不同觸發(fā)器調(diào)用同一個(gè)函數(shù)。 比如,我們可能有一個(gè)通用的觸發(fā)器函數(shù), 接受兩個(gè)字段名字,把當(dāng)前用戶放在第一個(gè),而當(dāng)前時(shí)間戳在第二個(gè)。 只要我們寫得恰當(dāng),那么這個(gè)觸發(fā)器函數(shù)就可以和觸發(fā)它的特定表無關(guān)。 這樣同一個(gè)函數(shù)就可以用于有著合適字段的任何表的 INSERT 事件,實(shí)現(xiàn)自動(dòng)跟蹤交易表中的記錄創(chuàng)建之類的問題。如果定義成一個(gè) UPDATE 觸發(fā)器,我們還可以用它跟蹤最后更新的事件。
每種支持觸發(fā)器的編程語言都有自己的方法讓觸發(fā)器函數(shù)得到輸入數(shù)據(jù)。 這些輸入數(shù)據(jù)包括觸發(fā)器事件的類型(比如,INSERT 或者 UPDATE)以及所有在 CREATE TRIGGER 里面列出的參數(shù)。 對(duì)于低層次的觸發(fā)器,輸入數(shù)據(jù)也包括 INSERT 和 UPDATE 觸發(fā)器的 NEW 行,和/或 UPDATE 和 DELETE 觸發(fā)器的 OLD 行。 語句級(jí)別的觸發(fā)器目前沒有任何方法檢查改語句修改的獨(dú)立行。
網(wǎng)站欄目:postgresql級(jí)聯(lián)的簡(jiǎn)單介紹
鏈接URL:http://biofuelwatch.net/article/dscoiej.html