99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

包含postgresql說明的詞條

postgresql中使用if else語句

1、首先在postgresql數據庫中復制表的時候,必須先建立表結構,然后通過insert into語句來實現。

十余年的陸河網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。營銷型網站建設的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整陸河建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“陸河網站設計”,“陸河網站推廣”以來,每個客戶項目都認真落實執行。

2、如果在復制數據之前沒有建立相應的表結構,如下圖中的錯誤信息。

3、在查詢數據的時候也可以把兩個表聯合起來進行查詢,通過union關鍵字來進行查詢,如下圖。

4、如果在使用union進行查詢的進修,兩條結果一樣人被合并成一條。

5、如果想顯示聯合查詢中相同的語句,可以使用union all來進行查詢。

如何學習PostgreSQL SQL語法

我們可以利用psql命令來查詢sql語法。

切換到PostgreSql用戶下,

[sql] view plain copy

span style="font-size:18px;"[doctor@localhost ~]$ su - postgres

密碼:

su: 鑒定故障

[doctor@localhost ~]$ su - postgres

密碼:

-bash-4.3$ bash

bash-4.3$ psql

psql (9.4.2)

輸入 "help" 來獲取幫助信息.

postgres=#

postgres=# help

您正在使用psql, 這是一種用于訪問PostgreSQL的命令行界面

鍵入: \copyright 顯示發行條款

\h 顯示 SQL 命令的說明

\? 顯示 pgsql 命令的說明

\g 或者以分號(;)結尾以執行查詢

\q 退出

postgres=#

/span

\h 命令就是我們用來學習sql語法的命令。

[sql] view plain copy

span style="font-size:18px;"postgres=# \h

可用的說明:

ABORT DEALLOCATE

ALTER AGGREGATE DECLARE

ALTER COLLATION DELETE

ALTER CONVERSION DISCARD

ALTER DATABASE DO

ALTER DEFAULT PRIVILEGES DROP AGGREGATE

ALTER DOMAIN DROP CAST

ALTER EVENT TRIGGER DROP COLLATION

ALTER EXTENSION DROP CONVERSION

ALTER FOREIGN DATA WRAPPER DROP DATABASE

ALTER FOREIGN TABLE DROP DOMAIN

ALTER FUNCTION DROP EVENT TRIGGER

ALTER GROUP DROP EXTENSION

ALTER INDEX DROP FOREIGN DATA WRAPPER

ALTER LANGUAGE DROP FOREIGN TABLE

ALTER LARGE OBJECT DROP FUNCTION

ALTER MATERIALIZED VIEW DROP GROUP

ALTER OPERATOR DROP INDEX

ALTER OPERATOR CLASS DROP LANGUAGE

ALTER OPERATOR FAMILY DROP MATERIALIZED VIEW

ALTER ROLE DROP OPERATOR

ALTER RULE DROP OPERATOR CLASS

postgres=# \h select

命令: SELECT

描述: 從資料表或視觀表讀取資料

語法:

[ WITH [ RECURSIVE ] with查詢語句(with_query) [, ...] ]

SELECT [ ALL | DISTINCT [ ON ( 表達式 [, ...] ) ] ]

[ * | 表達式 [ [ AS ] 輸出名稱 ] [, ...] ]

[ FROM from列表中項 [, ...] ]

[ WHERE 條件 ]

[ GROUP BY 表達式 [, ...] ]

[ HAVING 條件 [, ...] ]

[ WINDOW 窗口名稱 AS ( 窗口定義 ) [, ...] ]

[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] 查詢 ]

[ ORDER BY 表達式 [ ASC | DESC | USING 運算子 ] [ NULLS { FIRST | LAST } ] [

, ...] ]

[ LIMIT { 查詢所用返回記錄的最大數量 | ALL } ]

[ OFFSET 起始值 [ ROW | ROWS ] ]

[ FETCH { FIRST | NEXT } [ 查詢所用返回記錄的最大數量 ] { ROW | ROWS } ONLY

]

