亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜索
前言 何為PostgreSQL? PostgreSQL簡史 格式約定 更多信息 臭蟲匯報指導(dǎo) I. 教程 章1. 從頭開始 1.1. 安裝 1.2. 體系基本概念 1.3. 創(chuàng)建一個數(shù)據(jù)庫 1.4. 訪問數(shù)據(jù)庫 章2. SQL語言 2.1. 介紹 2.2. 概念 2.3. 創(chuàng)建新表 2.4. 向表中添加行 2.5. 查詢一個表 2.6. 表間鏈接 2.7. 聚集函數(shù) 2.8. 更新 2.9. 刪除 章3. 高級特性 3.1. 介紹 3.2. 視圖 3.3. 外鍵 3.4. 事務(wù) 3.5. 窗口函數(shù) 3.6. 繼承 3.7. 結(jié)論 II. SQL語言 章4. SQL語法 4.1. 詞法結(jié)構(gòu) 4.2. 值表達(dá)式 4.3. 調(diào)用函數(shù) 章5. 數(shù)據(jù)定義 5.1. 表的基本概念 5.2. 缺省值 5.3. 約束 5.4. 系統(tǒng)字段 5.5. 修改表 5.6. 權(quán)限 5.7. 模式 5.8. 繼承 5.9. 分區(qū) 5.10. 其它數(shù)據(jù)庫對象 5.11. 依賴性跟蹤 章 6. 數(shù)據(jù)操作 6.1. 插入數(shù)據(jù) 6.2. 更新數(shù)據(jù) 6.3. 刪除數(shù)據(jù) 章7. 查詢 7.1. 概述 7.2. 表表達(dá)式 7.3. 選擇列表 7.4. 組合查詢 7.5. 行排序 7.6. LIMIT和OFFSET 7.7. VALUES列表 7.8. WITH的查詢(公用表表達(dá)式) 章8. 數(shù)據(jù)類型 8.1. 數(shù)值類型 8.2. 貨幣類型 8.3. 字符類型 8.4. 二進制數(shù)據(jù)類型 8.5. 日期/時間類型 8.6. 布爾類型 8.7. 枚舉類型 8.8. 幾何類型 8.9. 網(wǎng)絡(luò)地址類型 8.10. 位串類型 8.11. 文本搜索類型 8.12. UUID類型 8.13. XML類型 8.14. 數(shù)組 8.15. 復(fù)合類型 8.16. 對象標(biāo)識符類型 8.17. 偽類型 章 9. 函數(shù)和操作符 9.1. 邏輯操作符 9.2. 比較操作符 9.3. 數(shù)學(xué)函數(shù)和操作符 9.4. 字符串函數(shù)和操作符 9.5. 二進制字符串函數(shù)和操作符 9.6. 位串函數(shù)和操作符 9.7. 模式匹配 9.8. 數(shù)據(jù)類型格式化函數(shù) 9.9. 時間/日期函數(shù)和操作符 9.10. 支持枚舉函數(shù) 9.11. 幾何函數(shù)和操作符 9.12. 網(wǎng)絡(luò)地址函數(shù)和操作符 9.13. 文本檢索函數(shù)和操作符 9.14. XML函數(shù) 9.15. 序列操作函數(shù) 9.16. 條件表達(dá)式 9.17. 數(shù)組函數(shù)和操作符 9.18. 聚合函數(shù) 9.19. 窗口函數(shù) 9.20. 子查詢表達(dá)式 9.21. 行和數(shù)組比較 9.22. 返回集合的函數(shù) 9.23. 系統(tǒng)信息函數(shù) 9.24. 系統(tǒng)管理函數(shù) 9.25. 觸發(fā)器函數(shù) 章10. 類型轉(zhuǎn)換 10.3. 函數(shù) 10.2. 操作符 10.1. 概述 10.4. 值存儲 10.5. UNION 章11. 索引 11.1. 介紹 11.2. 索引類型 11.3. 多字段索引 11.4. 索引和ORDER BY 11.5. 組合多個索引 11.6. 唯一索引 11.7. 表達(dá)式上的索引 11.8. 部分索引 11.9. 操作類和操作簇 11.10. 檢查索引的使用 章12. Full Text Search 12.1. Introduction 12.2. Tables and Indexes 12.3. Controlling Text Search 12.4. Additional Features 12.5. Parsers 12.6. Dictionaries 12.7. Configuration Example 12.8. Testing and Debugging Text Search 12.9. GiST and GIN Index Types 12.10. psql Support 12.11. Limitations 12.12. Migration from Pre-8.3 Text Search 章13. 并發(fā)控制 13.1. 介紹 13.2. 事務(wù)隔離 13.3. 明確鎖定 13.4. 應(yīng)用層數(shù)據(jù)完整性檢查 13.5. 鎖和索引 章14. 性能提升技巧 14.1. 使用EXPLAIN 14.2. 規(guī)劃器使用的統(tǒng)計信息 14.3. 用明確的JOIN語句控制規(guī)劃器 14.4. 向數(shù)據(jù)庫中添加記錄 14.5. 非持久性設(shè)置 III. 服務(wù)器管理 章15. 安裝指導(dǎo) 15.1. 簡版 15.2. 要求 15.3. 獲取源碼 15.4. 升級 15.5. 安裝過程 15.6. 安裝后的設(shè)置 15.7. 支持的平臺 15.8. 特殊平臺的要求 章16. Installation from Source Code on Windows 16.1. Building with Visual C++ or the Platform SDK 16.2. Building libpq with Visual C++ or Borland C++ 章17. 服務(wù)器安裝和操作 17.1. PostgreSQL用戶帳戶 17.2. 創(chuàng)建數(shù)據(jù)庫集群 17.3. 啟動數(shù)據(jù)庫服務(wù)器 17.4. 管理內(nèi)核資源 17.5. 關(guān)閉服務(wù) 17.6. 防止服務(wù)器欺騙 17.7. 加密選項 17.8. 用SSL進行安全的TCP/IP連接 17.9. Secure TCP/IP Connections with SSH Tunnels 章18. 服務(wù)器配置 18.1. 設(shè)置參數(shù) 18.2. 文件位置 18.3. 連接和認(rèn)證 18.4. 資源消耗 18.5. 預(yù)寫式日志 18.6. 查詢規(guī)劃 18.7. 錯誤報告和日志 18.8. 運行時統(tǒng)計 18.9. 自動清理 18.10. 客戶端連接缺省 18.12. 版本和平臺兼容性 18.11. 鎖管理 18.13. 預(yù)置選項 18.14. 自定義的選項 18.15. 開發(fā)人員選項 18.16. 短選項 章19. 用戶認(rèn)證 19.1. pg_hba.conf 文件 19.2. 用戶名映射 19.3. 認(rèn)證方法 19.4. 用戶認(rèn)證 章20. 數(shù)據(jù)庫角色和權(quán)限 20.1. 數(shù)據(jù)庫角色 20.2. 角色屬性 20.3. 權(quán)限 20.4. 角色成員 20.5. 函數(shù)和觸發(fā)器 章21. 管理數(shù)據(jù)庫 21.1. 概述 21.2. 創(chuàng)建一個數(shù)據(jù)庫 21.3. 臨時庫 21.4. 數(shù)據(jù)庫配置 21.5. 刪除數(shù)據(jù)庫 21.6. 表空間 章22. 本土化 22.1. 區(qū)域支持 22.2. 字符集支持 章23. 日常數(shù)據(jù)庫維護工作 23.1. Routine Vacuuming日常清理 23.2. 經(jīng)常重建索引 23.3. 日志文件維護 章24. 備份和恢復(fù) 24.1. SQL轉(zhuǎn)儲 24.2. 文件系統(tǒng)級別的備份 24.3. 在線備份以及即時恢復(fù)(PITR) 24.4. 版本間遷移 章25. 高可用性與負(fù)載均衡,復(fù)制 25.1. 不同解決方案的比較 25.2. 日志傳送備份服務(wù)器 25.3. 失效切換 25.4. 日志傳送的替代方法 25.5. 熱備 章26. 恢復(fù)配置 26.1. 歸檔恢復(fù)設(shè)置 26.2. 恢復(fù)目標(biāo)設(shè)置 26.3. 備服務(wù)器設(shè)置 章27. 監(jiān)控數(shù)據(jù)庫的活動 27.1. 標(biāo)準(zhǔn)Unix工具 27.2. 統(tǒng)計收集器 27.3. 查看鎖 27.4. 動態(tài)跟蹤 章28. 監(jiān)控磁盤使用情況 28.1. 判斷磁盤的使用量 28.2. 磁盤滿導(dǎo)致的失效 章29. 可靠性和預(yù)寫式日志 29.1. 可靠性 29.2. 預(yù)寫式日志(WAL) 29.3. 異步提交 29.4. WAL配置 29.5. WAL內(nèi)部 章30. Regression Tests 30.1. Running the Tests 30.2. Test Evaluation 30.3. Variant Comparison Files 30.4. Test Coverage Examination IV. 客戶端接口 章31. libpq-C庫 31.1. 數(shù)據(jù)庫聯(lián)接函數(shù) 31.2. 連接狀態(tài)函數(shù) 31.3. 命令執(zhí)行函數(shù) 31.4. 異步命令處理 31.5. 取消正在處理的查詢 31.6. 捷徑接口 31.7. 異步通知 31.8. 與COPY命令相關(guān)的函數(shù) 31.9. Control Functions 控制函數(shù) 31.10. 其他函數(shù) 31.11. 注意信息處理 31.12. 事件系統(tǒng) 31.13. 環(huán)境變量 31.14. 口令文件 31.15. 連接服務(wù)的文件 31.16. LDAP查找連接參數(shù) 31.17. SSL支持 31.18. 在多線程程序里的行為 31.19. 制作libpq程序 31.20. 例子程序 章32. 大對象 32.1. 介紹 32.2. 實現(xiàn)特點 32.3. 客戶端接口 32.4. 服務(wù)器端函數(shù) 32.5. 例子程序 章33. ECPG - Embedded SQL in C 33.1. The Concept 33.2. Connecting to the Database Server 33.3. Closing a Connection 33.4. Running SQL Commands 33.5. Choosing a Connection 33.6. Using Host Variables 33.7. Dynamic SQL 33.8. pgtypes library 33.9. Using Descriptor Areas 33.10. Informix compatibility mode 33.11. Error Handling 33.12. Preprocessor directives 33.13. Processing Embedded SQL Programs 33.14. Library Functions 33.15. Internals 章34. 信息模式 34.1. 關(guān)于這個模式 34.2. 數(shù)據(jù)類型 34.3. information_schema_catalog_name 34.4. administrable_role_authorizations 34.5. applicable_roles 34.6. attributes 34.7. check_constraint_routine_usage 34.8. check_constraints 34.9. column_domain_usage 34.10. column_privileges 34.11. column_udt_usage 34.12. 字段 34.13. constraint_column_usage 34.14. constraint_table_usage 34.15. data_type_privileges 34.16. domain_constraints 34.18. domains 34.17. domain_udt_usage 34.19. element_types 34.20. enabled_roles 34.21. foreign_data_wrapper_options 34.22. foreign_data_wrappers 34.23. foreign_server_options 34.24. foreign_servers 34.25. key_column_usage 34.26. parameters 34.27. referential_constraints 34.28. role_column_grants 34.29. role_routine_grants 34.30. role_table_grants 34.31. role_usage_grants 34.32. routine_privileges 34.33. routines 34.34. schemata 34.35. sequences 34.36. sql_features 34.37. sql_implementation_info 34.38. sql_languages 34.39. sql_packages 34.40. sql_parts 34.41. sql_sizing 34.42. sql_sizing_profiles 34.43. table_constraints 34.44. table_privileges 34.45. tables 34.46. triggered_update_columns 34.47. 觸發(fā)器 34.48. usage_privileges 34.49. user_mapping_options 34.50. user_mappings 34.51. view_column_usage 34.52. view_routine_usage 34.53. view_table_usage 34.54. 視圖 V. 服務(wù)器端編程 章35. 擴展SQL 35.1. 擴展性是如何實現(xiàn)的 35.2. PostgreSQL類型系統(tǒng) 35.3. User-Defined Functions 35.4. Query Language (SQL) Functions 35.5. Function Overloading 35.6. Function Volatility Categories 35.7. Procedural Language Functions 35.8. Internal Functions 35.9. C-Language Functions 35.10. User-Defined Aggregates 35.11. User-Defined Types 35.12. User-Defined Operators 35.13. Operator Optimization Information 35.14. Interfacing Extensions To Indexes 35.15. 用C++擴展 章36. 觸發(fā)器 36.1. 觸發(fā)器行為概述 36.3. 用 C 寫觸發(fā)器 36.2. 數(shù)據(jù)改變的可視性 36.4. 一個完整的例子 章37. 規(guī)則系統(tǒng) 37.1. The Query Tree 37.2. 視圖和規(guī)則系統(tǒng) 37.3. 在INSERT,UPDATE和DELETE上的規(guī)則 37.4. 規(guī)則和權(quán)限 37.5. 規(guī)則和命令狀態(tài) 37.6. 規(guī)則與觸發(fā)器得比較 章38. Procedural Languages 38.1. Installing Procedural Languages 章39. PL/pgSQL - SQL過程語言 39.1. 概述 39.2. PL/pgSQL的結(jié)構(gòu) 39.3. 聲明 39.4. 表達(dá)式 39.5. 基本語句 39.6. 控制結(jié)構(gòu) 39.7. 游標(biāo) 39.8. 錯誤和消息 39.9. 觸發(fā)器過程 39.10. PL/pgSQL Under the Hood 39.11. 開發(fā)PL/pgSQL的一些提示 39.12. 從OraclePL/SQL 進行移植 章40. PL/Tcl - Tcl Procedural Language 40.1. Overview 40.2. PL/Tcl Functions and Arguments 40.3. Data Values in PL/Tcl 40.4. Global Data in PL/Tcl 40.5. Database Access from PL/Tcl 40.6. Trigger Procedures in PL/Tcl 40.7. Modules and the unknown command 40.8. Tcl Procedure Names 章41. PL/Perl - Perl Procedural Language 41.1. PL/Perl Functions and Arguments 41.2. Data Values in PL/Perl 41.3. Built-in Functions 41.4. Global Values in PL/Perl 41.6. PL/Perl Triggers 41.5. Trusted and Untrusted PL/Perl 41.7. PL/Perl Under the Hood 章42. PL/Python - Python Procedural Language 42.1. Python 2 vs. Python 3 42.2. PL/Python Functions 42.3. Data Values 42.4. Sharing Data 42.5. Anonymous Code Blocks 42.6. Trigger Functions 42.7. Database Access 42.8. Utility Functions 42.9. Environment Variables 章43. Server Programming Interface 43.1. Interface Functions Spi-spi-connect Spi-spi-finish Spi-spi-push Spi-spi-pop Spi-spi-execute Spi-spi-exec Spi-spi-execute-with-args Spi-spi-prepare Spi-spi-prepare-cursor Spi-spi-prepare-params Spi-spi-getargcount Spi-spi-getargtypeid Spi-spi-is-cursor-plan Spi-spi-execute-plan Spi-spi-execute-plan-with-paramlist Spi-spi-execp Spi-spi-cursor-open Spi-spi-cursor-open-with-args Spi-spi-cursor-open-with-paramlist Spi-spi-cursor-find Spi-spi-cursor-fetch Spi-spi-cursor-move Spi-spi-scroll-cursor-fetch Spi-spi-scroll-cursor-move Spi-spi-cursor-close Spi-spi-saveplan 43.2. Interface Support Functions Spi-spi-fname Spi-spi-fnumber Spi-spi-getvalue Spi-spi-getbinval Spi-spi-gettype Spi-spi-gettypeid Spi-spi-getrelname Spi-spi-getnspname 43.3. Memory Management Spi-spi-palloc Spi-realloc Spi-spi-pfree Spi-spi-copytuple Spi-spi-returntuple Spi-spi-modifytuple Spi-spi-freetuple Spi-spi-freetupletable Spi-spi-freeplan 43.4. Visibility of Data Changes 43.5. Examples VI. 參考手冊 I. SQL命令 Sql-abort Sql-alteraggregate Sql-alterconversion Sql-alterdatabase Sql-alterdefaultprivileges Sql-alterdomain Sql-alterforeigndatawrapper Sql-alterfunction Sql-altergroup Sql-alterindex Sql-alterlanguage Sql-alterlargeobject Sql-alteroperator Sql-alteropclass Sql-alteropfamily Sql-alterrole Sql-alterschema Sql-altersequence Sql-alterserver Sql-altertable Sql-altertablespace Sql-altertsconfig Sql-altertsdictionary Sql-altertsparser Sql-altertstemplate Sql-altertrigger Sql-altertype Sql-alteruser Sql-alterusermapping Sql-alterview Sql-analyze Sql-begin Sql-checkpoint Sql-close Sql-cluster Sql-comment Sql-commit Sql-commit-prepared Sql-copy Sql-createaggregate Sql-createcast Sql-createconstraint Sql-createconversion Sql-createdatabase Sql-createdomain Sql-createforeigndatawrapper Sql-createfunction Sql-creategroup Sql-createindex Sql-createlanguage Sql-createoperator Sql-createopclass Sql-createopfamily Sql-createrole Sql-createrule Sql-createschema Sql-createsequence Sql-createserver Sql-createtable Sql-createtableas Sql-createtablespace Sql-createtsconfig Sql-createtsdictionary Sql-createtsparser Sql-createtstemplate Sql-createtrigger Sql-createtype Sql-createuser Sql-createusermapping Sql-createview Sql-deallocate Sql-declare Sql-delete Sql-discard Sql-do Sql-dropaggregate Sql-dropcast Sql-dropconversion Sql-dropdatabase Sql-dropdomain Sql-dropforeigndatawrapper Sql-dropfunction Sql-dropgroup Sql-dropindex Sql-droplanguage Sql-dropoperator Sql-dropopclass Sql-dropopfamily Sql-drop-owned Sql-droprole Sql-droprule Sql-dropschema Sql-dropsequence Sql-dropserver Sql-droptable Sql-droptablespace Sql-droptsconfig Sql-droptsdictionary Sql-droptsparser Sql-droptstemplate Sql-droptrigger Sql-droptype Sql-dropuser Sql-dropusermapping Sql-dropview Sql-end Sql-execute Sql-explain Sql-fetch Sql-grant Sql-insert Sql-listen Sql-load Sql-lock Sql-move Sql-notify Sql-prepare Sql-prepare-transaction Sql-reassign-owned Sql-reindex Sql-release-savepoint Sql-reset Sql-revoke Sql-rollback Sql-rollback-prepared Sql-rollback-to Sql-savepoint Sql-select Sql-selectinto Sql-set Sql-set-constraints Sql-set-role Sql-set-session-authorization Sql-set-transaction Sql-show Sql-start-transaction Sql-truncate Sql-unlisten Sql-update Sql-vacuum Sql-values II. 客戶端應(yīng)用程序 App-clusterdb App-createdb App-createlang App-createuser App-dropdb App-droplang App-dropuser App-ecpg App-pgconfig App-pgdump App-pg-dumpall App-pgrestore App-psql App-reindexdb App-vacuumdb III. PostgreSQL服務(wù)器應(yīng)用程序 App-initdb App-pgcontroldata App-pg-ctl App-pgresetxlog App-postgres App-postmaster VII. 內(nèi)部 章44. PostgreSQL內(nèi)部概覽 44.1. 查詢路徑 44.2. 連接是如何建立起來的 44.3. 分析器階段 44.4. ThePostgreSQL規(guī)則系統(tǒng) 44.5. 規(guī)劃器/優(yōu)化器 44.6. 執(zhí)行器 章45. 系統(tǒng)表 45.1. 概述 45.2. pg_aggregate 45.3. pg_am 45.4. pg_amop 45.5. pg_amproc 45.6. pg_attrdef 45.7. pg_attribute 45.8. pg_authid 45.9. pg_auth_members 45.10. pg_cast 45.11. pg_class 45.12. pg_constraint 45.13. pg_conversion 45.14. pg_database 45.15. pg_db_role_setting 45.16. pg_default_acl 45.17. pg_depend 45.18. pg_description 45.19. pg_enum 45.20. pg_foreign_data_wrapper 45.21. pg_foreign_server 45.22. pg_index 45.23. pg_inherits 45.24. pg_language 45.25. pg_largeobject 45.26. pg_largeobject_metadata 45.27. pg_namespace 45.28. pg_opclass 45.29. pg_operator 45.30. pg_opfamily 45.31. pg_pltemplate 45.32. pg_proc 45.33. pg_rewrite 45.34. pg_shdepend 45.35. pg_shdescription 45.36. pg_statistic 45.37. pg_tablespace 45.38. pg_trigger 45.39. pg_ts_config 45.40. pg_ts_config_map 45.41. pg_ts_dict 45.42. pg_ts_parser 45.43. pg_ts_template 45.44. pg_type 45.45. pg_user_mapping 45.46. System Views 45.47. pg_cursors 45.48. pg_group 45.49. pg_indexes 45.50. pg_locks 45.51. pg_prepared_statements 45.52. pg_prepared_xacts 45.53. pg_roles 45.54. pg_rules 45.55. pg_settings 45.56. pg_shadow 45.57. pg_stats 45.58. pg_tables 45.59. pg_timezone_abbrevs 45.60. pg_timezone_names 45.61. pg_user 45.62. pg_user_mappings 45.63. pg_views 章46. Frontend/Backend Protocol 46.1. Overview 46.2. Message Flow 46.3. Streaming Replication Protocol 46.4. Message Data Types 46.5. Message Formats 46.6. Error and Notice Message Fields 46.7. Summary of Changes since Protocol 2.0 47. PostgreSQL Coding Conventions 47.1. Formatting 47.2. Reporting Errors Within the Server 47.3. Error Message Style Guide 章48. Native Language Support 48.1. For the Translator 48.2. For the Programmer 章49. Writing A Procedural Language Handler 章50. Genetic Query Optimizer 50.1. Query Handling as a Complex Optimization Problem 50.2. Genetic Algorithms 50.3. Genetic Query Optimization (GEQO) in PostgreSQL 50.4. Further Reading 章51. 索引訪問方法接口定義 51.1. 索引的系統(tǒng)表記錄 51.2. 索引訪問方法函數(shù) 51.3. 索引掃描 51.4. 索引鎖的考量 51.5. 索引唯一性檢查 51.6. 索引開銷估計函數(shù) 章52. GiST Indexes 52.1. Introduction 52.2. Extensibility 52.3. Implementation 52.4. Examples 52.5. Crash Recovery 章53. GIN Indexes 53.1. Introduction 53.2. Extensibility 53.3. Implementation 53.4. GIN tips and tricks 53.5. Limitations 53.6. Examples 章54. 數(shù)據(jù)庫物理存儲 54.1. 數(shù)據(jù)庫文件布局 54.2. TOAST 54.3. 自由空間映射 54.4. 可見映射 54.5. 數(shù)據(jù)庫分頁文件 章55. BKI后端接口 55.1. BKI 文件格式 55.2. BKI命令 55.3. 系統(tǒng)初始化的BKI文件的結(jié)構(gòu) 55.4. 例子 章56. 規(guī)劃器如何使用統(tǒng)計信息 56.1. 行預(yù)期的例子 VIII. 附錄 A. PostgreSQL錯誤代碼 B. 日期/時間支持 B.1. 日期/時間輸入解析 B.2. 日期/時間關(guān)鍵字 B.3. 日期/時間配置文件 B.4. 日期單位的歷史 C. SQL關(guān)鍵字 D. SQL Conformance D.1. Supported Features D.2. Unsupported Features E. Release Notes Release-0-01 Release-0-02 Release-0-03 Release-1-0 Release-1-01 Release-1-02 Release-1-09 Release-6-0 Release-6-1 Release-6-1-1 Release-6-2 Release-6-2-1 Release-6-3 Release-6-3-1 Release-6-3-2 Release-6-4 Release-6-4-1 Release-6-4-2 Release-6-5 Release-6-5-1 Release-6-5-2 Release-6-5-3 Release-7-0 Release-7-0-1 Release-7-0-2 Release-7-0-3 Release-7-1 Release-7-1-1 Release-7-1-2 Release-7-1-3 Release-7-2 Release-7-2-1 Release-7-2-2 Release-7-2-3 Release-7-2-4 Release-7-2-5 Release-7-2-6 Release-7-2-7 Release-7-2-8 Release-7-3 Release-7-3-1 Release-7-3-10 Release-7-3-11 Release-7-3-12 Release-7-3-13 Release-7-3-14 Release-7-3-15 Release-7-3-16 Release-7-3-17 Release-7-3-18 Release-7-3-19 Release-7-3-2 Release-7-3-20 Release-7-3-21 Release-7-3-3 Release-7-3-4 Release-7-3-5 Release-7-3-6 Release-7-3-7 Release-7-3-8 Release-7-3-9 Release-7-4 Release-7-4-1 Release-7-4-10 Release-7-4-11 Release-7-4-12 Release-7-4-13 Release-7-4-14 Release-7-4-15 Release-7-4-16 Release-7-4-17 Release-7-4-18 Release-7-4-19 Release-7-4-2 Release-7-4-20 Release-7-4-21 Release-7-4-22 Release-7-4-23 Release-7-4-24 Release-7-4-25 Release-7-4-26 Release-7-4-27 Release-7-4-28 Release-7-4-29 Release-7-4-3 Release-7-4-30 Release-7-4-4 Release-7-4-5 Release-7-4-6 Release-7-4-7 Release-7-4-8 Release-7-4-9 Release-8-0 Release-8-0-1 Release-8-0-10 Release-8-0-11 Release-8-0-12 Release-8-0-13 Release-8-0-14 Release-8-0-15 Release-8-0-16 Release-8-0-17 Release-8-0-18 Release-8-0-19 Release-8-0-2 Release-8-0-20 Release-8-0-21 Release-8-0-22 Release-8-0-23 Release-8-0-24 Release-8-0-25 Release-8-0-26 Release-8-0-3 Release-8-0-4 Release-8-0-5 Release-8-0-6 Release-8-0-7 Release-8-0-8 Release-8-0-9 Release-8-1 Release-8-1-1 Release-8-1-10 Release-8-1-11 Release-8-1-12 Release-8-1-13 Release-8-1-14 Release-8-1-15 Release-8-1-16 Release-8-1-17 Release-8-1-18 Release-8-1-19 Release-8-1-2 Release-8-1-20 Release-8-1-21 Release-8-1-22 Release-8-1-23 Release-8-1-3 Release-8-1-4 Release-8-1-5 Release-8-1-6 Release-8-1-7 Release-8-1-8 Release-8-1-9 Release-8-2 Release-8-2-1 Release-8-2-10 Release-8-2-11 Release-8-2-12 Release-8-2-13 Release-8-2-14 Release-8-2-15 Release-8-2-16 Release-8-2-17 Release-8-2-18 Release-8-2-19 Release-8-2-2 Release-8-2-20 Release-8-2-21 Release-8-2-3 Release-8-2-4 Release-8-2-5 Release-8-2-6 Release-8-2-7 Release-8-2-8 Release-8-2-9 Release-8-3 Release-8-3-1 Release-8-3-10 Release-8-3-11 Release-8-3-12 Release-8-3-13 Release-8-3-14 Release-8-3-15 Release-8-3-2 Release-8-3-3 Release-8-3-4 Release-8-3-5 Release-8-3-6 Release-8-3-7 Release-8-3-8 Release-8-3-9 Release-8-4 Release-8-4-1 Release-8-4-2 Release-8-4-3 Release-8-4-4 Release-8-4-5 Release-8-4-6 Release-8-4-7 Release-8-4-8 Release-9-0 Release-9-0-1 Release-9-0-2 Release-9-0-3 Release-9-0-4 F. 額外提供的模塊 F.1. adminpack F.2. auto_explain F.3. btree_gin F.4. btree_gist F.5. chkpass F.6. citext F.7. cube F.8. dblink Contrib-dblink-connect Contrib-dblink-connect-u Contrib-dblink-disconnect Contrib-dblink Contrib-dblink-exec Contrib-dblink-open Contrib-dblink-fetch Contrib-dblink-close Contrib-dblink-get-connections Contrib-dblink-error-message Contrib-dblink-send-query Contrib-dblink-is-busy Contrib-dblink-get-notify Contrib-dblink-get-result Contrib-dblink-cancel-query Contrib-dblink-get-pkey Contrib-dblink-build-sql-insert Contrib-dblink-build-sql-delete Contrib-dblink-build-sql-update F.9. dict_int F.10. dict_xsyn F.11. earthdistance F.12. fuzzystrmatch F.13. hstore F.14. intagg F.15. intarray F.16. isn F.17. lo F.18. ltree F.19. oid2name F.20. pageinspect F.21. passwordcheck F.22. pg_archivecleanup F.23. pgbench F.24. pg_buffercache F.25. pgcrypto F.26. pg_freespacemap F.27. pgrowlocks F.28. pg_standby F.29. pg_stat_statements F.30. pgstattuple F.31. pg_trgm F.32. pg_upgrade F.33. seg F.34. spi F.35. sslinfo F.36. tablefunc F.37. test_parser F.38. tsearch2 F.39. unaccent F.40. uuid-ossp F.41. vacuumlo F.42. xml2 G. 外部項目 G.1. 客戶端接口 G.2. 過程語言 G.3. 擴展 H. The Source Code Repository H.1. Getting The Source Via Git I. 文檔 I.1. DocBook I.2. 工具集 I.3. 制作文檔 I.4. 文檔寫作 I.5. 風(fēng)格指導(dǎo) J. 首字母縮略詞 參考書目 Bookindex Index
文字

