SQL 命令
這部分包含那些 PostgreSQL 支持的 SQL 命令的信息.這里的 "SQL" 就是該語言通常的含義; 每條命令的與標準有關的兼容性的信息可以在相關的參考頁中找到.
Table of Contents
ABORT -- 退出當前事務
ALTER GROUP -- 向組中增加用戶或從組中刪除用戶
ALTER USER -- 改變數據庫用戶帳號.
ANALYZE -- 收集與數據庫有關的統計
BEGIN -- 開始一個事務塊
CHECKPOINT -- 強制一個事務日志檢查點
CLOSE -- 關閉一個游標
CLUSTER -- 根據一個索引對某個表集簇
COMMENT -- 定義或者改變一個對象的評注
COMMIT -- 提交當前事務
COPY -- 在表和文件之間拷貝數據
CREATE AGGREGATE -- 定義一個新的聚集函數
CREATE CONSTRAINT TRIGGER -- 定義一個新的約束觸發器
CREATE DATABASE -- 創建新數據庫
CREATE FUNCTION -- 定義一個新函數
CREATE GROUP -- 定義一個新的用戶組
CREATE INDEX -- 定義一個新索引
CREATE LANGUAGE -- 定義一種新的過程語言
CREATE OperaTOR -- 定義一個新的操作符
CREATE RULE -- 定義一個新的重寫規則
CREATE SEQUENCE -- 創建一個新的序列發生器
CREATE TABLE -- 定義一個新表
CREATE TABLE AS -- 從一條查詢的結果中創建一個新表
CREATE TRIGGER -- 定義一個新的觸發器
CREATE TYPE -- 定義一個新的數據類型
CREATE USER -- 創建一個新的數據庫用戶帳戶
CREATE VIEW -- 定義一個視圖
DECLARE -- 定義一個游標
DELETE -- 刪除一個表中的行
DROP AGGREGATE -- 刪除一個用戶定義的聚集函數
DROP DATABASE -- 刪除一個數據庫.
DROP FUNCTION -- 刪除一個用戶定義的函數
DROP GROUP -- 刪除一個用戶組
DROP INDEX -- 刪除一個索引
DROP LANGUAGE -- 刪除一個用戶定義的過程語言
DROP OPERATOR -- 刪除一個用戶定義操作符
DROP RULE -- 刪除一個重寫規則
DROP SEQUENCE -- 刪除一個序列
DROP TABLE -- 刪除一個表
DROP TRIGGER -- 刪除一個觸發器定義.
DROP TYPE -- 刪除一個用戶定義數據類型
DROP USER -- 刪除一個數據庫用戶帳號
DROP VIEW -- 刪除一個視圖
END -- 提交當前的事務
EXPLAIN -- 顯示語句執行規劃
FETCH -- 用游標從表中抓取行
GRANT -- 定義訪問權限
INSERT -- 在表中創建新行
LISTEN -- 監聽一個通知
LOAD -- 裝載或重載一個共享庫文件
LOCK -- 明確地鎖定一個表
MOVE -- 把游標放到表中的特定的行
NOTIFY -- 生成一個通知
REINDEX -- 恢復一個損壞了的索引
RESET -- 把一個運行時參數值恢復為缺省值
REVOKE -- 刪除訪問權限.
ROLLBACK -- 退出當前事務
SELECT -- 從表或視圖中取出若干行.
SELECT INTO -- 從一個查詢的結果中創建一個新表
SET -- 改變運行時參數
SET CONSTRAINTS -- 設置當前事務的約束模式
SET session AUTHORIZATION -- 為當前會話設置會話用戶標識符和當前用戶標識符
SET TRANSACTION -- 設置當前事務的特性
SHOW -- 顯示運行時參數的數值
TRUNCATE -- 清空一個表
UNLISTEN -- 停止監聽通知信息
UPDATE -- 更新一個表中的行
VACUUM -- 垃圾收集以及可選地分析一個數據庫
--------------------------------------------------------------------------------
ABORT 退出當前事務
ABORT Name
ABORT -- 退出當前事務
Synopsis
ABORT [ WORK | TRANSACTION ]
輸入
無
輸出
ROLLBACK 成功的返回信息.
NOTICE: ROLLBACK: no transaction in PRogress
如果當前沒有任何正在處理的事務存在.
描述
ABORT回卷當前事務并且廢棄所有當前事務中做的更新. 這個命令和 命令 ROLLBACK 完全一樣, 只是由于歷史原因而保留下來.
注意
用COMMIT語句可以成功地結束/提交一個事務.
用法
取消所有更改:
ABORT WORK;
兼容性 SQL92
此命令是 PostgreSQL 基于歷史原因做的擴展. ROLLBACK 是 中等價的命令.
--------------------------------------------------------------------------------
ALTER GROUP向組中增加用戶或從組中刪除用戶
ALTER GROUP
Name
ALTER GROUP -- 向組中增加用戶或從組中刪除用戶
Synopsis
ALTER GROUP name ADD USER username [, ... ]
ALTER GROUP name DROP USER username [, ... ]
輸入
Name
要更改的組名稱。
Username
準備向組中增加或從組中刪除的用戶名。用戶名必須已經存在。
輸出
ALTER GROUP
更改成功的返回信息。
描述
ALTER GROUP用于向組中增加用戶或者從組中刪除用戶。 只有數據庫超級用戶才能使用這條命令。向組中增加用戶并不創建用戶。同樣從組中刪除用戶也不刪除用戶本身。
使用 CREATE GROUP創建新組以及 DROP GROUP刪除一個組。
用法
向組中增加用戶:
ALTER GROUP staff ADD USER Karl, john;
從組中刪除用戶:
ALTER GROUP workers DROP USER Beth;
兼容性 SQL92
里沒有 ALTER GROUP 語句。角色(roles)的概念與之類似。
--------------------------------------------------------------------------------
ALTER TABLE修改表的定義
ALTER TABLE
Name
ALTER TABLE -- 修改表的定義
Synopsis
ALTER TABLE [ ONLY ] table [ * ]
ADD [ COLUMN ] column type [ column constraint [ ... ] ]
ALTER TABLE [ ONLY ] table [ * ]
ALTER [ COLUMN ] column { SET DEFAULT value | DROP DEFAULT }
ALTER TABLE [ ONLY ] table [ * ]
ALTER [ COLUMN ] column SET STATISTICS integer
ALTER TABLE [ ONLY ] table [ * ]
RENAME [ COLUMN ] column TO new column
ALTER TABLE
RENAME TO new table
ALTER TABLE
ADD table constraint definition
ALTER TABLE [ ONLY ] table
DROP CONSTRAINT constraint
{ RESTRICT | CASCADE }
ALTER TABLE table
OWNER TO new owner
輸入
table
試圖更改的現存表的名稱.
column
現存或新的列名稱.
type
新列的類型.
newcolumn
現存列的新名稱.
new table
表的新名稱.
table constraint definition
表的新的約束定義.
New user
該表的新所有者的用戶名.
輸出
ALTER
從被改名的列或表返回的信息.
ERROR
如果一個列或表不存在返回的信息.
描述
ALTER TABLE變更一個現存表的定義.
ADD COLUMN形式使用與 CREATE TABLE一樣的語法向表中增加一個新列/字段。
ALTER COLUMN SET/DROP DEFAULT形式允許你從列/字段中設置或者刪除缺?。ㄖ担?注意缺?。ㄖ担┲贿m用于隨后的 INSERT 命令。 它們不會改變已經存在于表中的行.
ALTER COLUMN SET STATISTICS形式允許你為 隨后的 ANALYZE 操作 設置收集統計信息的對象.
RENAME 子句可以在不影響任何相關數據的情況下更改 一個表,字段,索引或者序列名稱。因此, 在此命令執行后數據仍將是相同尺寸和類型。
ADD table constraint definition子句使用與 CREATE TABLE一樣的語法向表中增加一個新的約束。
DROP CONSTRAINT constraint子句刪除所有表上匹配 constraint 的 CHECK 約束(以及其子表)
OWNER 把該表的所有者改為用戶 new user.
如果要改變表的綱要,你必須是表的所有者.
注意
COLUMN 關鍵字是多余的,可以省略.
在目前的 ADD COLUMN實現里還不支持 新列/字段的缺省(值)和 NOT NULL 子句。不過你可以隨后用 ALTER TABLE 的 SET DEFAULT 形式設置缺省(值)。(你可能還想用 UPDATE 把已存在行更新為缺省值。)
目前只有 CHECK 約束可以從表中刪除.RESTRICT 關鍵字是必須的,盡管 并不檢查依賴性.還不支持 CASCADE 選項.要刪除一個 PRIMARY 或者 UNIQUE 約束,用 DROP INDEX 命令刪除相關的索引. 要刪除 FOREIGN KEY 約束,你需要重新創建并重新裝載該表, 創建的時候使用 CREATE TABLE命令的其它參數.
比如,要刪除在表 distributors 上的所有約束∶
CREATE TABLE temp AS SELECT * FROM distributors;
DROP TABLE distributors;
CREATE TABLE distributors AS SELECT * FROM temp;
DROP TABLE temp;
要修改表的結構,你必須是表的所有人。不允許更改系統表結構的任何部分。 PostgreSQL 用戶手冊里有關于繼承的更多信息.
請參考CREATE TABLE 部分獲取更多有效參數的描述.
用法
向表中增加一個 varchar 列:
ALTER TABLE distributors ADD COLUMN address VARCHAR(30);
對現存列改名:
ALTER TABLE distributors RENAME COLUMN address TO city;
更改現存表的名字∶
ALTER TABLE distributors RENAME TO suppliers;
給一個表增加一個檢查約束∶
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
刪除一個表和它的所有子表的監查約束∶
ALTER TABLE distributors DROP CONSTRAINT zipchk;
向表中增加一個外鍵約束:
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses(address) MATCH FULL;
給表增加一個(多字段)唯一約束∶
ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
兼容性 SQL92
ADD COLUMN 形式是兼容的,除了上面說的缺?。ㄖ担┖?NOT NULL 約束外。 ALTER COLUMN 形式是完全兼容的。
對 ALTER TABLE 聲明了一些附加的 PostgreSQL 目前還不直接支持的功能:
ALTER TABLE table DROP [ COLUMN ] column { RESTRICT | CASCADE }
從一個表中刪除一個列. 目前,要刪除一個現存的列,表必須重新創建和重新裝載:
CREATE TABLE temp AS SELECT did, city FROM distributors;
DROP TABLE distributors;
CREATE TABLE distributors (
did DECIMAL(3) DEFAULT 1,
name VARCHAR(40) NOT NULL
);
INSERT INTO distributors SELECT * FROM temp;
DROP TABLE temp;
重命名表,列/字段,索引,和序列的名字是 PostgreSQL 對 的擴展。
--------------------------------------------------------------------------------
ALTER USER
ALTER USER
Name
ALTER USER -- 改變數據庫用戶帳號.
Synopsis
ALTER USER username [ [ WITH ] option [ ... ] ]
這里 option 可以是∶
[ ENCRYPTED | UNENCRYPTED ] PASSWord 'password'
| CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| VALID UNTIL 'abstime'
輸入
username
想進行更改的用戶的名字。
[ encrypted | unencrypted ] password
此帳號所使用的新口令。 Encrypted/ unencrypted 控制該口令在數據庫里是否以加密形式存儲.
CREATEDB
NOCREATEDB
這個子句定義該用戶創建數據庫的能力。 如果聲明了 CREATEDB,該用戶可以創建她自己的數據庫。用 NOCREATEDB 將剝奪一個用戶創建數據庫的能力。
CREATEUSER
NOCREATEUSER
這個子句決定一個用戶能否創建新用戶。 這個選項同樣還令該用戶成為超級用戶,可以超越所有訪問限制。
abstime
該用戶帳號口令的有效日期(和可選的時間)。
輸出
ALTER USER
更改成功的返回信息.
ERROR: ALTER USER: user "username" does not exist
如果數據庫不認識你所聲明的用戶返回的信息.
描述
ALTER USER用于更改用戶的 PostgreSQL 帳號的屬性.沒有在該命令中出現的屬性保持原值.
只有一個數據庫超級用戶可以用這個命令更改權限和口令有效期。 普通用戶只能更改他們自己的口令。
ALTER USER無法改變一個用戶的組的成員性. 用 ALTER GROUP實現這個目地.
使用 CREATE USER創建新用戶和 DROP USER刪除用戶。
用法
更改一用戶口令:
ALTER USER divide WITH PASSWORD 'hu8jmn3';
更改一用戶有效期
ALTER USER Manuel VALID UNTIL 'Jan 31 2030';
更改一用戶有效期, 聲明其權限應該在用比UTC早一小時的時區記時的1998年5月4日正午失效
ALTER USER Chris VALID UNTIL 'May 4 12:00:00 1998 +1';
賦予一用戶創建新用戶和新數據庫的權限:
ALTER USER Miriam CREATEUSER CREATEDB;
兼容性 SQL92
里沒有 ALTER USER. 該標準將用戶定義部分交給具體數據庫實現處理.
--------------------------------------------------------------------------------
ANALYZE
ANALYZE
Name
ANALYZE -- 收集與數據庫有關的統計
Synopsis
ANALYZE [ VERBOSE ] [ table [ (column [, ...] ) ] ]
輸入
VERBOSE
打開處理過程信息的顯示.
table
要分析的特定表的名字.缺省是所有表.
column
要分析的特定行的名字.缺省是所有列.
輸出
ANALYZE
命令已經結束了.
描述
ANALYZE收集有關 PostgreSQL 表的內容的統計,然后把結果保存在系統表 pg_statistic 里.隨后,查詢規劃器就可以使用這些統計幫助判斷查詢的最有效的 規劃.
如果沒有參數,ANALYZE 檢查在當前數據庫里的所有 表.如果有參數,ANALYZE 只檢查那個表. 你還可以給出一列字段名字,這個時候只有那些字段的統計信息被更新.
注意
周期性地運行 ANALYZE,或者在對表的 大部分內容做了更改之后馬上運行它是個好習慣,準確的統計信息將幫助規劃器選擇最合適的查詢規劃,并因此 而改善查詢處理的速度.一種比較經常采用的策略是每天在 低負荷的時候運行一次 VACUUM和 ANALYZE.
和 VACUUM FULL 不同的是, ANALYZE 只需要在目標表上有一個讀取鎖, 因此它可以和表上的其它活動并行地運行.
對于大表,ANALYZE 采集表內容的一個隨機的抽樣做 統計,而不是檢查每一行.這樣即使是很大的表,我們也只需要很少的一些時間就可以完成分析.不過要注意的是統計只是近似的結果,而且每次運行ANALYZE都會有一些小變化,即使表內容實際上 沒有改變也這樣.這樣會導致 EXPLAIN 所顯示的 規劃器計算的開銷有一些小變化,
收集的統計信息通常包括一個每字段最常用數值的列表以及一個包線圖,顯示每個字段里數據的近似分布.如果 ANALYZE 認為它們都沒有什么用, (比如,在一個唯一鍵字的字段上沒有公共的數值) 或者是該字段數據類型不支持相關的操作符,那么它們都可以忽略.在用戶手冊 中有關于統計的更多信息.
分析的廣度可以通過用 ALTER TABLE ALTER COLUMN SET STATISTICS (參閱 ALTER TABLE調整每字段的統計目標來控制.目標數值設置最常用數值列表中的記錄的最大數目以及包線圖中的最大塊數.缺省的目標數值是 10,不過我們可以調節 這個數值獲取規劃器計算精度和 ANALYZE 運行所需要的 時間以及 pg_statistic 里面占據的空間數目之間的 平衡.特別是,把統計目標設置為零就關閉了該字段的統計收集. 對那些從來不參與到查詢的 WHERE,GROUP BY,或者 ORDER BY 子句里的字段 是很有用的,因為規劃器不會使用到這樣的字段上的統計. )
在被分析的字段中最大的統計目標決定為統計采樣的表中的行的數目. 增大目標會導致做 ANALYZE 的時候成比例地 增大對時間和空間的需求.
兼容性 SQL92
里沒有 ANALYZE 語句.
--------------------------------------------------------------------------------
BEGIN
BEGIN
Name
BEGIN -- 開始一個事務塊
Synopsis
BEGIN [ WORK | TRANSACTION ]
輸入
WORK
TRANSACTION
可選關鍵字。沒什么作用。
輸出
BEGIN
這表明一個新的事務已經開始.
NOTICE: BEGIN: already a transaction in progress
這表明該事務已經運行,當前事務不受影響.
描述
缺省時,PostgreSQL 以 非鏈接模式(unchained mode)(在其他數據庫系統里也稱之為"自動提交("autocommit"))"。換句話說,每個用戶語句都是在其自身的事務中運行并且在語句結束時隱含的調用一個提交(commit)(如果執行成功則提交,否則調用一個回卷)。 BEGIN 以鏈接模式(chained mode)初始化一個用戶事務,也就是說所有 BEGIN 命令后的用戶語句都將在一個事務里面執行直到一個明確的 COMMIT, ROLLBACK,或執行退出(abort)。在鏈接模式里執行的語句很明顯地快得多,因為事務開始/提交(start/commit)需要大量的CPU和磁盤活動。在一個事務內部執行多條語句時因為可能修改若干個相關的表因而同樣需要一致性。
在 PostgreSQL 里缺省的事務隔離級別是 READ COMMITTED, 這時在事務內部的查詢只看到查詢提交之前的(數據)修改。 所以,如果你需要更嚴格的事務隔離,你必須在 BEGIN 后馬上使用 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE。 在 SERIALIZABLE 模式里,查詢將只能看到整個事務開始之前的修改。 (實際上是在一個可串行化事務內部第一個 DML 語句執行前的數據)。
如果提交了事務, PostgreSQL 將保證要么實現所有更新, 要么所有更新都沒有實現。事務有標準的 ACID (原子性,一致性,隔離性,持續性) (atomic,consistent,isolatable,and durable)屬性。
注意
請參考 LOCK語句獲取關于在事務內部鎖定一個表的詳細信息.
使用 COMMIT或者 ROLLBACK結束一個事務.
用法
開始一個用戶事務:
BEGIN WORK;
兼容性 SQL92
BEGIN是 PostgreSQL 語言的擴展. 在 中沒有明確的 BEGIN 的定義;事務初始化總是隱含的而且使用一個 COMMIT 或者 ROLLBACK 語句終止.
注意: 許多關系型數據庫為了方便提供一個自動提交(autocommit)特性。
順便說一句,BEGIN 關鍵字在嵌入 SQL 里用于不同的目的。 我們建議你在移植數據庫應用時仔細檢查事務的語意。
還要求事務的缺省隔離級別是 SERIALIZABLE。
CHECKPOINT
CHECKPOINT
Name
CHECKPOINT -- 強制一個事務日志檢查點
Synopsis
CHECKPOINT
描述
預寫式日志(Write-Ahead Logging (WAL))缺省時在事務日志中每隔一段時間放一個檢查點.(要調整這個原子化的檢查點間隔,你可以參考運行時 選項 CHECKPOINT_SEGMENTS 和 CHECKPOINT_TIMEOUT .) CHECKPOINT 強迫在命令聲明時立即進行檢查, 而不是等到下一次調度時的檢查點.
檢查點是一個事務日志訓練中的點,在該點,所有數據文件都被更新 以反映日志中的信息.所有數據文件都將被沖刷到磁盤.請參考 PostgreSQL 管理員手冊獲取更多有關 WAL 系統的信息.
只有超級用戶可以調用 CHECKPOINT. 該命令不是設計用于正常操作過程中的.
又見
PostgreSQL 管理員手冊
兼容性 SQL92
CHECKPOINT命令是 PostgreSQL 語言的擴展.
--------------------------------------------------------------------------------
CLOSE
CLOSE
Name
CLOSE -- 關閉一個游標
Synopsis
CLOSE cursor
輸入
cursor 一個待關閉的游標的名字.
輸出
CLOSE 游標關閉成功返回的信息.
NOTICE PerformPortalClose: portal "cursor" not found
如果該 cursor 沒有聲明或已經關閉,返回該信息.
描述
CLOSE釋放和一個游標關聯的資源. 一個游標關閉后,不允許對其再做任何操作.一個不再使用的游標應該關閉掉.
如果用 COMMIT 或 ROLLBACK 提交了一個事務,將對每個打開的游標執行隱含的關閉操作.
注意
PostgreSQL 沒有明確的 OPEN (打開)游標的語句; 我們認為一個游標在聲明時就打開了.使用 DECLARE 語句聲明一個游標.
用法
關閉游標liahona:
CLOSE liahona;
兼容性 SQL92
CLOSE與 完全兼容.
--------------------------------------------------------------------------------
CLUSTER
Name
CLUSTER -- 根據一個索引對某個表集簇
Synopsis
CLUSTER indexname ON table name
輸入
indexname
一個索引名稱.
table
準備建簇的表的名稱.
輸出
CLUSTER
成功建簇.
ERROR: relation <tablerelation_number> inherits "table"
ERROR: Relation table does not exist!
描述
CLUSTER指示PostgreSQL 近似地基于索引 indexname 的度量對表 table 進行存儲建簇. 索引必須已經在表 table name. 上定義了.
當對一個表建簇后,該表的物理存儲將基于索引信息進行. 建簇是靜態的,也就是說,當表被更新后,改變的內容不會建簇. 不會試圖對更新過的記錄重新建簇.如果需要,可以通過手工執行該命令的方法重建簇.
注意
該表實際上按索引順序拷貝到了一個臨時表中,然后重新改成原名. 因此,在建簇時所有賦予的權限和其它索引都將丟失.
如果你只是隨機的訪問表中的行, 那么在堆表中的數據的實際存儲順序是無關緊要的. 但是,如果你對某些數據的訪問多于其他數據,而且有一個索引將這些數據分組,那你就將從 使用 CLUSTER 中獲益.
另一個CLUSTER 很有幫助的例子是當你用索引從一個表中取出幾個記錄時. 如果你從一個表中請求一定索引范圍的值,或者是一個索引過的值對應多行, CLUSTER 也會有助于應用,因為如果索引標識出第一匹配行所在的堆存儲頁,所有 其他行也可能已經在同一堆存儲頁里了,這樣便節省了磁盤訪問的時間,加速了查詢.
有兩種建簇的數據.第一種是用 CLUSTER 命令,此命令將原表按你聲明的索引重新排列.這個動作在操作大表時可能會很慢,因為每一行都從堆存儲頁里按索引順序取出,如果存儲頁表沒有排序,整個表是隨機存放在各個頁面的,因而每行都要進行依次磁盤頁面操作. PostgreSQL 有一個緩沖, 但一個大表的主體是不可能都放到緩沖去的.
另一個對數據建簇的方法是使用
SELECT column list INTO TABLE new table
FROM table ORDER BY column list
這個用法使用PostgreSQL 排序的代碼 ORDER BY 來匹配索引,在對未排序的數據操作時速度快得多. 然后你可以刪除舊表,用 ALTER TABLE...RENAME將 new table 改成舊表名, 并且重建該表所有索引.唯一的問題是 OID 將不保留.這時再做 CLUSTER 將快得多, 因為大多數堆棧數據已經排過序了而且使用現有的索引.
用法
以雇員的薪水屬性對雇員關系建簇.
CLUSTER emp_ind ON emp;
兼容性 SQL92
在 規范里沒有 CLUSTER 語句.
--------------------------------------------------------------------------------
COMMENT
COMMENT
Name
COMMENT -- 定義或者改變一個對象的評注
Synopsis
COMMENT ON
[
[ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] object_name |
COLUMN table_name.column_name|
AGGREGATE agg_name agg_type|
FUNCTION func_name (arg1, arg2, ...)|
OPERATOR op (leftoperand_type rightoperand_type) |
TRIGGER trigger_name ON table_name
] IS 'text'
輸入
object_name, table_name, column_name, agg_name, func_name, op, trigger_name
要加入評注的對象名稱.
text
要加入的評注.
輸出
COMMENT 成功對表評注后的返回.
描述
COMMENT 存儲一個數據庫對象的評注, 這個評注可以很容易用 psql的 /dd或 /d+ 或者 /l+ 命令檢索出來.其它檢索評注的用戶接口可以建設在 psql 所用地同樣地內部函數的基礎上,也就是 obj_description() 和 col_description().
要修改一個評注,為同一個對象發出一條新的 COMMENT 命令即可.每個對象只存儲一條評注. 要刪除評注,在文本字串的位置寫上 NULL.當刪除對象時,評注自動被刪除掉.
需要說明的是目前評注沒有安全機制∶任何聯接到某數據庫上地用戶 都可以看到所有該數據庫對象地評注(盡管只有超級用戶可以修改 不屬于它地對象的評注).因此,不要在評注里放安全性敏感地信息.
用法
給表mytable 加評注:
COMMENT ON mytable IS 'This is my table.';
一些例子:
COMMENT ON DATABASE my_database IS 'Development Database';
COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
COMMENT ON TABLE my_table IS 'Employee Information';
COMMENT ON TYPE my_type IS 'Complex Number support';
COMMENT ON VIEW my_view IS 'View of departmental costs';
COMMENT ON COLUMN my_table.my_field IS 'Employee ID number';
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two text';
COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
兼容性 SQL92
里沒有COMMENT.
--------------------------------------------------------------------------------
COMMIT
COMMIT
Name
COMMIT -- 提交當前事務
Synopsis
COMMIT [ WORK | TRANSACTION ]
輸入
WORK
TRANSACTION
可選關鍵字。沒有作用。
輸出
COMMIT
提交成功返回此信息.
NOTICE: COMMIT: no transaction in progress
如果過程中沒有事務,返回此信息.
描述
COMMIT提交當前事務. 所有事務的更改都將為其他事務可見,而且保證當崩潰發生時的可持續性.
注意
關鍵字 WORK 和 TRANSACTION 都可以忽略.
使用 ROLLBACK語句退出一次事務.
用途
要讓所有變更永久化:
COMMIT WORK;
兼容性 SQL92
只聲明了兩種形式 COMMIT 和 COMMIT WORK。否則完全兼容。
--------------------------------------------------------------------------------
COPY
COPY
Name
COPY -- 在表和文件之間拷貝數據
Synopsis
COPY [ BINARY ] table [ WITH OIDS ] FROM { 'filename' | stdin } [ [USING] DELIMITERS 'delimiter' ] [ WITH NULL AS 'null string' ]COPY [ BINARY ] table [ WITH OIDS ] TO { 'filename' | stdout } [ [USING] DELIMITERS 'delimiter' ] [ WITH NULL AS 'null string' ] 輸入
BINARY
改變字段格式行為,強制所有數據都使用二進制格式存儲和讀取, 而不是以文本的方式. DELIMITERS 和 WITH NULL 選項和二進制格式無關.
table
現存表的名字.
WITH OIDS
拷貝每行的內部唯一對象標識(OID).
filename
輸入或輸出的 Unix 文件的絕對文件名.
stdin
聲明輸入是來自客戶端應用.
stdout
聲明輸入前往客戶端應用.
delimiter
用于在文件中每行中分隔各個字段的字符.
null string
個代表 NULL 值的字串。缺省是 "/N" (反斜杠-N)。 當然,你可以自己挑一個空字串。
注意: 對于拷貝入(copy in),任何匹配這個字串的字串將被存儲為 NULL 值, 所以你應該確保你用 的字串和拷貝出(copy out)相同。
輸出
COPY
拷貝成功完成.
ERROR: reason
拷貝失敗,原因在錯誤信息里.
描述
COPY在 PostgreSQL表和標準文件系統文件之間交換數據. COPY TO 把一個表的所有內容都拷貝到一個文件, 而 COPY FROM 從一個文件里拷貝數據到一個表里 (把數據附加到表中已經存在的內容里).
COPY指示 PostgreSQL 后端直接從文件中讀寫數據.如果聲明了文件名,那么該文件必須為后 端可見,而且文件名必須從后端的角度聲明.如果聲明的是 stdin 或 stdout, 數據通過客戶前端流到后端.
小提示: 不要把 COPY 和 psql 指令 /copy 混淆在一起. /copy 調用 COPY FROM stdin 或 COPY TO stdout,然后抓取/存儲 psql 客戶端可以訪問的一個文件里. 因此,使用 /copy 的時候,可訪問性和訪問權限取決于客戶端而不是服務器端.
注意
BINARY 關鍵字將強制使用二進制對象而不是文本存儲/讀取所有數據. 這樣做在一定程度上比傳統的拷貝命令快,但二進制拷貝文件在不同機器體系間的植性不是很好.
缺省地,文本拷貝使用 tab ("/t")字符作為分隔符. 分隔符仍然可以用關鍵字 USING DELIMITERS 改成任何其它的字符. 在數據中碰巧與分隔符相同的字符將用反斜扛引起.
你對任何要COPY 出來的數據必須有select 權限,對任何要 COPY 入數據的表必須有 insert 或 update 權限. 使用 COPY 時后端同樣需要適當的對文件操作的 Unix 權限.
COPY TO不會激活規則,也不會處理字段缺省值。不過它的確激活觸發器和檢查約束。
COPY 在第一個錯誤處停下來.這些在 COPY FROM中不應該導致問題,但在 COPY TO 時目的表會已經接收到早先的行,這些行將不可見或不可訪問,但是仍然會占據磁盤空間. 如果你碰巧是拷貝很大一塊數據文件的話,積累起來,這些東西可能會占據相當大的一部分磁盤空間.你可以調用 VACUUM來恢復那些磁盤空間.
COPY命令里面的文件必須是可以由后端直接讀或寫的文件,而不是由客戶端應用讀寫.因此,它們必須位于數據庫服務器上或者可以為數據庫服務器所訪問, 而不是由客戶端做這些事情.它們必須是PostgreSQL用戶(服務器運行的用戶 ID) 可以訪問到并且 可讀或者可寫,而不是客戶端. COPY 到一個命名文件是只允許數據庫超級用戶進行的, 因為它允許寫任意后端有權限寫的文件.
小技巧: psql指令 /copy 以客戶的權限讀或寫在客戶端的文件,因此不局限于超級用戶.
我們建議在 COPY 里的文件名字總是使用 絕對路徑.在 COPY TO 的時候是由后端強制 進行的,但是對于 COPY FROM,你的確有從一個聲明為相對路徑的文件里讀取的選擇.該路徑將解釋為相對于后端的 工作目錄(在 $PGDATA 里的什么地方),而不是客戶端的工作目錄.
文件格式
文本格式
當不帶 BINARY 選項使用 COPY TO 時,生成的文件每條元組占據一行,每列(字段)用分隔符分開.內嵌的分隔符字 符將由一個反斜杠("/")開頭.字段值本身是由與每個字段類型相關的輸出函數生成的字符串.某一類型的輸出函數本身不應該生成反斜杠;這個任務由 COPY 本身完成.
每個元組的實際格式是
<attr1><separator><attr2><separator>...<separator><attrn><newline> 請注意每行的結尾是用 Unix 風格的換行符("/n")標記的. 如果給出的文件包含 DOS 或 Mac 風格的換行符,那么 COPY FROM 將會出錯.
如果聲明了 WITH OIDST,它將被放在每行的開頭.
如果 COPY TO 將它的輸出輸出到標準輸出而不是一個文件, 在拷貝結束時,它將在一個新行上輸出一個反斜杠("/")和一個句點("."),最后是一個換行符做為文件結束符.類似,如果 COPY FROM 從標準輸入讀入數據,它將把一行開頭的由一個反斜杠("/")和一個句點(".")和一個換行符組成的這三個連續字符作為文件結束符. 不過,如果在這個特殊的文件結束模式出現前關閉了輸入聯接,那么COPY FROM 將正確結束(接著就是后端自身).
反斜杠有其他的含義.一個文本反斜杠字符輸出成兩個連續的反斜杠 ("//") 一個文本tab字符用一個反斜 杠后面跟一個tab代表. (如果你使用了非 tab 作為列分隔符,那么在數據中出現的該字符將會使用反斜扛轉意.) 一個文本新行字符用一個反斜杠和一個新行代表. 當裝載不是由 PostgreSQL 生成的文件時,你需要將反 斜杠字符 ("/")轉換成雙反斜杠("//")以保證正確裝載.
二進制格式
在PostgreSQLv7.1 中的 COPY BINARY 的文件格式做了變化.新格式由一個文件頭,零或多條元組, 以及文件尾組成.
文件頭
文件頭由 24 個字節的固定域組成,后面跟著一個變長的頭擴展區.固定域是:
簽名
12- 字節的序列 "PGBCOPY/n/377/r/n/0" --- 請注意空是簽名是要求的一部分.(使用這個簽名是為了讓我們能夠很容易看出文件是否已經被一個非 8 位安全的轉換器給糟蹋了.這個簽名會被換行符轉換過濾器,刪除空,刪除高位,或者奇偶的改變而改變.)
整數布局域
以源機器的字節序的 int32 常量 0x1020304.如果在這里偵測到錯誤的字節序,那么讀者很可能在后面的字段列造成了字節錯位.
標志域
int32 位掩碼表示該文件格式的重要方面.位是從 0(LSB)到 31 (MSB)編碼的 --- 請注意這個域是以源機器的位權重存儲的,后繼的整數都是如此.位 16 - 31 是保留用做關鍵文件格式的;如果讀者發現一個不認識的位出現在這個范圍內,那么它應該退出.位 0-15 都保留為標志向后兼容的格式使用;讀者可以忽略這個范圍內的不認識的位.目前只定義了一個標志位,而其它的必須是零:
Bit 16
如果為 1,那么在傾倒中包括了 OID;如果為 0,則沒有
頭擴展范圍長度
int32 以字節計的頭剩余長度,不包括自身.在初始的版本里,它將會是零,后面緊跟第一條元組.對該格式的更多的修改都將允許額外的數據出現在頭中.讀者應該忽略任何它不知道該如何處理的頭擴展數據.
頭擴展數據是一個用來保留一個自定義的數據訓練用的.這個標志域無意告訴讀者擴展區的內容是什么.頭擴展的具體設計內容留給以后的版本用.
這樣設計就允許向下兼容頭附加(增加頭擴展塊,或者設置低位序標志位) 以及非向下兼容修改(設置高位標志位以標識這樣的修改,并且根據需要向擴展區域增加支持數據).
元組
每條元組都以一個 int16 計數開頭,該計數是元組中字段的數目.(目前,在一個表里的每條元組都有相同的計數,但可能不會永遠這樣.)然后后面不斷出現元組中的各個字段,在字段數據后面可能跟著一個 int16 類型長度字.類型長度域是這樣解釋的:
零
數據域是 NULL.沒有數據跟著.
> 0
數據域是定長數據類型.和類型長字相同的準確的 N 字節.
-1
數據域是變長的數據類型.下面四個字節是變長頭, 它包含包括其自身在內的所有值長度.
< -1
保留為將來使用.
對于非 NULL 域,讀者可以檢查這個類型長度是否匹配目標列的長度.這樣就提供了一種簡單但有用的檢查,核實該數據是否預期數據.
在數據域之間沒有對奇填充或者任何其它額外的數據.還要注意該格式并不區分一種數據類型是傳值還是傳參.這些東西都是非常有意的:它們可能可以提高這些文件的移植性(盡管位權重和浮點格式等問題可能仍然不能讓你進行跨機器移動二進制數據).
如果在傾倒中包括了 OID,那么該 OID 域立即跟在域計數字后面.它是一個普通的域,只不過它沒有包括在域計數.但它包括類型長度 --- 這樣就允許我們不用花太多的勁就可以處理 4 字節和 8 字節,并且如果某個家伙允許 OID 是可選的話,那么還可以把 OID 顯示成 NULL.
文件尾
文件尾包括一個 int16 字減 1.這樣就很容易與一條元組的域計數字 相區分.
如果一個域計數字既不是 -1 也不是預期的字段的數目,那么讀者應該報錯.這樣就提供了對丟失與數據的同步的額外的檢查.
用法
下面的例子把一個表拷貝到標準輸出, 使用豎直條(|)作為域分隔符:
COPY country TO stdout USING DELIMITERS '|'; 從一個 Unix 文件中拷貝數據到一個表范圍中:
COPY country FROM '/usr1/proj/bray/sql/country_data'; 下面是一個可以從 stdin 中拷貝數據 到表中的例子(因此它在最后一行中有終止序列):
AF AFGHANISTANAL ALBANIADZ ALGERIAZM ZAMBIAZW ZIMBABWE/. 請注意在這里每行里的空白實際上是一個 TAB.
下面的是同樣的數據,在一臺 linux/i586 機器上以二進制形式輸出.這些數據是用 Unix 工具 od -c 過濾之后輸出的.該表有三個域;第一個是 char(2),第二個是 text, 第三個是integer.所有的行在第三個域都是一個 null 值.
0000000 P G B C O P Y /n 377 /r /n /0 004 003 002 0010000020 /0 /0 /0 /0 /0 /0 /0 /0 003 /0 377 377 006 /0 /0 /00000040 A F 377 377 017 /0 /0 /0 A F G H A N I S0000060 T A N /0 /0 003 /0 377 377 006 /0 /0 /0 A L 3770000100 377 /v /0 /0 /0 A L B A N I A /0 /0 003 /00000120 377 377 006 /0 /0 /0 D Z 377 377 /v /0 /0 /0 A L0000140 G E R I A /0 /0 003 /0 377 377 006 /0 /0 /0 Z0000160 M 377 377 /n /0 /0 /0 Z A M B I A /0 /0 0030000200 /0 377 377 006 /0 /0 /0 Z W 377 377 /f /0 /0 /0 Z0000220 I M B A B W E /0 /0 377 377 兼容性 SQL92 在里沒有 COPY 語句.
--------------------------------------------------------------------------------
CREATE AGGREGATE
CREATE AGGREGATE
Name
CREATE AGGREGATE -- 定義一個新的聚集函數
Synopsis
CREATE AGGREGATE name ( BASETYPE = input_data_type,
SFUNC = sfunc, STYPE = state_type
[ , FINALFUNC = ffunc ]
[ , INITCOND = initial_condition ] )
輸入
name
要創建的聚集函數名.
input_data_type
本聚集函數要處理的基本數據類型. 對于不檢查輸入類型的聚集來說,這個參數可以聲明為 ANY. (比如 count(*)).
sfunc
用于處理源數據列里的每一個輸入數據的狀態轉換函數名稱. 它通常是一個兩個參數的函數,第一個參數的類型是 state_type 而第二個參數的類型是 input_data_type. 另外,對于一個不檢查輸入數據的聚集,該函數只接受一個類型為 state_type 的參數. 不管是哪種情況,此函數必須返回一個類型為 state_type的值. 這個函數接受當前狀態值和當前輸入數據條目,而返回下個狀態值.
state_type
聚集的狀態值的數據類型.
ffunc
在轉換完所有輸入域/字段后調用的最終處理函數.它計算聚集的結果. 此函數必須接受一個類型為 state_type 的參數.聚集的輸出數據類型被定義為此函數的返回類型.如果沒有聲明 ffunc 則使用聚集結果的狀態值作為聚集的結果,而輸出類型為 state_type.
initial_condition
狀態值的初始設置(值).它必須是一個數據類型 state_type 可以接受的文本常量值. 如果沒有聲明,狀態值初始為 NULL.
輸出
CREATE
命令執行成功的返回信息.
描述
CREATE AGGREGATE允許用戶或程序員通過定義新的聚集函數來擴展 PostgreSQL 的功能.一些用于基本類型的聚集函數如 min(integer) 和 avg(double precision) 等已經包含在基礎軟件包里了.如果你需要定義一個新類型或需要一個還沒有提供的聚集函數,這時便可用 CREATE AGGREGATE 來提供我們所需要的特性.
一個聚集函數是用它的名字和輸入數據類型來標識的. 如果兩個聚集的輸入數據不同,它們可以有相同的名字.要避免沖突, 不要寫一個與聚集同名而且輸入函數也相同的普通函數.
一個聚集函數是用一個或兩個普通函數做成的: 一個狀態轉換函數 sfunc, 和一個可選的終計算函數 ffunc. 它們是這樣使用的:
sfunc( internal-state, next-data-item ) ---> next-internal-state
ffunc( internal-state ) ---> aggregate-value
PostgreSQL 創建一個類型為 stype的臨時變量. 它保存這個聚集的當前內部狀態. 對于每個輸入數據條目,都調用狀態轉換函數計算內部狀態值的新數值.在處理完所有數據后,調用一次最終處理函數以計算聚集的輸出值.如果沒有最終處理函數,那么將最后的狀態值當做返回值.
一個聚集函數還可能提供一個初始條件,也就是說, 所用的該內部狀態值的初始值.這個值是作為類型 text 的數據域存儲在數據庫里的, 不過它們必須是狀態值數據類型的合法的外部表現形式的常量. 如果沒有提供狀態,那么狀態值初始化為 NULL.
如果在 pg_proc 里該狀態轉換函數被定義為 "strict", 那么 NULL 輸入就不能調用它.這個時候,帶有這樣的轉換函數的聚集執行起來的現象如下所述.NULL 輸入的值被忽略(不調用此函數并且保留前一個狀態值).如果初始狀態值是 NULL,那么由第一個非 NULL 值替換該狀態值, 而狀態轉換函數從第二個非 NULL 的輸入值開始調用.這樣做讓我們比較容易 實現象 max 這樣的聚集.請注意這種行為只是當 state_type 與 input_data_type 相同的時候才表現出來. 如果這些類型不同,你必須提供一個非 NULL 的初始條件或者使用一個非strice的狀態轉換函數.
如果狀態轉換函數不是 strict(嚴格)的, 那么它將無條件地為每個輸入值調用,并且必須自行處理 NULL 輸入和 NULL 轉換值, 這樣就允許聚集的作者對聚集中的 NULL 有完全的控制.
如果終轉換函數定義為"strict",則如果最終狀態值是 NULL 時就不能調用它; 而是自動輸出一個NULL的結果.(當然,這才是 strict 函數的正常特征.) 不管是那種情況,終處理函數可以選擇返回 NULL.比如, avg 的終處理函數在零輸入記錄時就會返回 NULL.
注意
使用 DROP AGGREGATE 刪除聚集函數.
CREATE AGGREGATE的參數可以以任何順序書寫,而不只是上面顯示的順序.
用法
請參考 PostgreSQL 程序員手冊 聚集函數章節的聚集函數部分獲取完整的例子.
兼容性 SQL92
CREATE AGGREGATE是 PostgreSQL 語言的擴展. 在 里沒有 CREATE AGGREGATE.
--------------------------------------------------------------------------------
CREATE CONSTRAINT TRIGGER
CREATE CONSTRAINT TRIGGER
Name
CREATE CONSTRAINT TRIGGER -- 定義一個新的約束觸發器
Synopsis
CREATE CONSTRAINT TRIGGER name
AFTER events ON
relation constraint attributes
FOR EACH ROW EXECUTE PROCEDURE func '(' args ')'
輸入
name
約束觸發器的名稱.
events
觸發該觸發器的事件范圍.
relation
被觸發的關系名稱.
constraint
實際的約束聲明.
attributes
約束屬性.
func(args)
觸發器處理所調用的函數.
輸出
CREATE CONSTRAINT
成功創建后的返回信息.
描述
CREATE CONSTRAINT TRIGGER被 CREATE/ALTER TABLE 內部使用以及被 pg_dump 用于創建那些用于參考完整性的特殊的觸發器.
這條語句不是做一般用途用的.
--------------------------------------------------------------------------------
CREATE DATABASE
CREATE DATABASE
Name
CREATE DATABASE -- 創建新數據庫
Synopsis
CREATE DATABASE name
[ WITH [ LOCATION = 'dbpath' ]
[ TEMPLATE = template ]
[ ENCODING = encoding ] ]
輸入
name
要創建的數據庫名.
dbpath
在文件系統里存儲新數據庫的可選位置;用字串文本聲明. 或者用 DEFAULT 表示使用缺省位置.
template
從哪個模板創建新數據庫,這是模板名.或者用 DEFAULT 使用缺省模板(template1).
encoding
創建新數據庫用的多字節編碼方法.聲明一個字串文本名字 (比如,'SQL_ASCII'),或者一個整數編號,或者是 DEFAULT 表示使用缺省編碼.
輸出
CREATE DATABASE
命令成功執行的返回信息.
ERROR: user 'username' is not allowed to create/drop databases
你必須有特殊的 CREATEDB 權限來創建數據庫。參閱 See CREATE USER。
ERROR: createdb: database "name" already exists
如果聲明的數據庫 name 已經存在返回的信息.
ERROR: database path may not contain single quotes
數據庫路徑名 dbpath 不能包含單引號。這樣要求是為了創建數據庫目錄的 shell 命令能夠正確執行。
ERROR: CREATE DATABASE: may not be called in a transaction block
如果你有一個明確的事務塊正在處理,你不能調用 CREATE DATABASE。你必須先結束事務。
ERROR: Unable to create database directory 'path'.
ERROR: Could not initialize database directory.
這種情況最有可能是因為對數據目錄權限不夠, 磁盤已滿或其他文件系統問題。數據庫服務器運行的機器上的用戶必 須能訪問該路徑。
描述
CREATE DATABASE創建一個新的 PostgreSQL 數據庫.創建者成為新數據庫的管理員.
可以聲明一個可選的數據庫位置,例如,在另一塊硬盤上存放數據庫。 該路徑必須是事先用 initlocation命令準備好了的.
如果路徑名不包含斜杠,那么它被解釋成一個環境變量, 該變量必須為服務進程所知。這樣數據庫管理員可以對能夠在那里創建數據庫進行控制。(例如,一個用戶化的選擇是 'PGDATA2'。)如果服務器帶著 ALLOW_ABSOLUTE_DBPATHS (缺省時沒有)選項編譯,那么也允許使用以斜杠開頭為標識的絕對路徑(例如, ' '/usr/local/pgsql/data')。
缺省時,新數據庫將通過克隆標準系統數據庫 template1 來創建.不同的模板可以用 TEMPLATE = name 來寫.尤其是,如果你用 TEMPLATE = template0,你可以創建一個很純凈的數據庫,只包括你的版本的 PostgreSQL 預定義的標準對象.這個方法可以避免把任何已經加入到template1 里的本地安裝對象拷貝到新數據庫.
可選的編碼參數允許選擇數據庫編碼, 如果你的服務器是帶著多字節編碼支持編譯的話. 如果沒有聲明,缺省是所選用的模板數據庫用的編碼.
可選參數可以以任意順序寫,而不僅是上面顯示的順序.
注意
CREATE DATABASE是 PostgreSQL 語言的擴展.
使用 DROP DATABASE刪除一個數據庫.
程序 createdb是 是這個命令的 shell 腳本的封裝,提供來方便使用。
在用絕對路徑指定的可選數據庫位置時, 有一些安全和數據完整性的問題, 而且缺省時只有后端識別的環境變量可以聲明為可選的路徑.參考管理員手冊獲取更多的信息.
盡管我們可以通過把某數據庫名聲明為模板從非template1數據庫拷貝數據庫,但是這(還)不是一個通用的 COPY DATABASE 功能. 因此,我們建議當做模板使用的數據庫都應該是以只讀方式對待的.參閱管理員手冊獲取更多信息.
用法
創建一個新的數據庫:
olly=> create database lusiadas;
在另一個地方 ~/private_db創建新數據庫:
$ mkdir private_db
$ initlocation ~/private_db
The location will be initialized with username "olly".
This user will own all the files and must also own the server process.
Creating directory /home/olly/private_db
Creating directory /home/olly/private_db/base
initlocation is complete.
$ psql olly
Welcome to psql, the PostgreSQL interactive terminal.
Type: /copyright for distribution terms
/h for help with SQL commands
/? for help on internal slash commands
/g or terminate with semicolon to execute query
/q to quit
olly=> CREATE DATABASE elsewhere WITH LOCATION = '/home/olly/private_db';
CREATE DATABASE
兼容性 SQL92
在 里沒有 CREATE DATABASE 語句. 數據庫等同于目錄,其創建是由實現決定的.
--------------------------------------------------------------------------------
CREATE FUNCTION
CREATE FUNCTION
Name
CREATE FUNCTION -- 定義一個新函數
Synopsis
CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
RETURNS rettype
AS 'definition'
LANGUAGE 'langname'
[ WITH ( attribute [, ...] ) ]
CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
RETURNS rettype
AS 'obj_file' , 'link_symbol'
LANGUAGE langname
[ WITH ( attribute [, ...] ) ]
描述
CREATE FUNCTION定義一個新的函數. CREATE OR REPLACE FUNCTION 將要么創建一個新函數,要么替換現有的定義.
參數
name
要創建的函數名字.這個名字可以不是唯一的, 因為函數可以重載,膽識同名的函數必須有不同的參數類型.
argtype
該函數的數據類型(如果有).輸入類型可以是基本類型,也可以是復合類型,opaque,或者和一個現有字段相同的類型. Opaque 表示該函數接受非 SQL 類型,比如 char *. 一個字段的類型是用 tablename.columnname%TYPE 表示的;使用這個東西可以幫助函數獨立于表定義的修改.
rettype
返回數據類型.輸出類型可以聲明為一個基本類型,復合類型, setof 類型,opaque, 或者和現有字段同類型. setof 修飾詞表示該函數將返回一套條目,而不是一條條目.返回類型聲明為 opaque 的函數不返回數值.它們不能直接調用;觸發器函數可以利用這個 特性.
definition
一個定義函數的字串;含義取決于語言.它可以是一個內部函數名字, 一個指向某個目標文件的路徑,一個 SQL 查詢,或者一個用過程語言 寫的文本.
obj_file, link_symbol
這個形式的 AS 子句用于在函數的 C 源文件 名字和 SQL 函數的名字不同的時候動態聯接 C 語言函數. 字串 obj_file 是包含可動態裝載的對象的文件名,而 link_symbol 是對象的聯接符號,也就是該函數在 C 源文件列的名字.
langname
可以是 SQL,C, internal,或者 plname,這里的 plname 是一種已創建過程語言的名字. 參閱 CREATE LANGUAGE獲取細節. 為了保持向下兼容,該名字可以用單引號包圍.
attribute
一段可選的有關該函數的信息,用于優化.見下文獲取細節.
創建該函數的用戶成為該函數所有者.
下面的屬性可以出現在 WITH 子句里∶
iscachable
Iscachable 表示此函數在輸入相同時總是返回相同的值 (也就是說, 它不做數據庫查找或者是使用沒有直接在它的參數列表出現的信息)。 優化器使用 iscachable 來認知對該函數的調用進行預先計算是否安全。
isstrict
isstrict 表明如果它的任何參數是 NULL,此函數總是返回 NULL. 如果聲明了這個屬性,則如果存在 NULL 參數時不會執行該函數;而只是自動假設一個 NULL 結果.如果沒有聲明 isstrict 該函數將為 NULL 輸入調用并進行處理.那么剩下的事就是函數作者的責任來檢查 NULL 是否必須并且做相應響應.
注意
請參閱 PostgreSQL 程序員手冊 關于通過函數擴展 PostgreSQL 的章節獲取更多關于書寫外部函數的信息.
我們允許你將完整的 SQL 類型語法用于 輸入參數和返回值.不過,有些類型聲明的細節(比如, numeric 類型的精度域)是由下層函數實現負責的, 并且會被 CREATE FUNCTION 命令悄悄地吞掉. (也就是說,不再被識別或強制).
PostgreSQL 允許函數 重載;也就是說,同一個函數名可以用于幾個不同的函數, 只要它們的參數可以區分它們。不過,這個功能在用于 internal(內部)和 C 語言 的函數時要小心。
兩個 internal 函數擁有相同 C 名稱時肯定會發生鏈接時錯誤。 要解決這個問題,給它們賦予不同的 C 名稱(例如,使用參數類型做為 C 名稱的一部分),然后在 CREATE FUNCTION 的 AS 子句里面聲明這些名字。 如果 AS 子句為空,那么 CREATE FUNCTION 假設函數的 C 名稱與SQL名稱一樣。
類似的還有,如果用多個 C 語言函數重載 SQL 函數, 給每個 C 語言函數的實例一個獨立的名稱,然后使用 CREATE FUNCTION 語法里的 AS 句的不同形式來選擇每個重載的 SQL 函數的正確的 C 語言實現.
如果重復調用 CREATE FUNCTION,并且都指向同一個目標文件,那么該文件只裝載一次.要卸載和恢復裝載 該文件(可能是在開發過程中),你可以使用 LOAD命令.
使用 DROP FUNCTION 刪除一個用戶定義函數.
要更新現存函數的定義,用 CREATE OR REPLACE FUNCTION.請注意不可能用這種方法改變一個函數的名字或者參數類型 (如果你這么干,你只是會創建一個新的,不同的函數). 同樣,CREATE OR REPLACE FUNCTION 也不會讓你改變一個現存函數的返回類型.要干這些事,你必須刪除并 重新創建該函數.
如果你刪除然后重新創建一個函數,新函數和舊的并非相同實體; 你會破壞現存的引用了原有函數的規則,視圖,觸發器等等.使用 CREATE OR REPLACE FUNCTION 可以改變一個函數的定義而又不會破壞引用該函數的對象.
例子
要創建一個簡單的 SQL 函數∶
CREATE FUNCTION one() RETURNS integer
AS 'SELECT 1 AS RESULT;'
LANGUAGE SQL;
SELECT one() AS answer;
answer
--------
1
這個例子通過調用一個用戶創建的名為 funcs.so (擴展名因平臺而異)的共享庫過程創建一個 C 函數.該共享庫文件應該位于服務器的動態搜索路徑里.該路徑計算一個檢測位并且如果函數參數里的檢測位 正確就返回一個 TRUE .這些可以通過用一個 CHECK 約束實現的.
CREATE FUNCTION ean_checkdigit(char, char) RETURNS boolean
AS 'funcs' LANGUAGE C;
CREATE TABLE product (
id char(8) PRIMARY KEY,
eanprefix char(8) CHECK (eanprefix ~ '[0-9]{2}-[0-9]{5}')
REFERENCES brandname(ean_prefix),
eancode char(6) CHECK (eancode ~ '[0-9]{6}'),
CONSTRAINT ean CHECK (ean_checkdigit(eanprefix, eancode))
);
這個例子創建一個在用戶定義類型 complex 和內部類型 point 之間做類型轉換的函數。該函數是用一個從 C 源代碼編譯的動態裝載的對象來實現的。(我們演示了使用聲明共享目標文件 的準確路徑名的過時方法). 對于 PostgreSQL 而言,要自動尋找類型轉換函數,SQL 函數必須和返回類型同名,因而重載是不可避免的。 該函數名通過使用 SQL定義里 AS 子句的第二種類型來重載:
CREATE FUNCTION point(complex) RETURNS point
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
LANGUAGE C;
該函數的 C 聲明可以是∶
Point * complex_to_point (Complex *z)
{
Point *p;
p = (Point *) palloc(sizeof(Point));
p->x = z->x;
p->y = z->y;
return p;
}
兼容性 SQL92
在 SQL99 里的確定義了一個CREATE FUNCTION PostgreSQL 的和它類似但是不兼容.這個屬性是不可移植的,可以使用的不同語言也是如此.
又見
DROP FUNCTION , LOAD, PostgreSQL程序員手冊
--------------------------------------------------------------------------------
CREATE FUNCTION
Name
CREATE FUNCTION -- 定義一個新函數
Synopsis
CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
RETURNS rettype
AS 'definition'
LANGUAGE 'langname'
[ WITH ( attribute [, ...] ) ]
CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
RETURNS rettype
AS 'obj_file' , 'link_symbol'
LANGUAGE langname
[ WITH ( attribute [, ...] ) ]
描述
CREATE FUNCTION定義一個新的函數. CREATE OR REPLACE FUNCTION 將要么創建一個新函數,要么替換現有的定義.
參數
name
要創建的函數名字.這個名字可以不是唯一的, 因為函數可以重載,膽識同名的函數必須有不同的參數類型.
argtype
該函數的數據類型(如果有).輸入類型可以是基本類型,也可以是復合類型,opaque,或者和一個現有字段相同的類型. Opaque 表示該函數接受非 SQL 類型,比如 char *. 一個字段的類型是用 tablename.columnname%TYPE 表示的;使用這個東西可以幫助函數獨立于表定義的修改.
rettype
返回數據類型.輸出類型可以聲明為一個基本類型,復合類型, setof 類型,opaque, 或者和現有字段同類型. setof 修飾詞表示該函數將返回一套條目,而不是一條條目.返回類型聲明為 opaque 的函數不返回數值.它們不能直接調用;觸發器函數可以利用這個 特性.
definition
一個定義函數的字串;含義取決于語言.它可以是一個內部函數名字, 一個指向某個目標文件的路徑,一個 SQL 查詢,或者一個用過程語言 寫的文本.
obj_file, link_symbol
這個形式的 AS 子句用于在函數的 C 源文件 名字和 SQL 函數的名字不同的時候動態聯接 C 語言函數. 字串 obj_file 是包含可動態裝載的對象的文件名,而 link_symbol 是對象的聯接符號,也就是該函數在 C 源文件列的名字.
langname
可以是 SQL,C, internal,或者 plname,這里的 plname 是一種已創建過程語言的名字. 參閱 CREATE LANGUAGE獲取細節. 為了保持向下兼容,該名字可以用單引號包圍.
attribute
一段可選的有關該函數的信息,用于優化.見下文獲取細節.
創建該函數的用戶成為該函數所有者.
下面的屬性可以出現在 WITH 子句里∶
iscachable
Iscachable 表示此函數在輸入相同時總是返回相同的值 (也就是說, 它不做數據庫查找或者是使用沒有直接在它的參數列表出現的信息)。 優化器使用 iscachable 來認知對該函數的調用進行預先計算是否安全。
isstrict
isstrict 表明如果它的任何參數是 NULL,此函數總是返回 NULL. 如果聲明了這個屬性,則如果存在 NULL 參數時不會執行該函數;而只是自動假設一個 NULL 結果.如果沒有聲明 isstrict 該函數將為 NULL 輸入調用并進行處理.那么剩下的事就是函數作者的責任來檢查 NULL 是否必須并且做相應響應.
注意
請參閱 PostgreSQL 程序員手冊 關于通過函數擴展 PostgreSQL 的章節獲取更多關于書寫外部函數的信息.
我們允許你將完整的 SQL 類型語法用于 輸入參數和返回值.不過,有些類型聲明的細節(比如, numeric 類型的精度域)是由下層函數實現負責的, 并且會被 CREATE FUNCTION 命令悄悄地吞掉. (也就是說,不再被識別或強制).
PostgreSQL 允許函數 重載;也就是說,同一個函數名可以用于幾個不同的函數, 只要它們的參數可以區分它們。不過,這個功能在用于 internal(內部)和 C 語言 的函數時要小心。
兩個 internal 函數擁有相同 C 名稱時肯定會發生鏈接時錯誤。 要解決這個問題,給它們賦予不同的 C 名稱(例如,使用參數類型做為 C 名稱的一部分),然后在 CREATE FUNCTION 的 AS 子句里面聲明這些名字。 如果 AS 子句為空,那么 CREATE FUNCTION 假設函數的 C 名稱與SQL名稱一樣。
類似的還有,如果用多個 C 語言函數重載 SQL 函數, 給每個 C 語言函數的實例一個獨立的名稱,然后使用 CREATE FUNCTION 語法里的 AS 句的不同形式來選擇每個重載的 SQL 函數的正確的 C 語言實現.
如果重復調用 CREATE FUNCTION,并且都指向同一個目標文件,那么該文件只裝載一次.要卸載和恢復裝載 該文件(可能是在開發過程中),你可以使用 LOAD命令.
使用 DROP FUNCTION 刪除一個用戶定義函數.
要更新現存函數的定義,用 CREATE OR REPLACE FUNCTION.請注意不可能用這種方法改變一個函數的名字或者參數類型 (如果你這么干,你只是會創建一個新的,不同的函數). 同樣,CREATE OR REPLACE FUNCTION 也不會讓你改變一個現存函數的返回類型.要干這些事,你必須刪除并 重新創建該函數.
如果你刪除然后重新創建一個函數,新函數和舊的并非相同實體; 你會破壞現存的引用了原有函數的規則,視圖,觸發器等等.使用 CREATE OR REPLACE FUNCTION 可以改變一個函數的定義而又不會破壞引用該函數的對象.
例子
要創建一個簡單的 SQL 函數∶
CREATE FUNCTION one() RETURNS integer
AS 'SELECT 1 AS RESULT;'
LANGUAGE SQL;
SELECT one() AS answer;
answer
--------
1
這個例子通過調用一個用戶創建的名為 funcs.so (擴展名因平臺而異)的共享庫過程創建一個 C 函數.該共享庫文件應該位于服務器的動態搜索路徑里.該路徑計算一個檢測位并且如果函數參數里的檢測位 正確就返回一個 TRUE .這些可以通過用一個 CHECK 約束實現的.
CREATE FUNCTION ean_checkdigit(char, char) RETURNS boolean
AS 'funcs' LANGUAGE C;
CREATE TABLE product (
id char(8) PRIMARY KEY,
eanprefix char(8) CHECK (eanprefix ~ '[0-9]{2}-[0-9]{5}')
REFERENCES brandname(ean_prefix),
eancode char(6) CHECK (eancode ~ '[0-9]{6}'),
CONSTRAINT ean CHECK (ean_checkdigit(eanprefix, eancode))
);
這個例子創建一個在用戶定義類型 complex 和內部類型 point 之間做類型轉換的函數。該函數是用一個從 C 源代碼編譯的動態裝載的對象來實現的。(我們演示了使用聲明共享目標文件 的準確路徑名的過時方法). 對于 PostgreSQL 而言,要自動尋找類型轉換函數,SQL 函數必須和返回類型同名,因而重載是不可避免的。 該函數名通過使用 SQL定義里 AS 子句的第二種類型來重載:
CREATE FUNCTION point(complex) RETURNS point
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
LANGUAGE C;
該函數的 C 聲明可以是∶
Point * complex_to_point (Complex *z)
{
Point *p;
p = (Point *) palloc(sizeof(Point));
p->x = z->x;
p->y = z->y;
return p;
}
兼容性 SQL92
在 SQL99 里的確定義了一個CREATE FUNCTION PostgreSQL 的和它類似但是不兼容.這個屬性是不可移植的,可以使用的不同語言也是如此.
又見
DROP FUNCTION , LOAD, PostgreSQL程序員手冊
--------------------------------------------------------------------------------
CREATE GROUP
CREATE GROUP
Name
CREATE GROUP -- 定義一個新的用戶組
Synopsis
CREATE GROUP name [ [ WITH ] option [ ... ] ]
這里 option 可以是∶
SYSID gid
| USER username [, ...]
輸入
name
組名。
gid
SYSID 子句可以用于選擇 PostgreSQL 里新組的組標識(group id)。 不過,這樣做不是必須的。
如果沒有聲明這個,將使用從 1 開始的,已分配的最高組標識加一作為缺省值。
username
包括到組里面的用戶列表。用戶必須已經存在。
輸出
CREATE GROUP
成功創建組后的返回。
描述
CREATE GROUP 將在數據庫節點上創建一個新組。參考管理員手冊獲取關于使用組來認證的信息。 要使用這條命令, 你必須是數據庫超級用戶。
使用 ALTER GROUP修改組成員,DROP GROUP刪除一個組。
用法
創建一個空組:
CREATE GROUP staff
創建一個有成員的組:
CREATE GROUP marketing WITH USER jonathan, david
兼容性 SQL92
里沒有 CREATE GROUP 。Roles 在概念上與組類似。
--------------------------------------------------------------------------------
CREATE LANGUAGE
CREATE LANGUAGE
Name
CREATE LANGUAGE -- 定義一種新的過程語言
Synopsis
CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE langname
HANDLER call_handler
描述
使用 CREATE LANGUAGE, 一個PostgreSQL 用戶可以在 PostgreSQL里注冊一個新的語言.因而,函數和觸發器過程可以用這種新語言定義.要注冊新 語言用戶必須具有 PostgreSQL 超級用戶權限.
CREATE LANGUAGE將該語言的名字和一個調用句柄 關聯起來,而該調用句柄負責執行該語言書寫的函數.請參考程序員手冊獲取有關語言調用句柄的 更多信息.
請注意過程語言是對每個獨立的數據庫而言是自己的. 要讓一種語言缺省時可以為所有數據庫獲得,那你應該把它安裝到 template1 數據庫里.
參數
TRUSTED
TRUSTED 說明對該語言的調用句柄是安全的;也就是說,它不會提供給非特權用戶任何繞過訪問限制的能力. 如果忽略這個關鍵字,只有具有 PostgreSQL 超級用戶權限的人可以使用這個語言創建新的函數.
PROCEDURAL
這是個沒有用的字.
langname
新的過程化語言的名稱.語言名是大小寫無關的. 一個過程化語言不能覆蓋 PostgreSQL內置的語言.
出于向下兼容的原因,這個名字可以用單引號包圍.
HANDLER call_handler
call_handler 是一個以前注冊過的函數的名字,該函數將被調用來執行這門過程語言寫的函數.過程語言的調用句柄必須用一種編譯語言書寫,比如 C,調用風格必須是版本 1 的調用風格,并且在 PostgreSQL 里注冊為不接受參數并且返回 opaque 類型的函數, (opaque 是用于未聲明或未定義類型的占位符). undefined types.
診斷
CREATE
如果語言成功創建,返回此信息.
ERROR: PL handler function funcname() doesn't exist
如果沒有找到函數 funcname(), 則返回此信息.
注意
這條命令通常不應該由用戶直接執行. 對于 PostgreSQL 版本里提供的過程語言,我們應該使用 createlang腳本, 它將為我們安裝正確的調用句柄. (createlang 也會在內部調用 CREATE LANGUAGE.)
使用 CREATE FUNCTION 命令創建新函數.
使用 DROP LANGUAGE,或者更好是 droplang腳本刪除一個過程語言.
系統表 pg_language 記錄了更多有關 當前安裝的過程語言的信息.
Table "pg_language"
Attribute | Type | Modifier
---------------+---------+----------
lanname | name |
lanispl | boolean |
lanpltrusted | boolean |
lanplcallfoid | oid |
lancompiler | text |
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
-------------+---------+--------------+---------------+-------------
internal | f | f | 0 | n/a
C | f | f | 0 | /bin/cc
sql | f | f | 0 | postgres
目前,一種過程語言創建之后它的定義就不能再更改.
例子
下面兩條順序執行的命令將注冊一門新的過程語言及其關聯的調用句柄.
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '$libdir/plsample'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
兼容性 SQL92
CREATE LANGUAGE是 PostgreSQL 擴展.
歷史
CREATE LANGUAGE命令第一次出現在 PostgreSQL 6.3.
又見
createlang, CREATE FUNCTION , droplang, DROP LANGUAGE, PostgreSQL 程序員手冊
--------------------------------------------------------------------------------
CREATE OPERATOR
CREATE OPERATOR
Name
CREATE OPERATOR -- 定義一個新的操作符
Synopsis
CREATE OPERATOR name ( PROCEDURE = func_name
[, LEFTARG = lefttype
] [, RIGHTARG = righttype ]
[, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
[, RESTRICT = res_proc ] [, JOIN = join_proc ]
[, HASHES ] [, SORT1 = left_sort_op ] [, SORT2 = right_sort_op ] )
輸入
name
要定義的操作符??捎玫淖址娤挛?。
func_name
用于實現該操作符的函數。
lefttype
如果存在的話,操作符左手邊的參數類型. 如果是左目操作符,這個參數可以省略。
righttype
如果存在的話,操作符右手邊的參數類型. 如果是右目操作符,這個參數可以省略。
com_op
該操作符對應的交換(commutator)操作符。
neg_op
對應的負操作符。
res_proc
此操作符約束選擇性計算函數。
join_proc
此操作符連接選擇性計算函數。
HASHES
表明此操作符支持哈希(散列)連接。
left_sort_op
如果此操作符支持融合連接(join),此操作符的左手邊數據的排序操作符。
right_sort_op
如果此操作符支持融合連接(join),此操作符的右手邊數據的排序操作符。
輸出
CREATE
成功創建操作符后的返回信息.
描述
CREATE OPERATOR定義一個新的操作符, name. 定義該操作符的用戶成為其所有者.
操作符 name 是一個最多NAMEDATALEN-1 長的(缺省為 31 個)下列字符組成的字串:
+ - * / < > = ~ ! @ # % ^ & | ` ? $
你選擇名字的時候有幾個限制:
"$" 和 ":" 不能定義為單字符操作符, 但是它們可以是一個多字符操作符的名稱的一部分.
"--" 和 "/*" 不能在操作符名字的任何地方出現, 因為它們會被認為是一個注釋的開始.
一個多字符的操作符名字不能以 "+" 或 "-" 結尾, 除非該名字還包含至少下面字符之一:
~ ! @ # % ^ & | ` ? $
例如, @- 是一個允許的操作符名, 但 *- 不是. 這個限制允許 PostgreSQL 分析 SQL-有問題的查詢而不要求在符號之間有空白.
注意: 當使用非 SQL-標準操作符名時, 你通常將需要用空白把聯接的操作符分離開以避免含混.例如,如果你定義了一個左目操作符,名為 "@",你不能寫 X*@Y ;你必須寫成 X* @Y 以保證 PostgreSQL 把它讀做兩個操作符而不是一個.
操作符 "!=" 在輸入時映射成 "<>", 因此這兩個名稱總是相等的.
至少需要定義一個 LEFTARG 或 RIGHTARG. 對于雙目操作符來說,兩者都需要定義. 對右目操作符來說,只需要定義 LEFTARG, 而對于左目操作符來說,只需要定義 RIGHTARG.
同樣, func_name 過程必須已經用 CREATE FUNCTION 定義過, 而且必須定義為接受正確數量的指定類型參數(一個或是兩個).
如果存在換向操作符則必須指明,這樣 PostgreSQL 可以按它的意愿轉換操作符的方向.例如,操作符面積小于, <<<, 很有可能有一個轉換操作符:面積大于操作符, >>>. 因此,查詢優化器可以自由的將下面查詢從:
box '((0,0), (1,1))' >>> MYBOXES.description
轉換到
MYBOXES.description <<< box '((0,0), (1,1))'
這就允許執行代碼總是使用后面的形式而某種程度上簡化了查詢優化器.
類似地,如果存在負號操作符則也應該聲明。 假設一個操作符,面積相等, ===,存在,同樣有一個面積不等操作符, !==. 負號操作符允許查詢優化器將
NOT MYBOXES.description === box '((0,0), (1,1))'
簡化成
MYBOXES.description !== box '((0,0), (1,1))'
如果提供了一個交換操作符名稱, PostgreSQL 將在表中查找它.如果找到,而且其本身沒有一個交換符,那么交換符表將被更新,以當前(最新)創建的操作符作為它的交換符.這一點一樣適用于負號操作符. 這就允許定義兩個互為交換符或負號符的操作符.第一個操作符應該定義為沒有交換符或負號符(as appropriate).當定義第二個操作符時,將第一個符號作為交換符或負號符.第一個將因上述的副作用一樣被更新(而獲得交換符 或負號符).(對于PostgreSQL 6.5, 把兩個操作符指向對方同樣也行。)
HASHES,SORT1 和 SORT2 選項將為查詢優化器進行連接查詢時提供支持. PostgreSQL 能夠總是用反復替換來計算一個連接(也就是說,處理這樣的子句,該子句有兩個元組變量,這兩個變量被一個操作符分開,這個操作符返回一個boolean量) [WONG76]. 另外, PostgreSQL 可以延著 [SHAP86]實現一個散列-連接算法(hash-join algorithm);但是,我們必須知道這個策略是否可行.目前的散列-連接算法只是對代表相等測試的操作符有效;而且,數據類型的相等必須意味著類型的表現是按位相等的。(例如,一個包含未用的位的數據類型,這些位對相等測試沒有影響,但卻不能用于哈希連接。)HASHES 標記告訴優化器,對這個操作符可以安全地使用哈希連接。
類似的,兩目排序操作符告訴查詢優化器一個融合-排序 (merge-sort)是否是一個可用的連接策略,并且告訴優化器使用哪個操作符來對這兩個操 作數表排序.排序操作符應該只提供給相等操作符, 并且它們應該對應用于相應的左邊和右邊數據類型的小于操作符。
如果發現有其他聯合策略可用, PostgreSQL 將更改優化器和運行時系統以利用這些策略,并且在定義一個操作符時將需要更多的聲明.幸運的是,研究 團隊不經常發明新的聯合策略, 而且增加用戶定義聯合策略的方法看來與其實現的復雜性相比是不值得的。
RESTRICT 和 JOIN 選項幫助優化器計算結果的尺寸大?。绻裣旅娴恼Z句:
MYBOXES.description <<< box '((0,0),(1,1))'
在判斷條件中出現,那么 PostgreSQL 將不得不估計 MYBOXES 中滿足該子句的記錄數量的范圍的大?。?函數 res_proc 必需是一個注冊過的函數(也就是說它已經用 CREATE FUNCTION定義過了),它接受一個正確數據的數據類型作為參數,返回一個浮點數.查詢優化器只是簡單的調 用這個函數,將參數 ((0,0),(1,1)) 傳入并且把結果乘以關系(表)尺寸以獲得所需要的記錄的數值。
類似的,當操作符的兩個操作數都包含記錄變量時, 優化器必須計算聯合結果的尺寸. 函數 join_proc 將返回另一個浮點數,這個數就是將兩個表相關 的記錄相乘,計算出預期結果的尺寸.
函數
my_procedure_1 (MYBOXES.description, box '((0,0), (1,1))')
和操作符
MYBOXES.description === box '((0,0), (1,1))'
之間的區別是 PostgreSQL 試圖優化操作符并且可以決定使用索引來縮小相關操作符的搜索區間.但是,對函數將不會有任何優化的動作,而且是強制 執行.最后,函數可有任意個參數,而操作符限于一個或兩個.
注意
請參閱 PostgreSQL 用戶手冊 中操作符章節獲取更多信息.請使用 DROP OPERATOR 從數據庫中刪除用戶定義操作符.