[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF 表名 [, ...] ] [ N

OWAIT ] [...] ]

from 列表中的項可以是下列內容之一

[ ONLY ] 表名 [ * ] [ [ AS ] 化名 [ ( 列的化名 [, ...] ) ] ]

[ LATERAL ] ( 查詢 ) [ AS ] 化名 [ ( 列的化名 [, ...] ) ]

WITH查詢語句名稱(with_query_name) [ [ AS ] 化名 [ ( 列的化名 [, ...] ) ] ]

[ LATERAL ] 函數名稱 ( [ 參數 [, ...] ] )

[ WITH ORDINALITY ] [ [ AS ] 化名 [ ( 列的化名 [, ...] ) ] ]

[ LATERAL ] 函數名稱 ( [ 參數 [, ...] ] ) [ AS ] 化名 ( 列定義 [, ...] )

[ LATERAL ] 函數名稱 ( [ 參數 [, ...] ] ) AS ( 列定義 [, ...] )

[ LATERAL ] ROWS FROM( 函數名稱 ( [ 參數 [, ...] ] ) [ AS ( 列定義 [, ...] )

] [, ...] )

[ WITH ORDINALITY ] [ [ AS ] 化名 [ ( 列的化名 [, ...] ) ] ]

from列表中項 [ NATURAL ] 連接操作的類型 from列表中項 [ ON 用連接操作的條件 |

USING ( 用于連接操作的列 [, ...] ) ]

with查詢語句是:

WITH查詢語句名稱(with_query_name) [ ( 列名稱 [, ...] ) ] AS ( 查詢 | 值 | in

sert | update | delete )

TABLE [ ONLY ] 表名 [ * ]

postgres=# /span

看這命令對于學習sql語法很有用。

如何設置PostgreSQL允許被遠程訪問

postgresql默認情況下,遠程訪問不能成功,如果需要允許遠程訪問,需要修改兩個配置文件,說明如下:

1.postgresql.conf

將該文件中的listen_addresses項值設定為“*”,在9.0 Windows版中,該項配置已經是“*”無需修改。

2.pg_hba.conf

在該配置文件的host all all 127.0.0.1/32 md5行下添加以下配置,或者直接將這一行修改為以下配置

host all all 0.0.0.0/0 md5

如果不希望允許所有IP遠程訪問,則可以將上述配置項中的0.0.0.0設定為特定的IP值。

postgresql 建立索引

一、索引的類型:

PostgreSQL提供了多種索引類型:B-Tree、Hash、GiST和GIN,由于它們使用了不同的算法,因此每種索引類型都有其適合的查詢類型,缺省時,CREATE INDEX命令將創建B-Tree索引。

1. B-Tree:

CREATE TABLE test1 (

id integer,

content varchar

);

CREATE INDEX test1_id_index ON test1 (id);

B-Tree索引主要用于等于和范圍查詢,特別是當索引列包含操作符" 、=和"作為查詢條件時,PostgreSQL的查詢規劃器都會考慮使用B-Tree索引。在使用BETWEEN、IN、IS NULL和IS NOT NULL的查詢中,PostgreSQL也可以使用B-Tree索引。然而對于基于模式匹配操作符的查詢,如LIKE、ILIKE、~和 ~*,僅當模式存在一個常量,且該常量位于模式字符串的開頭時,如col LIKE 'foo%'或col ~ '^foo',索引才會生效,否則將會執行全表掃描,如:col LIKE '%bar'。

2. Hash:

CREATE INDEX name ON table USING hash (column);

散列(Hash)索引只能處理簡單的等于比較。當索引列使用等于操作符進行比較時,查詢規劃器會考慮使用散列索引。

這里需要額外說明的是,PostgreSQL散列索引的性能不比B-Tree索引強,但是散列索引的尺寸和構造時間則更差。另外,由于散列索引操作目前沒有記錄WAL日志,因此一旦發生了數據庫崩潰,我們將不得不用REINDEX重建散列索引。