39.6. 控制結(jié)構(gòu)

控制結(jié)構(gòu)可能是PL/pgSQL中最有用的(以及最重要)的部分了。 利用PL/pgSQL的控制結(jié)構(gòu),你可以以非常靈活而且強大的方法操縱PostgreSQL的數(shù)據(jù)。

39.6.1. 從函數(shù)返回

有兩個命令可以用來從函數(shù)中返回數(shù)據(jù):RETURNRETURN NEXT。

39.6.1.1. RETURN

RETURN expression;

帶表達(dá)式的RETURN用于終止函數(shù)并把expression的值返回給調(diào)用者。 這種形式用于不返回集合的PL/pgSQL函數(shù)。

如果返回標(biāo)量類型,那么可以使用任何表達(dá)式。 表達(dá)式的類型將被自動轉(zhuǎn)換成函數(shù)的返回類型,就像在賦值中描述的那樣。 要返回一個復(fù)合(行)數(shù)值,你必須寫一個記錄或者行變量的expression。

如果你聲明函數(shù)帶輸出參數(shù),那么就只需要寫無表達(dá)式的RETURN。 那么輸出參數(shù)變量的當(dāng)前值將被返回。

如果你聲明函數(shù)返回void,那么一個RETURN語句可以用于提前退出函數(shù); 但是不要在RETURN后面寫一個表達(dá)式。

