输入 name 创建的规则名. event 事件是 SELECT, UPDATE,DELETE 或 INSERT 之一. object 对象是 table 或 table.column.(目前只有 table 形式实际上是实现了的. condition 任意 SQL 布尔条件表达式.条件表达式除了引用 new 和 old 之外不能引用任何表. query 组成 action 的查询可以是任何 SQL SELECT,INSERT, UPDATE,DELETE,或 NOTIFY 语句之一. 在 condition 和 action 里,特殊表名字 new 和 old 可以用于指向引用表 ( object) 里的数值 new 在 ON INSERT 和 ON UPDATE 规则里 可以指向被插入或更新的新行. old 在 ON UPDATE,和 ON DELETE 规则里可以指向现存的被更新,或者删除的行. 输出 CREATE 成功创建规则后的返回信息. 描述 PostgreSQL 规则系统 允许我们在从数据库或表中更新, 插入或删除东西时定义一个可选的动作来执行。目前,规则用于实现表视图。 规则的语意是在一个单独的记录正被访问,更新,插入或删除时, 将存在一个旧记录(用于检索,更新和删除)和一个新记录(用于更新和追加).这时给定事件类型和给定目标对象(表)的所有规则都将被检查, (顺序不定). 如果在 WHERE (如果有)子句里面所声明的 condition? 为真,那么 action 部分的规则就被执行. 如果声明了 INSTEAD,那么 action 就会代替原来的查询;否则,如果是 ON INSERT 那么它在原来的查询之后执行,如果是 ON UPDATE 或者 ON DELETE,那么它在原来的查询之前执行.在 condition 和 action 里面, 在旧记录里字段的数值和/或新记录里字段的数值被 old. attribute-name 和 new. attribute-name 代替. 规则的 action 部分可以由一条或者多条查询组成.要写多个查询,用圆括弧或者方括弧 把它们包围起来.这样的查询将以声明的顺序执行(只是我们不能保证对一个对象的多个规则的执行顺序). action 还可以是 NOTHING 表示没有动作.因此,一个 DO INSTEAD NOTHING 规则制止了原来的查询的运行(当条件为真时); DO NOTHING 规则是没有用的. 规则的 action 部分 执行的时候带有和触发动作的用户命令相同的命令和事务标识符. 规则和视图 目前,ON SELECT 规则必须是无条件的 INSTEAD 规则并且 必须有一个由一条 SELECT 查询组成的动作.因此,一条 ON SELECT 规则有效地把对象表转成视图,它的可见内容 是规则的 SELECT 查询返回的记录而不是存储在表中的内容(如果有的话).我们认为写一条 CREATE VIEW 命令比创建一个表然后定义一条 ON SELECT 规则在上面的风格要好. CREATE VIEW 创建一个虚拟表(没有下层的存储) 以及相关的 ON SELECT 规则.系统不允许对视图进行更新,因为它知道在视图上没有真正的表.你可以创建一个可以更新的视图的幻觉, 方法是在视图上定义 ON INSERT,ON UPDATE,和 ON DELETE 规则 (或者满足你需要的任何上述规则的子集),用合适的对其它表的更新替换 在视图上更新的动作. 如果你想在视图更新上使用条件规则,那么这里就有一个补充∶ 对你希望在视图上允许的每个动作,你都必须有一个无条件的 INSTEAD 规则.如果规则是有条件的,或者它不是 INSTEAD, 那么系统仍将拒绝执行更新动作的企图,因为它认为它最终会在某种 程度上在虚拟表上执行动作.如果你想处理条件规则上的所由有用的情况,那也可以;只需要增加一个无条件的 DO INSTEAD NOTHING 规则确保系统明白它将决不会被调用来更新虚拟表就可以了.然后把条件规则做成非 INSTEAD; 在这种情况下,如果它们被触发,那么它们就增加到缺省的 INSTEAD NOTHING 动作中.
注意 为了在表上定义规则,你必须有规则定义权限. 用 GRANT 和 REVOKE 修改权限. 有一件很重要的事情是要避免循环规则. 比如,尽管下面两条规则定义都是 PostgreSQL 可以接受的, select 命令会导致 PostgreSQL 报告 一条错误信息,因为该查询循环了太多次: CREATE RULE bad_rule_combination_1 AS ON SELECT TO emp DO INSTEAD SELECT * FROM toyemp; CREATE RULE bad_rule_combination_2 AS ON SELECT TO toyemp DO INSTEAD SELECT * FROM emp; 下面这个对 EMP 的查询企图将导致 PostgreSQL 产生一个错误信息, 因为该查询循环了太多次: SELECT * FROM emp; 目前,如果一个规则包含一个 NOTIFY 查询,那么该 NOTIFY 将被 无条件执行 --- 也就是说,如果规则不施加到任何行上头,该 NOTIFY 也会被发出.比如,在 CREATE RULE notify_me AS ON UPDATE TO mytable DO NOTIFY mytable; UPDATE mytable SET name = 'foo' WHERE id = 42; 里,一个 NOTIFY 事件将在 UPDATE 的时候发出,不管是否有某行的 id = 42.这是一个实现的限制,将来的版本应该修补这个毛病. 兼容性 SQL92 CREATE RULE语句是 PostgreSQL 语言的扩展. 在里没有CREATE RULE 语句.
CREATE TRIGGER Name CREATE TRIGGER -- 定义一个新的触发器 Synopsis CREATE TRIGGER name { BEFORE | AFTER } { event [OR ...] } ON table FOR EACH { ROW | STATEMENT } EXECUTE PROCEDURE func ( arguments ) 输入 name 赋予新触发器的名称. table 现有表名称. event INSERT,DELETE 或 UPDATE 之一. func 一个用户提供的函数. 输出 CREATE 如果触发器成功创建,返回此信息. 描述 CREATE TRIGGER将向现有数据库中增加一个新的触发器. 触发器将与表 table 相联并且将执行声明的函数 func. 触发器可以声明为在对记录进行操作之前 在检查约束之前和 INSERT,UPDATE 或 DELETE 执行前)或之后(在检 查约束之后和完成 INSERT, UPDATE 或 DELETE 操作)触发. 如果触发器在事件之前,触发器可能略过当前记录的操作或改变被插入的(当前)记录(只对 INSERT 和 UPDATE 操作有效). 如果触发器在事件之后,所有更改,包括最后的插入,更新或删除对触发器都是"可见"的. SELECT并不更改任何行,因此你不能创建 SELECT 触发器.这种场合下规则和视图更合适些. 请参考 PostgreSQL 程序员手册中SPI 和触发器章节获取更多信息. 注意 CREATE TRIGGER是 PostgreSQL 语言扩展. 只有表所有者可以就此表创建一个触发器. 在当前的版本,STATEMENT 触发器还没有实现. 请参考 DROP TRIGGER 获取如何删除触发器的信息. 用法 在插入或更新表 films 之前检查一下声明的分销商代码是否存在于 distributors 表中: CREATE TRIGGER if_dist_exists BEFORE INSERT OR UPDATE ON films FOR EACH ROW EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');
在删除或更新一个分销商的内容之前, 将所有记录移到表 films 中: CREATE TRIGGER if_film_exists BEFORE DELETE OR UPDATE ON distributors FOR EACH ROW EXECUTE PROCEDURE check_foreign_key (1, 'CASCADE', 'did', 'films', 'did'); 兼容性 SQL92 在 里没有 CREATE TRIGGER语句. 上面第二个例子可以使用一个 FOREIGN KEY 约束实现: CREATE TABLE distributors ( did DECIMAL(3), name VARCHAR(40), CONSTRAINT if_film_exists FOREIGN KEY(did) REFERENCES films ON UPDATE CASCADE ON DELETE CASCADE );
DELETE DELETE Name DELETE -- 删除一个表中的行 Synopsis DELETE FROM [ ONLY ] table [ WHERE condition ]
输入 table 一个现存表的名字 condition 这是一个 SQL 选择查询,它返回要被删除的行. 请参考 SELECT 语句获取关于 WHERE 子句的更多信息. 输出 DELETE count 如果行被成功的删除返回此信息. count 是要被删除的行数. 如果 count 为 0, 没有行被删除. 描述 DELETE从指明的表里删除满足 WHERE condition (条件)的行. 如果 condition (WHERE 子句)不存在, 效果是删除表中所有行.结果是一个有效的空表. 小技巧: TRUNCATE 是一个 PostgreSQL 扩展, 它提供一个更快的从表中删除所有行的机制。 缺省时DELETE将删除所声明的表和所有它的子表的记录. 如果你希望只更新提到的表,你应该使用OLNY子句. 要对表进行修改,你必须有写权限,同样也必须有读表的权限,这样才能对符合 condition(条件) 的值进行读取操作. 用法 删除所有电影(films)但不删除音乐(musicals): DELETE FROM films WHERE kind <> 'Musical'; SELECT * FROM films;
code | title | did | date_prod | kind | len -------+---------------------------+-----+------------+---------+------- UA501 | West Side Story | 105 | 1961-01-03 | Musical | 02:32 TC901 | The King and I | 109 | 1956-08-11 | Musical | 02:13 WD101 | Bed Knobs and Broomsticks | 111 | | Musical | 01:57 (3 rows) 清空表 films: DELETE FROM films; SELECT * FROM films;
code | title | did | date_prod | kind | len ------+-------+-----+-----------+------+----- (0 rows) 兼容性 SQL92 允许定位的 DELETE (删除)语句: DELETE FROM table WHERE CURRENT OF cursor 这里 cursor 表示一个打开的游标. PostgreSQL 里交互式游标是只读的.
DROP AGGREGATE DROP AGGREGATE Name DROP AGGREGATE -- 删除一个用户定义的聚集函数 Synopsis DROP AGGREGATE name type 输入 name 现存的聚集函数名。 type 现存的聚集函数的输入数据类型,或者 * -- 如果这个聚集函数接受任意输入类型.(请参考 PostgreSQL 用户手册 获取关于数据类型的更多信息)。 输出 DROP 命令成功的返回信息. ERROR: RemoveAggregate: aggregate 'name' for type type does not exist 如果声明的函数在数据库中不存在,返回此信息. 描述 DROP AGGREGATE将删除对一个现存聚集函数的所有索引. 执行这条命令的用户必须是该聚集函数的所有者. 注意 使用 CREATE AGGREGATE语句创建一个聚集函数。 用法 将类型 int4的聚集函数 myavg 删除: DROP AGGREGATE myavg(int4); 兼容性 SQL92 在 中没有 DROP AGGREGATE语句. 该语句是一个 PostgreSQL 语言的扩展.
DROP DATABASE Name DROP DATABASE -- 删除一个数据库. Synopsis DROP DATABASE name 输入 name 要被删除的现有数据库名. 输出 DROP DATABASE 如果命令成功执行,返回此命令. DROP DATABASE: cannot be executed on the currently open database 你不能和准备删除的数据库建立联接.你需要和 template1 或者任何其它的数据库相连来运行这些命令. DROP DATABASE: cannot be executed on the currently open database 执行这条命令之前你必须先结束正在处理的事务。 描述 DROP DATABASE删除一个现存数据库的目录入口并且删除包含数据的目录.只有数据库所有者能够执行这条命令(通常也是数据库创建者). DROP DATABASE不能撤销,小心使用. 注意 这条命令在和目标数据库联接时不能执行. 通常更好的做法是用 dropdb脚本代替,该脚本是此命令的一个封装。 , 请参考 CREATE DATABASE语句获取如何创建数据库的信息. 兼容性 SQL92
DROP FUNCTION Name DROP FUNCTION -- 删除一个用户定义的函数 Synopsis DROP FUNCTION name ( [ type [, ...] ] ) 输入 name 现存的函数名称. type 函数参数的类型. 输出 DROP 命令成功执行的返回信息. NOTICE RemoveFunction: Function "name" ("types") does not exist 如果当前数据库里不存在所声明的函数,返回此信息. 描述 DROP FUNCTION 将删除一个现存的函数的引用.要执行这条命令,用户必须是函数的所有者. 必须声明函数的输入参数类型,因为几个不同的函数可能会有同样的名字 和不同的参数列表. 注意 请参考 CREATE FUNCTION 获取创建聚集函数的信息. 对依赖于该函数的类型, 操作符访问方式或者触发器是否事先被删除不做任何校验. 用法 这条命令删除平方根函数: DROP FUNCTION sqrt(int4); 兼容性 SQL92 DROP FUNCTION是 PostgreSQL 语言的扩展. SQL/PSM SQL/PSM 是一个为实现函数扩展能力而提出的标准. SQL/PSM DROP FUNCTION 语句有下面的语法: DROP [ SPECIFIC ] FUNCTION name { RESTRICT | CASCADE }
DROP GROUP DROP GROUP Name DROP GROUP -- 删除一个用户组 Synopsis DROP GROUP name
输入 name 现存组名。 输出 DROP GROUP 成功删除组后返回的信息。 描述 DROP GROUP从数据库中删除指定的组。组中的用户不被删除。 组中的用户不被删除。 使用 CREATE GROUP增加新组,用 ALTER GROUP修改组的成员。 用法 删除一个组: DROP GROUP staff; 兼容性 SQL92
DROP INDEX Name DROP INDEX -- 删除一个索引 Synopsis DROP INDEX index_name [, ...] 输入 index_name 要删除的索引名. 输出 DROP 如果索引成功删除返回的信息. ERROR: index "index_name" does not exist 如果 index_name 不是这个数据库的索引,返回此信息. 描述 DROP INDEX从数据库中删除一个现存的索引. 要执行这个命令,你必须是索引的所有者. the index. 注意 DROP INDEX是PostgreSQL 语言扩展. 请参考 CREATE INDEX语句获取如何创建索引的信息. 用法 此命令将删除title_idx 索引: DROP INDEX title_idx; 兼容性 SQL92 定义用于访问纯关系型数据库的命令. 索引是一个与具体实现相关的特性,因而没有与具体实现相关的特性或定义在 语言里面.
DROP RULE DROP RULE Name DROP RULE -- 删除一个重写规则 Synopsis DROP RULE name [, ...] 输入 name 要删除的现存的规则. 输出 DROP 删除成功返回的信息. ERROR: Rule or view "name" not found 如果声明的规则不存在,返回此信息. 描述 DROP RULE从声明的 PostgreSQL规则系统里删除一个规则. PostgreSQL 将立即停止使用之并且将会把它从系统表中清理出去. 注意 DROP RULE语句是 PostgreSQL 语言的扩展. 请参考 CREATE RULE 获取如何创建规则的信息. 一旦一个规则被删除掉,该规则所写的历史记录信息将可能不存在. 用法 删除重写规则 newrule: DROP RULE newrule; 兼容性 SQL92 在 中没有DROP RULE.
DROP SEQUENCE DROP SEQUENCE Name DROP SEQUENCE -- 删除一个序列 Synopsis DROP SEQUENCE name [, ...] 输入 name 序列名. 输出 DROP 序列成功删除后返回的信息. ERROR: sequence "name" does not exist 如果声明的序列不存在,返回此信息. 描述 DROP SEQUENCE从数据库中删除序列号生成器. 因为目前的序列实现是作为一个特殊的表,所以此语句就象 DROP TABLE 语句一样. 注意 DROP SEQUENCE语句是 Postgres 语言扩展. 请参考 CREATE SEQUENCE 语句获取如何创建一个序列的信息. 用法 从数据库中删除序列 serial: DROP SEQUENCE serial; 兼容性 SQL92 在里没有 DROP SEQUENCE.
DROP TRIGGER DROP TRIGGER Name DROP TRIGGER -- 删除一个触发器定义. Synopsis DROP TRIGGER name ON table
输入 name 现存的触发器名. table 表的名称. 输出 DROP 如果触发器成功的删除,返回此信息. ERROR: DropTrigger: there is no trigger name on relation "table" 如果声明的触发器不存在,返回此信息. 描述 DROP TRIGGER将删除所有对一个现存触发器的引用. 要执行这个命令,当前用户必须是触发器的所有者. 注意 DROP TRIGGER是 PostgreSQL 语言的扩展. 请参考 CREATE TRIGGER 获取如何创建触发器的信息. 用法 删除表films的if_dist_exists触发器: DROP TRIGGER if_dist_exists ON films; 兼容性 SQL92 在里没有DROP TRIGGER.
DROP TYPE DROP TYPE Name DROP TYPE -- 删除一个用户定义数据类型 Synopsis DROP TYPE typename [, ...] 输入 typename 现存的类型名. 输出 DROP 命令执行成功的返回信息. ERROR: RemoveType: type 'typename' does not exist 如果声明的类型没有找到,返回此信息. 描述 DROP TYPE将从系统表里删除用户的类型. 只有类型所有者可以删除类型. 注意 DROP TYPE 语句是 PostgreSQL 语言的扩展. 请参考 CREATE TYPE 获取如何创建类型的信息. 用户有责任删除任何使用了被删除类型的操作符,函数,聚集,访问模式, 子类型和表.不过,相关等数组数据类型(由 CREATE TYPE 自动创建)将自动删除. 如果删除了一个内建的类型,后端的行为将不可预测. 用法 删除 box 类型: DROP TYPE box; 兼容性 SQL92 SQL3 DROP TYPE是 SQL3 语句.
DROP USER DROP USER Name DROP USER -- 删除一个数据库用户帐号 Synopsis DROP USER name 输入 name 一个现存用户的名称. 输出 DROP USER 用户被成功删除的返回信息. ERROR: DROP USER: user "name" does not exist 如果用户名没有找到,返回此信息. DROP USER: user "name" owns database "name", cannot be removed 你必须先删除数据库或者改变其所有者。 描述 DROP USER从数据库中删除指定的用户。 它不删除数据库里此用户所有的表,视图或其他对象。 如果该用户拥有任何数据库,你会收到一个错误信息。 使用 CREATE USER增加新用户,用 ALTER USER修改用户属性。 PostgreSQL 还有一个脚本 dropuser,这个脚本和这条命令功能相同(实际上,脚本里调用此命令),但是可以在命令行上运行。 用法 删除一个用户帐户: DROP USER jonathan; 兼容性 SQL92 在里没有DROP USER.
DROP VIEW DROP VIEW Name DROP VIEW -- 删除一个视图 Synopsis DROP VIEW name [, ...] 输入 name 现存视图名称. 输出 DROP 命令成功执行的返回. ERROR: view name does not exist 如果声明的视图在数据库中不存在,返回此信息. 描述 DROP VIEW从数据库中删除一个现存的视图. 执行这条命令必须是视图的所有者. 注意 请参考CREATE VIEW 获取关于如何创建视图的信息. 用法 下面命令将删除视图 kinds: DROP VIEW kinds; 兼容性 SQL92 为 DROP VIEW 声明了一些附加的功能: DROP VIEW view { RESTRICT | CASCADE } 输入 RESTRICT 确保只有不存在关联视图或完整性约束的视图可以被删除. CASCADE 任何引用的视图和完整性约束都将被删除. 注意 目前,要从 PostgreSQL 数据库中删除一个视图, 你必须明确地将其删除.
END Name END -- 提交当前的事务 Synopsis END [ WORK | TRANSACTION ] 输入 WORK TRANSACTION 可选关键字。没有作用。 输出 COMMIT 事务成功提交后的返回信息。 NOTICE: COMMIT: no transaction in progress 如果没有正在处理的事务,返回此信息。 描述 END是 PostgreSQL 而 -兼容的同义语句是 COMMIT. 注意 关键字 WORK 和 TRANSACTION 是多余的,可以省略。 使用 ROLLBACK退出一个事务。 用法 令所有改变生效: END WORK; 兼容性 SQL92 END是 PostgreSQL 的扩展,提供与 COMMIT相同的功能。
GRANT Name GRANT -- 定义访问权限 Synopsis GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } ON [ TABLE ] objectname [, ...] TO { username | GROUP groupname | PUBLIC } [, ...] 描述 GRANT命令将某对象(表,视图,序列) 上的特定权限给予一个用户或者多个用户或者一组用户.这些权限将增加到那些已经赋予的权限上,如果存在这些权限的话. 键字 PUBLIC 表示该权限要赋予所有用户, 包括那些以后可能创建的用户.PUBLIC 可以看做是一个隐含定义好的组,它总是包括所有用户.请注意,任何特定的用户都将拥有直接赋予他/她的权限,加上 他/她所处的任何组,以及再加上赋予 PUBLIC 的权限的总和. 在创建完对象之后,除了对象的创建者之外, 其它用户没有任何访问该对象的权限,除非创建者赋予某些权限.对对象的创建者而言,没有什么权限需要赋予,因为创建者自动持有所有权限.(不过,创建者出于安全考虑可以选择废弃一些他自己的权限.请注意赋予和废止权限的能力是创建者与生具来的,并且不会丢失.删除对象的权利也是创建者固有的,并且不能赋予或 撤销.) 可能的权限有∶ SELECT 允许对声明的表,试图,或者序列 SELECT 仁义字段.还允许做 COPY 的源. INSERT 允许向声明的表 INSERT 一个新行. 同时还允许做 COPY 的目标. UPDATE 允许对声明的表中任意字段做 UPDATE . SELECT ... FOR UPDATE 也要求这个权限 (除了 SELECT 权限之外).比如, 这个权限允许使用nextval, currval 和 setval. DELETE 允许从声明的表中 DELETE 行. RULE 允许在该表/视图上创建规则.(参阅 CREATE RULE 语句.) REFERENCES 要在一个表上创建一个外键约束,你必须在带参考健字的表上 拥有这个权限. TRIGGER 允许在声明表上创建触发器.(参阅 CREATE TRIGGER 语句.) ALL PRIVILEGES 把上面所有权限都一次赋予.PRIVILEGES 关键字在 PostgreSQL 里是可选的, 但是严格的 SQL 要求有这个关键字. 其它命令要求的权限都在相应的命令的参考页上列出. 注意 我们要注意数据库 superusers 可以访问所有对象, 而不会受对象的权限设置影响.这个特点类似 Unix 系统的 root 的权限.和 root 一样,除了必要的情况,总是以超级用户 身分进行操作是不明智的做法. 目前,要在 PostgreSQL 里只对某几列 赋予权限,你必须创建一个拥有那几行的视图然后给那个视图赋予权限. 使用 psql的 /z 命令 获取在现有对象上的与权限有关的信息. Database = lusitania +------------------+---------------------------------------------+ | Relation | Grant/Revoke Permissions | +------------------+---------------------------------------------+ | mytable | {"=rw","miriam=arwdRxt","group todos=rw"} | +------------------+---------------------------------------------+ Legend: uname=arwR -- privileges granted to a user group gname=arwR -- privileges granted to a group =arwR -- privileges granted to PUBLIC
r -- SELECT ("read") w -- UPDATE ("write") a -- INSERT ("append") d -- DELETE R -- RULE x -- REFERENCES t -- TRIGGER arwdRxt -- ALL PRIVILEGES 用 REVOKE 命令删除访问权限. 例子 把表 films 的插入权限赋予所有用户∶ GRANT INSERT ON films TO PUBLIC; 赋予用户manuel对视图kinds的所有权限∶ GRANT ALL PRIVILEGES ON kinds TO manuel; 兼容性 SQL92 在 ALL PRIVILEGES 里的 PRIVILEGES 关键字是必须的.SQL 不支持在一条命令里 对多个表设置权限. 的 GRANT 语法允许在一个表里 为独立的字段设置权限,并且允许设置一个权限用来给其它人赋予同样的权限∶ GRANT privilege [, ...] ON object [ ( column [, ...] ) ] [, ...] TO { PUBLIC | username [, ...] } [ WITH GRANT OPTION ] SQL 允许对其它类型的对象赋予 USAGE 权限∶CHARACTER SET,COLLATION,TRANSLATION,DOMAIN. TRIGGER 权限是 SQL99 引入的.RULE 权限是 PostgreSQL 扩展. 又见 REVOKE