3. GiST:

GiST索引不是一種單獨的索引類型,而是一種架構,可以在該架構上實現很多不同的索引策略。從而可以使GiST索引根據不同的索引策略,而使用特定的操作符類型。

4. GIN:

GIN索引是反轉索引,它可以處理包含多個鍵的值(比如數組)。與GiST類似,GIN同樣支持用戶定義的索引策略,從而可以使GIN索引根據不同的索引策略,而使用特定的操作符類型。作為示例,PostgreSQL的標準發布中包含了用于一維數組的GIN操作符類型,如:、=、等。

二、復合索引:

PostgreSQL中的索引可以定義在數據表的多個字段上,如:

CREATE TABLE test2 (

major int,

minor int,

name varchar

}

CREATE INDEX test2_mm_idx ON test2 (major, minor);

1. B-Tree類型的復合索引:

在B-Tree類型的復合索引中,該索引字段的任意子集均可用于查詢條件,不過,只有當復合索引中的第一個索引字段(最左邊)被包含其中時,才可以獲得最高效率。

2. GiST類型的復合索引:

在GiST類型的復合索引中,只有當第一個索引字段被包含在查詢條件中時,才能決定該查詢會掃描多少索引數據,而其他索引字段上的條件只是會限制索引返回的條目。假如第一個索引字段上的大多數數據都有相同的鍵值,那么此時應用GiST索引就會比較低效。

3. GIN類型的復合索引:

與B-Tree和GiST索引不同的是,GIN復合索引不會受到查詢條件中使用了哪些索引字段子集的影響,無論是哪種組合,都會得到相同的效率。

使用復合索引應該謹慎。在大多數情況下,單一字段上的索引就已經足夠了,并且還節約時間和空間。除非表的使用模式非常固定,否則超過三個字段的索引幾乎沒什么用處。

三、組合多個索引:

PostgreSQL可以在查詢時組合多個索引(包括同一索引的多次使用),來處理單個索引掃描不能實現的場合。與此同時,系統還可以在多個索引掃描之間組成AND和OR的條件。比如,一個類似WHERE x = 42 OR x = 47 OR x = 53 OR x = 99的查詢,可以被分解成四個獨立的基于x字段索引的掃描,每個掃描使用一個查詢子句,之后再將這些掃描結果OR在一起并生成最終的結果。另外一個例子是,如果我們在x和y上分別存在獨立的索引,那么一個類似WHERE x = 5 AND y = 6的查詢,就會分別基于這兩個字段的索引進行掃描,之后再將各自掃描的結果進行AND操作并生成最終的結果行。

為了組合多個索引,系統掃描每個需要的索引,然后在內存里組織一個BITMAP,它將給出索引掃描出的數據在數據表中的物理位置。然后,再根據查詢的需要,把這些位圖進行AND或者OR的操作并得出最終的BITMAP。最后,檢索數據表并返回數據行。表的數據行是按照物理順序進行訪問的,因為這是位圖的布局,這就意味著任何原來的索引的排序都將消失。如果查詢中有ORDER BY子句,那么還將會有一個額外的排序步驟。因為這個原因,以及每個額外的索引掃描都會增加額外的時間,這樣規劃器有時候就會選擇使用簡單的索引掃描,即使有多個索引可用也會如此。

四、唯一索引:

CREATE UNIQUE INDEX name ON table (column [, ...]);

五、表達式索引:

表達式索引主要用于在查詢條件中存在基于某個字段的函數或表達式的結果與其他值進行比較的情況,如:

SELECT * FROM test1 WHERE lower(col1) = 'value';

此時,如果我們僅僅是在col1字段上建立索引,那么該查詢在執行時一定不會使用該索引,而是直接進行全表掃描。如果該表的數據量較大,那么執行該查詢也將會需要很長時間。解決該問題的辦法非常簡單,在test1表上建立基于col1字段的表達式索引,如:

CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));

SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';

和上面的例子一樣,盡管我們可能會為first_name和last_name分別創建獨立索引,或者是基于這兩個字段的復合索引,在執行該查詢語句時,這些索引均不會被使用,該查詢能夠使用的索引只有我們下面創建的表達式索引。

CREATE INDEX people_names ON people ((first_name || ' ' || last_name));

CREATE INDEX命令的語法通常要求在索引表達式周圍書寫圓括弧,就像我們在第二個例子里顯示的那樣。如果表達式只是一個函數調用,那么可以省略,就像我們在第一個例子里顯示的那樣。

從索引維護的角度來看,索引表達式要相對低效一些,因為在插入數據或者更新數據的時候,都必須為該行計算表達式的結果,并將該結果直接存儲到索引里。然而在查詢時,PostgreSQL就會把它們看做WHERE idxcol = 'constant',因此搜索的速度等效于基于簡單索引的查詢。通常而言,我們只是應該在檢索速度比插入和更新速度更重要的場景下使用表達式索引。

六、部分索引:

部分索引(partial index)是建立在一個表的子集上的索引,而該子集是由一個條件表達式定義的(叫做部分索引的謂詞)。該索引只包含表中那些滿足這個謂詞的行。

由于不是在所有的情況下都需要更新索引,因此部分索引會提高數據插入和數據更新的效率。然而又因為部分索引比普通索引要小,因此可以更好的提高確實需要索引部分的查詢效率。見以下三個示例:

1. 索引字段和謂詞條件字段一致:

CREATE INDEX access_log_client_ip_ix ON access_log(client_ip)

WHERE NOT (client_ip inet '192.168.100.0' AND client_ip inet '192.168.100.255');

下面的查詢將會用到該部分索引:

SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';

下面的查詢將不會用該部分索引:

一個不能使用這個索引的查詢可以是

SELECT * FROM access_log WHERE client_ip = inet '192.168.100.23';

2. 索引字段和謂詞條件字段不一致:

PostgreSQL支持帶任意謂詞的部分索引,唯一的約束是謂詞的字段也要來自于同樣的數據表。注意,如果你希望你的查詢語句能夠用到部分索引,那么就要求該查詢語句的條件部分必須和部分索引的謂詞完全匹配。 準確說,只有在PostgreSQL能夠識別出該查詢的WHERE條件在數學上涵蓋了該索引的謂詞時,這個部分索引才能被用于該查詢。

CREATE INDEX orders_unbilled_index ON orders(order_nr) WHERE billed is not true;

下面的查詢一定會用到該部分索引:

SELECT * FROM orders WHERE billed is not true AND order_nr 10000;

那么對于如下查詢呢?

SELECT * FROM orders WHERE billed is not true AND amount 5000.00;

這個查詢將不像上面那個查詢這么高效,畢竟查詢的條件語句中沒有用到索引字段,然而查詢條件"billed is not true"卻和部分索引的謂詞完全匹配,因此PostgreSQL將掃描整個索引。這樣只有在索引數據相對較少的情況下,該查詢才能更有效一些。

下面的查詢將不會用到部分索引。

SELECT * FROM orders WHERE order_nr = 3501;

3. 數據表子集的唯一性約束:

CREATE TABLE tests (

subject text,

target text,

success boolean,

...

);

CREATE UNIQUE INDEX tests_success_constraint ON tests(subject, target) WHERE success;

該部分索引將只會對success字段值為true的數據進行唯一性約束。在實際的應用中,如果成功的數據較少,而不成功的數據較多時,該實現方法將會非常高效。

七、檢查索引的使用:

見以下四條建議:

1. 總是先運行ANALYZE。

該命令將會收集表中數值分布狀況的統計。在估算一個查詢返回的行數時需要這個信息,而規劃器則需要這個行數以便給每個可能的查詢規劃賦予真實的開銷值。如果缺乏任何真實的統計信息,那么就會使用一些缺省數值,這樣肯定是不準確的。因此,如果還沒有運行ANALYZE就檢查一個索引的使用狀況,那將會是一次失敗的檢查。