一個函數(shù)的返回值不能是未定義。 如果控制到達(dá)了函數(shù)最頂層的塊而沒有碰到一個RETURN語句,那么它就會發(fā)生一個錯誤。 不過,這個限制不適用于帶輸出參數(shù)的函數(shù)以及那些返回void的函數(shù)。 在這些例子里,如果頂層的塊結(jié)束,則自動執(zhí)行一個RETURN語句。

39.6.1.2. RETURN NEXTRETURN QUERY

RETURN NEXT expression;
RETURN QUERY query;
RETURN QUERY EXECUTE command-string [ USING expression [, ... ] ];

如果一個PL/pgSQL函數(shù)聲明為返回SETOFsometype,那么遵循的過程則略有不同。 在這種情況下,要返回的獨立項是在 RETURN NEXTRETURN QUERY命令里聲明的, 然后最后有一個不帶參數(shù)的RETURN命令用于告訴這個函數(shù)已經(jīng)完成執(zhí)行了。 RETURN NEXT可以用于標(biāo)量和復(fù)合數(shù)據(jù)類型;對于復(fù)合類型,將返回一個完整的結(jié)果"table"。 RETURN QUERY命令將一條查詢的結(jié)果追加到一個函數(shù)的結(jié)果集中。 RETURN NEXTRETURN QUERY RETURN QUERY appends the results of executing a query to the function's result set. RETURN NEXT and RETURN QUERY can be freely intermixed in a single set-returning function, in which case their results will be concatenated.