2. 使用真實的數據做實驗。

用測試數據填充數據表,那么該表的索引將只會基于測試數據來評估該如何使用索引,而不是對所有的數據都如此使用。比如從100000行中選1000行,規劃器可能會考慮使用索引,那么如果從100行中選1行就很難說也會使用索引了。因為100行的數據很可能是存儲在一個磁盤頁面中,然而沒有任何查詢規劃能比通過順序訪問一個磁盤頁面更加高效了。與此同時,在模擬測試數據時也要注意,如果這些數據是非常相似的數據、完全隨機的數據,或按照排序順序插入的數據,都會令統計信息偏離實際數據應該具有的特征。

3. 如果索引沒有得到使用,那么在測試中強制它的使用也許會有些價值。有一些運行時參數可以關閉各種各樣的查詢規劃。

4. 強制使用索引用法將會導致兩種可能:一是系統選擇是正確的,使用索引實際上并不合適,二是查詢計劃的開銷計算并不能反映現實情況。這樣你就應該對使用和不使用索引的查詢進行計時,這個時候EXPLAIN ANALYZE命令就很有用了。

postgresql里邊的數組怎么操作

1. 數組可以作為字段類型

PostgreSQL中數據是一種基本的數據類型,可以作為字段的類型定義。例如,

CREATE?TABLE?ads.tb_mo_item

(

mo_key?integer?NOT?NULL,

input_flow?integer[]?NOT?NULL?DEFAULT?ARRAY[]::integer[]?

);

2. 可以用array[]來初始化一個數組

select?array[1,?3,?4]::int[];

3. 操作數組有一系列函數, 可以實現數組比較,添加新元素,一般數組是否包含另一數組的判斷,等等。具體參考PostgreSQL說明文檔中函數和操作符中有關Array的部分。

操作符有: =, , , , =, =, @, @, , ||

函數有: array_append, array_cat, array_ndims, array_dims, array_fill, array_length, array_lower, array_remove, array_replace, array_to_string, array_upper, string_to_array, unnest等.

其中,常用的是: array_append, ?array_length, unnest

4. 使用數組下標獲得數組的元素,下標是從1開始的

select?(array[1,?3,?4]::int[])[2];

5. 可以用unnest將數組轉換成一個結果集,個人覺得這個很有用處

select?a.a?from?unnest(array[1,?3,?4]::int[])?a;

postgreSQL觸發器

PostgreSQL 提供按行與按語句觸發的觸發器。按行觸發的觸發器函數為觸發語句影響的每一行執行一次;按語句觸發的觸發器函數為每條觸發語句執行一次,而不管影響的行數。特別是,一個影響零行的語句將仍然導致按語句觸發的觸發器執行。這兩種類型的觸發器有時候分別叫做行級觸發器和語句級觸發器。觸發器還通常分成 before 觸發器和 after 觸發器。語句級別的"before"觸發器通常在語句開始做任何事情之前觸發,而語句級別的"after"觸發器在語句結束時觸發。行級別的"before"觸發器在對特定行進行操作之前觸發,而行級別的"after"觸發器在語句結束的時候觸發(但是在任何語句級別的"after"觸發器之前)。

一個觸發器是一種聲明,告訴數據庫應該在執行特定的操作的時候執行特定的函數。觸發器可以定義在一個 INSERT, UPDATE, DELETE 命令之前或者之后執行,要么是對每行執行一次,要么是對每條 SQL 語句執行一次。如果發生觸發器事件,那么將在合適的時刻調用觸發器函數以處理該事件。觸發器函數必須在創建觸發器之前,作為一個沒有參數并且返回 trigger 類型的函數定義。觸發器函數通過特殊的 TriggerData 結構接收其輸入,而不是用普通的函數參數方式.

注意:

一.按語句觸發的觸發器應該總是返回 NULL.

二.如果必要,按行觸發的觸發器函數可以給調用它的執行者返回一行數據(一個類型為 HeapTuple 的數值),那些在操作之前觸發的觸發器有以下選擇

1. 它可以返回 NULL 以忽略對當前行的操作。這就指示執行器不要執行調用該觸

發器的行級別操作(對特定行的插入或者更改)。

2.只用于 INSERT 和 UPDATE 行觸發器:返回的行將成為被插入的行或者是成為

將要更新的行。這樣就允許觸發器函數修改將要被插入或者更新的行。

一個無意導致任何這類行為的在操作之前觸發的行級觸發器必須仔細返回那個被當作新行傳進來的行。也就是說,對于 INSERT 和 UPDATE 觸發器而言,是 NEW 行,對于 DELETE觸發器而言,是 OLD 行。

三. 對于在操作之后觸發的行級觸發器,其返回值會被忽略,因此可以回NULL。

下面通過具體的例子來說明在postgresql中觸發器的建立和使用(老規矩先寫代碼然后講解)

#include postgres.h

#include executor/spi.h

#include funcapi.h

#include commands/trigger.h

#include fmgr.h

extern Datum pg_trigf(PG_FUNCTION_ARGS);

#ifdef PG_MODULE_MAGIC

PG_MODULE_MAGIC;

#endif

PG_FUNCTION_INFO_V1(pg_trigf);

Datum

pg_trigf(PG_FUNCTION_ARGS)

{

TriggerData *trigdata = (TriggerData *)fcinfo-context;

HeapTuple rettuple = NULL;

int ret;

int proc; /* to store the value of SPI_processed (actual row number)*/

/* to be sure this function will be called by trigger */

if (!(CALLED_AS_TRIGGER(fcinfo))) {

elog(ERROR, "trigf: not called by triggermanager");

}

/* should be fired by statement */

if (TRIGGER_FIRED_FOR_ROW(trigdata-tg_event)) {

elog(ERROR, "cannot process row events");

}

/* should be fired before event */

if (TRIGGER_FIRED_AFTER(trigdata-tg_event)) {

elog(ERROR, "must be fired before event");

}

/* connect spi manager */

if ((ret = SPI_connect()) 0) {

elog(INFO, "SPI_connect failed: SPI_connectreturned: %d", ret);

return PointerGetDatum(rettuple);

}

/* check the permanent table name(perm_user) existsor not*/

ret = SPI_exec("SELECT tablename FROM pg_tables WHERE tablename LIKE'perm!_user' ESCAPE '!';", 1);

proc = SPI_processed;

if (ret != SPI_OK_SELECT) {

elog(INFO, "SPI_exec execute error: user table.");

SPI_finish();

return PointerGetDatum(rettuple);

}

/* create the permanent table(perm_user) if it does not exist */

if (proc 1) {

/* create permanent table: perm_user */

ret = SPI_exec("CREATE TABLE perm_user ASSELECT * FROM tbl_user;", 0);

if (ret != SPI_OK_SELINTO ) {

elog(INFO, "SPI_execexecute error: fail to create perm_user");

SPI_finish();

returnPointerGetDatum(rettuple);

}

/* set attribute to perm_user */

ret = SPI_exec("ALTER TABLE perm_user ADD PRIMARYKEY (user_name);", 0);

if (ret != SPI_OK_SELINTO) {

elog(INFO, "SPI_execexecute error: fail to add primary key to perm_user");

SPI_finish();

returnPointerGetDatum(rettuple);

}

/* set attribute to perm_user*/

ret = SPI_exec("ALTER TABLE perm_user ALTERuser_passwd SET NOT NULL;", 0);

if (ret != SPI_OK_SELINTO) {

elog(INFO, "SPI_execexecute error: fail to set attribute to password.");

SPI_finish();

returnPointerGetDatum(rettuple);

}

}

.....

/* check the permanent table name(perm_member) exists or not */

ret = SPI_exec("SELECT tablename FROM pg_tables WHERE tablename LIKE'perm!_member' ESCAPE '!';", 1);

proc = SPI_processed;

if (ret != SPI_OK_SELECT) {

elog(INFO, "SPI_exec execute errortbl_member");

SPI_finish();

return PointerGetDatum(rettuple);

}

/* create the permanent table(perm_member) if it does not exist */

if (proc 1) {

/* create permanent table: perm_member */

ret = SPI_exec("CREATE TABLE perm_member ASSELECT * FROM tbl_member;", 0);

if (ret != SPI_OK_SELINTO) {

elog(INFO, "SPI_execexecute error");

SPI_finish();

returnPointerGetDatum(rettuple);

}

/* set attribute to perm_member */

ret = SPI_exec("ALTER TABLE perm_member ADDCONSTRAINT user_fk FOREIGN KEY (user_name) REFERENCES perm_user(user_name) ONDELETE CASCADE ON UPDATE CASCADE;", 0);

if (ret != SPI_OK_UTILITY) {

elog(INFO, "SPI_execexecute error: fail to set attribute to user_name.");

SPI_finish();

returnPointerGetDatum(rettuple);

}

/* set attribute to perm_member */

ret = SPI_exec("ALTER TABLE perm_member ADDCONSTRAINT group_fk FOREIGN KEY (grp_name) REFERENCES perm_group(grp_name) ONDELETE CASCADE ON UPDATE CASCADE;", 0);

if (ret != SPI_OK_UTILITY) {

elog(INFO, "SPI_execexecute error: fail to set attribute to grp_name.");

SPI_finish();

return PointerGetDatum(rettuple);

}

/* add primary key to perm_member */

ret = SPI_exec("ALTER TABLE perm_member ADDPRIMARY KEY (user_name, grp_name);", 0);

if (ret != SPI_OK_UTILITY) {

elog(INFO, "SPI_execexecute error: fail to add primary key to perm_member.");

SPI_finish();

returnPointerGetDatum(rettuple);

}

}

/*close connect with SPI manager */

SPI_finish();

/* return back must be NULL*/

return PointerGetDatum(rettuple);

}