RETURN NEXTRETURN QUERY實際上不會從函數(shù)中返回,它們是將0或者多個行追加到函數(shù)的結(jié)果集中。 然后執(zhí)行繼續(xù)執(zhí)行PL/pgSQL函數(shù)里的下一條語句。 隨著后繼的RETURN NEXTRETURN QUERY命令的執(zhí)行,結(jié)果集就建立起來了。 最后一個RETURN應(yīng)該沒有參數(shù), 它導(dǎo)致控制退出該函數(shù)(或者你可以簡單地讓控制到達(dá)函數(shù)的結(jié)尾)。

RETURN QUERY has a variant RETURN QUERY EXECUTE, which specifies the query to be executed dynamically. Parameter expressions can be inserted into the computed query string via USING, in just the same way as in the EXECUTE command.

If you declared the function with output parameters, write just RETURN NEXT with no expression. On each execution, the current values of the output parameter variable(s) will be saved for eventual return as a row of the result. Note that you must declare the function as returning SETOF record when there are multiple output parameters, or SETOF sometype when there is just one output parameter of type sometype, in order to create a set-returning. function with output parameters. 如果你聲明函數(shù)帶有輸出參數(shù),那么就只需要寫不帶表達(dá)式的 RETURN NEXT 。 輸出參數(shù)的當(dāng)前值將被保存,用于最終返回。 請注意如果有多個輸出參數(shù), 比如聲明函數(shù)為返回 SETOF record 或者是在只有一個類型為 sometype 的輸出參數(shù)時聲明為 SETOF sometype , 這樣才能創(chuàng)建一個帶有輸出參數(shù)的返回集合的函數(shù)。

下面是一個使用RETURN NEXT的函數(shù)例子:

CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT);
INSERT INTO foo VALUES (1, 2, 'three');
INSERT INTO foo VALUES (4, 5, 'six');

CREATE OR REPLACE FUNCTION getAllFoo() RETURNS SETOF foo AS
$body$
DECLARE
    r foo%rowtype;
BEGIN
    FOR r IN SELECT * FROM foo
    WHERE fooid > 0
    LOOP
        -- can do some processing here
        RETURN NEXT r; -- return current row of SELECT
    END LOOP;
    RETURN;
END
$body$
LANGUAGE 'plpgsql' ;

SELECT * FROM getallfoo();

Note: 目前RETURN NEXTRETURN QUERY實現(xiàn)在從函數(shù)返回之前把整個結(jié)果集都保存起來,就像上面描述的那樣。 這意味著如果一個PL/pgSQL函數(shù)生成一個非常大的結(jié)果集,性能可能會很差: 數(shù)據(jù)將被寫到磁盤上以避免內(nèi)存耗盡,但是函數(shù)在完成整個結(jié)果集的生成之前不會退出。 將來的PL/pgSQL版本可能會允許用戶定義沒有這樣限制的返回集合的函數(shù)。 目前,數(shù)據(jù)開始向磁盤里寫的時刻是由配置變量work_mem控制的。 擁有足夠內(nèi)存的管理員如果想在內(nèi)存里存儲更大的結(jié)果集,則可以考慮把這個參數(shù)增大一些。