這個函數寫法與postgresql服務端函數的寫法很相似, 但是不完全相同.具體需要注意的地方是:

1. 需要多添加頭文件:#include commands/trigger.h

2. 這個函數的返回值一定是trigger類型的.

3. 函數的開始最好確認這個函數是供觸發器調用的并且明確一下自己要寫的觸發器的類型是什么,然后做一下判斷,以免別的語句也觸發的觸發器.

二. 接下來的事情是編譯:

gcc -fpic -c trigger.c-I/usr/local/postgreSQL/include/postgresql/server

gcc -shared -o trigger.so trigger.o

如果不明白可以參考手冊(說句題外話,手冊的作用實在是太大了,在手冊中也提供了一例子).

三. 在數據庫中創建函數和觸發器:

/* create a trigger used to write memory and configmemory */

CREATE OR REPLACE FUNCTION pg_trigf() RETURNS trigger

AS 'filename'

LANGUAGE C IMMUTABLESTRICT;

CREATE TRIGGER tbuser BEFORE INSERT OR UPDATE OR DELETE

ON tbl_user FOR EACH STATEMENT

EXECUTE PROCEDURE pg_trigf();

CREATE TRIGGER tbgroup BEFORE INSERT OR UPDATE OR DELETE

創建的觸發器是語句觸發器,這個和手冊上的不一樣, 手冊上的是行觸發器.

然后在數據庫中使用SQL語句就可以看到觸發器的效果了.

本文標題:包含postgresql說明的詞條
標題URL:http://www.yijiale78.com/article12/dsccjdc.html

成都網站建設公司_創新互聯,為您提供品牌網站制作面包屑導航搜索引擎優化商城網站營銷型網站建設網站維護

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

外貿網站建設