39.6.2. 條件

IFCASE語句讓你可以根據(jù)某種條件執(zhí)行命令。PL/pgSQL有三種形式的IF

  • IF ... THEN

  • IF ... THEN ... ELSE

  • IF ... THEN ... ELSIF ... THEN ... ELSE

以及兩種形式的CASE:

  • CASE ... WHEN ... THEN ... ELSE ... END CASE

  • CASE WHEN ... THEN ... ELSE ... END CASE

39.6.2.1. IF-THEN

IF boolean-expression THEN
    statements
END IF;

IF-THEN語句是IF的最簡單形式。 如果條件為真,在THENEND IF之間的語句將被執(zhí)行。 否則,將忽略它們。

例子:

IF v_user_id <> 0 THEN
    UPDATE users SET email = v_email WHERE user_id = v_user_id;
END IF;

39.6.2.2. IF-THEN-ELSE

IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

IF-THEN語句增加了add to,你可以聲明在條件為假的時候執(zhí)行的語句(包括條件為NULL的情況)。

例子:

IF parentid IS NULL OR parentid = ''
THEN
    RETURN fullname;
ELSE
    RETURN hp_true_filename(parentid) || '/' || fullname;
END IF;

IF v_count > 0 THEN
    INSERT INTO users_count (count) VALUES (v_count);
    RETURN 't';
ELSE
    RETURN 'f';
END IF;

39.6.2.3. IF-THEN-ELSIF

IF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
[ ELSIF boolean-expression THEN
    statements
    ...]]
[ ELSE
    statements ]
END IF;

有時不知兩個選擇。IF-THEN-ELSIF反過來提供了一個簡便的方法來檢查選擇條件。 IF判斷會陸續(xù)檢查,直到找到第一個為真的,然后執(zhí)行相關(guān)聲明,如此,直到END IF(不會檢測IF子查詢)。 如果沒有一個條件符合IF判斷,那么會接著執(zhí)行ELSE判斷。

例子:

IF number = 0 THEN
    result := 'zero';
ELSIF number > 0 THEN
    result := 'positive';
ELSIF number < 0 THEN
    result := 'negative';
ELSE
    -- hmm, the only other possibility is that number is null
    result := 'NULL';
END IF;

ELSIF關(guān)鍵字也可以寫成ELSEIF.

另一個可以實現(xiàn)該目的的方法是使用IF-THEN-ELSE聲明,如下:

IF demo_row.sex = 'm' THEN
    pretty_sex := 'man';
ELSE
    IF demo_row.sex = 'f' THEN
        pretty_sex := 'woman';
    END IF;
END IF;

然而,這個方法需要為每個IFEND IF,因此當(dāng)有很多選擇時,這種方法明顯比ELSIF繁瑣。

39.6.2.4. Simple CASE

CASE search-expression
    WHEN expression [, expression [ ... ]] THEN
      statements
  [ WHEN expression [, expression [ ... ]] THEN
      statements
    ... ]
  [ ELSE
      statements ]
END CASE;

The simple form of CASE provides conditional execution based on equality of operands. The search-expression is evaluated (once) and successively compared to each expression in the WHEN clauses. If a match is found, then the corresponding statements are executed, and then control passes to the next statement after END CASE. (Subsequent WHEN expressions are not evaluated.) If no match is found, the ELSE statements are executed; but if ELSE is not present, then a CASE_NOT_FOUND exception is raised.

例如:

CASE x
    WHEN 1, 2 THEN
        msg := 'one or two';
    ELSE
        msg := 'other value than one or two';
END CASE;

39.6.2.5. Searched CASE

CASE
    WHEN boolean-expression THEN
      statements
  [ WHEN boolean-expression THEN
      statements
    ... ]
  [ ELSE
      statements ]
END CASE;

The searched form of CASE provides conditional execution based on truth of Boolean expressions. Each WHEN clause's boolean-expression is evaluated in turn, until one is found that yields true. Then the corresponding statements are executed, and then control passes to the next statement after END CASE. (Subsequent WHEN expressions are not evaluated.) If no true result is found, the ELSE statements are executed; but if ELSE is not present, then a CASE_NOT_FOUND exception is raised.

Here is an example:

CASE
    WHEN x BETWEEN 0 AND 10 THEN
        msg := 'value is between zero and ten';
    WHEN x BETWEEN 11 AND 20 THEN
        msg := 'value is between eleven and twenty';
END CASE;

This form of CASE is entirely equivalent to IF-THEN-ELSIF, except for the rule that reaching an omitted ELSE clause results in an error rather than doing nothing.

39.6.3. 簡單循環(huán)

使用LOOP, EXIT,CONTINUE, WHILE,HE FOR語句, 可以控制PL/pgSQL函數(shù)重復(fù)一系列命令。

39.6.3.1. 循環(huán)

[ <<label>> ]
LOOP
    statements
END LOOP [ label ];

LOOP定義一個無條件的循環(huán),無限循環(huán),直到由EXITRETURN語句終止。 可選的label可以由EXITCONTINUE語句使用,用于在嵌套循環(huán)中聲明應(yīng)該應(yīng)用于哪一層循環(huán)。

39.6.3.2. 退出

EXIT [ label ] [ WHEN boolean-expression ];

如果沒有給出label,那么退出最內(nèi)層的循環(huán),然后執(zhí)行跟在END LOOP后面的語句。 如果給出label,那么它必須是當(dāng)前或者更高層的嵌套循環(huán)塊或者語句塊的標(biāo)簽。 然后該命名塊或者循環(huán)就會終止,而控制落到對應(yīng)循環(huán)/塊的END語句后面的語句上。

如果聲明了WHEN,循環(huán)退出只有在boolean-expression為真的時候才發(fā)生, 否則控制會落到EXIT后面的語句上。

EXIT可以用于在所有的循環(huán)類型中,它并不僅僅限制于在無條件循環(huán)中使用。

在和BEGIN塊一起使用的時候,EXIT把控制交給塊結(jié)束后的下一個語句。 需要注意的是,一個標(biāo)簽必須用于這個目的;一個沒有標(biāo)記的EXIT永遠(yuǎn)無法與BEGIN進行匹配。

例如:

LOOP
    -- some computations
    IF count > 0 THEN
        EXIT;  -- exit loop
    END IF;
END LOOP;

LOOP
    -- some computations
    EXIT WHEN count > 0;  -- same result as previous example
END LOOP;

<<ablock>>
BEGIN
    -- some computations
    IF stocks > 100000 THEN
        EXIT ablock;  -- causes exit from the BEGIN block
    END IF;
    -- computations here will be skipped when stocks > 100000
END;

39.6.3.3. CONTINUE

CONTINUE [ label ] [ WHEN boolean-expression ];

如果沒有給出label,那么就開始最內(nèi)層循環(huán)的下一次執(zhí)行。 也就是說,控制傳遞回給循環(huán)控制表達(dá)式(如果有),然后重新計算循環(huán)體。 如果出現(xiàn)了label,它聲明即將繼續(xù)執(zhí)行的循環(huán)的標(biāo)簽。

如果聲明了WHEN,那么循環(huán)的下一次執(zhí)行只有在boolean-expression為真的情況下才進行。 否則,控制傳遞給CONTINUE后面的語句。

CONTINUE可以用于所有類型的循環(huán);它并不僅僅限于無條件循環(huán)。

例如:

LOOP
    -- 一些計算
    EXIT WHEN count > 100;
    CONTINUE WHEN count < 50;
    -- 一些count數(shù)值在[50 .. 100]之間的計算

END LOOP;

39.6.3.4. WHILE

[ <<label>> ]
WHILE boolean-expression LOOP
    statements
END LOOP [ label ];

只要條件表達(dá)式(boolean-expression)為真,WHILE語句就會不停的在一系列語句上進行循環(huán), 條件是在每次進入循環(huán)體的時候檢查的。

例如:

WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP
    -- some computations here
END LOOP;

WHILE NOT done LOOP
    -- some computations here
END LOOP;

39.6.3.5. FOR (integer variant)

[ <<label>> ]
FOR name IN [ REVERSE ] expression .. expression [ BY expression ] LOOP
    statements
END LOOP [ label ];

這種形式的FOR對一定范圍的整數(shù)進行迭代的循環(huán)。 變量name會自動定義為integer類型并且只在循環(huán)里存在(任何該變量名的現(xiàn)存定義在此循環(huán)內(nèi)都將被忽略)。 給出范圍上下界的兩個表達(dá)式在進入循環(huán)的時候計算一次。 BY子句指定迭代步長(缺省為 1),但如果聲明了REVERSE步長將變?yōu)橄鄳?yīng)的負(fù)值。

一些整數(shù) FOR 循環(huán)的例子:

FOR i IN 1..10 LOOP
    -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;

FOR i IN REVERSE 10..1 LOOP
    -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop
END LOOP;

FOR i IN REVERSE 10..1 BY 2 LOOP
    -- i will take on the values 10,8,6,4,2 within the loop
END LOOP;

如果下界大于上界(或者是在REVERSE情況下是小于),那么循環(huán)體將完全不被執(zhí)行。 而且不會拋出任何錯誤。

If a label is attached to the FOR loop then the integer loop variable can be referenced with a qualified name, using that label.

39.6.4. 遍歷命令結(jié)果

使用不同類型的FOR循環(huán),你可以遍歷一個命令的結(jié)果并且對其進行相應(yīng)的操作。 語法是:

[ <<label>> ]
FOR target IN query LOOP
    statements
END LOOP [ label ];

target是一個記錄變量、行變量、逗號分隔的標(biāo)量變量列表 target被連續(xù)不斷被賦予所有來自query的行,并且循環(huán)體將為每行執(zhí)行一次。 下面是一個例子:

CREATE FUNCTION cs_refresh_mviews() RETURNS integer AS $$
DECLARE
    mviews RECORD;
BEGIN
    PERFORM cs_log('Refreshing materialized views...');

    FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP

        -- 現(xiàn)在"mviews"里有了一條來自 cs_materialized_views 的記錄 

        PERFORM cs_log('Refreshing materialized view '
                   || quote_ident(mviews.mv_name) || ' ...');
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(mviews.mv_name);
        EXECUTE 'INSERT INTO '
                   || quote_ident(mviews.mv_name) || ' ' 
                   || mviews.mv_query;
    END LOOP;

    PERFORM cs_log('Done refreshing materialized views.');
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

如果循環(huán)是用一個EXIT語句終止的,那么在循環(huán)之后你仍然可以訪問最后賦值的行

FOR語句中使用的這種query可以是任何返回行的SQL命令, 通常是SELECT,不過帶有RETURNING子句的INSERT, UPDATE,或DELETE也是可以的, 一些諸如EXPLAIN之類的命令也可以

PL/pgSQL variables are substituted into the query text, and the query plan is cached for possible re-use, as discussed in detail in Section 39.10.1 and Section 39.10.2. PL/pgSQL變量 正如在Section 39.10.1和Section 39.10.2中討論的那樣。

FOR-IN-EXECUTE語句是遍歷所有行的另外一種方法:

[ <<label>> ]
FOR target IN EXECUTE text_expression [ USING expression [, ... ] ] LOOP
    statements
END LOOP [ label ];

這個例子類似前面的形式,只不過源查詢語句聲明為了一個字符串表達(dá)式, 這樣它在每次進入FOR循環(huán)的時候都會重新計算和生成執(zhí)行計劃。 這樣就允許程序員在一個預(yù)先規(guī)劃好了的命令所獲得的速度和一個動態(tài)命令所獲得的靈活性 (就像一個簡單的EXECUTE語句那樣)之間進行選擇。 當(dāng)使用EXECUTE時,可以通過USING將參數(shù)值插入到動態(tài)命令中。

對于一個需要將結(jié)果迭代的查詢,另外一個聲明的方法是將它定義為游標(biāo)(cursor),可參閱Section 39.7.4。

39.6.5. Trapping Errors捕獲錯誤

缺省時,一個在PL/pgSQL函數(shù)里發(fā)生的錯誤退出函數(shù)的執(zhí)行, 并且實際上其周圍的事務(wù)也會退出。 你可以使用一個帶有EXCEPTION子句的BEGIN塊捕獲錯誤并且從中恢復(fù)。 其語法是正常的BEGIN塊語法的一個擴展:

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
EXCEPTION
    WHEN condition [ OR condition ... ] THEN
        handler_statements
    [ WHEN condition [ OR condition ... ] THEN
          handler_statements
      ... ]
END;

如果沒有發(fā)生錯誤,這種形式的塊只是簡單地執(zhí)行所有statements, 然后轉(zhuǎn)到下一個END之后的語句。 但是如果在statements內(nèi)部發(fā)生了一個錯誤,則對statements的進一步處理將廢棄, 然后轉(zhuǎn)到 EXCEPTION 列表。 系統(tǒng)搜索這個列表,尋找匹配錯誤的第一個condition。 如果找到匹配,則執(zhí)行對應(yīng)的handler_statements,然后轉(zhuǎn)到END之后的下一個語句。 如果沒有找到匹配,該錯誤就會廣播出去, 就好像根本沒有EXCEPTION子句一樣:該錯誤可以被一個包圍塊用EXCEPTION捕獲, 如果沒有包圍塊,則退出函數(shù)的處理。

condition的名字可以是 附錄A里顯示的任何名字。 一個范疇名匹配任意該范疇里的錯誤。 特殊的條件名OTHERS匹配除了QUERY_CANCELED之外的所有錯誤類型。 可以用名字捕獲QUERY_CANCELED,不過通常是不明智的。條件名是大小寫無關(guān)的。 同時也可以通過SQLSTATE來聲明一個錯誤條件,例如:

WHEN division_by_zero THEN ...
WHEN SQLSTATE '22012' THEN ...

如果在選中的handler_statements里發(fā)生了新錯誤, 那么它不能被這個EXCEPTION子句捕獲,而是傳播出去。 一個外層的EXCEPTION子句可以捕獲它。

如果一個錯誤被EXCEPTION捕獲,PL/pgSQL函數(shù)的局部變量保持錯誤發(fā)生時的原值, 但是所有該塊中想固化在數(shù)據(jù)庫中的狀態(tài)都回滾。 作為一個例子,讓我們看看下面片斷

INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
BEGIN
    UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
    x := x + 1;
    y := x / 0;
EXCEPTION
    WHEN division_by_zero THEN
        RAISE NOTICE 'caught division_by_zero';
        RETURN x;
END;

當(dāng)控制到達(dá)給y賦值的地方時,它會帶著一個division_by_zero錯誤失敗。 這個錯誤將被EXCEPTION子句捕獲。 而在RETURN語句里返回的數(shù)值將是x的增量值。 但是UPDATE已經(jīng)被回滾。然而,在該塊之前的INSERT將不會回滾, 因此最終的結(jié)果是數(shù)據(jù)庫包含Tom Jones而不是Joe Jones。

Tip: 進入和退出一個包含EXCEPTION子句的塊要比不包含的塊開銷大的多。 因此,不必要的時候不要使用EXCEPTION。

在異常處理器中,SQLSTATE變量包含拋出錯誤對應(yīng)的錯誤代碼(參考Table A-1獲取可能的錯誤碼的列表)。 SQLSTATE變量包含與異常關(guān)聯(lián)的錯誤信息。 這些變量在異常處理器外面是未定義的。

Example 39-2. UPDATE/INSERT異常

這個例子根據(jù)使用異常處理器執(zhí)行恰當(dāng)?shù)?tt class="COMMAND">UPDATE或INSERT。

CREATE TABLE db (a INT PRIMARY KEY, b TEXT);

CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
    LOOP
        -- first try to update the key
        UPDATE db SET b = data WHERE a = key;
        IF found THEN
            RETURN;
        END IF;
        -- not there, so try to insert the key
        -- if someone else inserts the same key concurrently,
        -- we could get a unique-key failure
        BEGIN
            INSERT INTO db(a,b) VALUES (key, data);
            RETURN;
        EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
        END;
    END LOOP;
END;
$$
LANGUAGE plpgsql;

SELECT merge_db(1, 'david');
SELECT merge_db(1, 'dennis');

上一篇: 下一篇: