国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄 搜尋
目錄 前言 1. 一般信息 1.1. 關(guān)于本手冊 1.2. 本手冊采用的慣例 1.3. MySQL AB概述 1.4. MySQL數(shù)據(jù)庫管理系統(tǒng)概述 1.4.1. MySQL的歷史 1.4.2. MySQL的的主要特性 1.4.3. MySQL穩(wěn)定性 1.4.4. MySQL表最大能達(dá)到多少 1.4.5. 2000年兼容性 1.5. MaxDB數(shù)據(jù)庫管理系統(tǒng)概述 1.5.1. 什么是MaxDB? 1.5.2. MaxDB的歷史 1.5.3. MaxDB的特性 1.5.4. 許可和支持 1.5.5. MaxDB和MySQL之間的特性差異 1.5.6. MaxDB和MySQL之間的協(xié)同性 1.5.7. 與MaxDB有關(guān)的鏈接 1.6. MySQL發(fā)展大事記 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL郵件列表 1.7.2. IRC(在線聊天系統(tǒng))上的MySQL社區(qū)支持 1.7.3. MySQL論壇上的MySQL社區(qū)支持 1.8. MySQL標(biāo)準(zhǔn)的兼容性 1.8.1. MySQL遵從的標(biāo)準(zhǔn)是什么 1.8.2. 選擇SQL模式 1.8.3. 在ANSI模式下運(yùn)行MySQL 1.8.4. MySQL對標(biāo)準(zhǔn)SQL的擴(kuò)展 1.8.5. MySQL與標(biāo)準(zhǔn)SQL的差別 1.8.6. MySQL處理約束的方式 2. 安裝MySQL 2.1. 一般安裝問題 2.1.1. MySQL支持的操作系統(tǒng) 2.1.2. 選擇要安裝的MySQL分發(fā)版 2.1.3. 怎樣獲得MySQL 2.1.4. 通過MD5校驗(yàn)和或GnuPG驗(yàn)證軟件包的完整性 2.1.5. 安裝布局 2.2. 使用二進(jìn)制分發(fā)版的標(biāo)準(zhǔn)MySQL安裝 2.3. 在Windows上安裝MySQL 2.3.1. Windows系統(tǒng)要求 2.3.2. 選擇安裝軟件包 2.3.3. 用自動安裝器安裝MySQL 2.3.4. 使用MySQL安裝向?qū)?/a> 2.3.5. 使用配置向?qū)?/a> 2.3.6. 通過非安裝Zip文件安裝MySQL 2.3.7. 提取安裝檔案文件 2.3.8. 創(chuàng)建選項(xiàng)文件 2.3.9. 選擇MySQL服務(wù)器類型 2.3.10. 首次啟動服務(wù)器 2.3.11. 從Windows命令行啟動MySQL 2.3.12. 以Windows服務(wù)方式啟動MySQL 2.3.13. 測試MySQL安裝 2.3.14. 在Windows環(huán)境下對MySQL安裝的故障診斷與排除 2.3.15. 在Windows下升級MySQL 2.3.16. Windows版MySQL同Unix版MySQL對比 2.4. 在Linux下安裝MySQL 2.5.在Mac OS X中安裝MySQL 2.6. 在NetWare中安裝MySQL 2.7. 在其它類Unix系統(tǒng)中安裝MySQL 2.8. 使用源碼分發(fā)版安裝MySQL 2.8.1. 源碼安裝概述 2.8.2. 典型配置選項(xiàng) 2.8.3. 從開發(fā)源碼樹安裝 2.8.4. 處理MySQL編譯問題 2.8.5. MIT-pthreads注意事項(xiàng) 2.8.6. 在Windows下從源碼安裝MySQL 2.8.7. 在Windows下編譯MySQL客戶端 2.9. 安裝后的設(shè)置和測試 2.9.1. Windows下安裝后的過程 2.9.2. Unix下安裝后的過程 2.9.3. 使初始MySQL賬戶安全 2.10. 升級MySQL 2.10.1. 從5.0版升級 2.10.2. 升級授權(quán)表 2.10.3. 將MySQL數(shù)據(jù)庫拷貝到另一臺機(jī)器 2.11. 降級MySQL 2.12. 具體操作系統(tǒng)相關(guān)的注意事項(xiàng) 2.12.1. Linux注意事項(xiàng) 2.12.2. Mac OS X注意事項(xiàng) 2.12.3. Solaris注意事項(xiàng) 2.12.4. BSD注意事項(xiàng) 2.12.5. 其它Unix注意事項(xiàng) 2.12.6. OS/2注意事項(xiàng) 2.13. Perl安裝注意事項(xiàng) 2.13.1. 在Unix中安裝Perl 2.13.2. 在Windows下安裝ActiveState Perl 2.13.3. 使用Perl DBI/DBD接口的問題 3. 教程 3.1. 連接與斷開服務(wù)器 3.2. 輸入查詢 3.3. 創(chuàng)建并使用數(shù)據(jù)庫 3.3.1. 創(chuàng)建并選擇數(shù)據(jù)庫 3.3.2. 創(chuàng)建表 3.3.3. 將數(shù)據(jù)裝入表中 3.3.4. 從表檢索信息 3.4. 獲得數(shù)據(jù)庫和表的信息 NoName 3.6. 常用查詢的例子 3.6.1. 列的最大值 3.6.2. 擁有某個(gè)列的最大值的行 3.6.3. 列的最大值:按組 3.6.4. 擁有某個(gè)字段的組間最大值的行 3.6.5. 使用用戶變量 3.6.6. 使用外鍵 3.6.7. 根據(jù)兩個(gè)鍵搜索 3.6.8. 根據(jù)天計(jì)算訪問量 3.6.9. 使用AUTO_INCREMENT 3.7. 孿生項(xiàng)目的查詢 3.7.1. 查找所有未分發(fā)的孿生項(xiàng) 3.7.2. 顯示孿生對狀態(tài)的表 3.8. 與Apache一起使用MySQL 4. MySQL程序概述 4.1. MySQL程序概述 4.2. 調(diào)用MySQL程序 4.3. 指定程序選項(xiàng) 4.3.1. 在命令行上使用選項(xiàng) 4.3.2. 使用選項(xiàng)文件 4.3.3. 用環(huán)境變量指定選項(xiàng) 4.3.4. 使用選項(xiàng)設(shè)置程序變量 5. 數(shù)據(jù)庫管理 5.1. MySQL服務(wù)器和服務(wù)器啟動腳本 5.1.1. 服務(wù)器端腳本和實(shí)用工具概述 5.1.2. mysqld-max擴(kuò)展MySQL服務(wù)器 5.1.3. mysqld_safe:MySQL服務(wù)器啟動腳本 5.1.4. mysql.server:MySQL服務(wù)器啟動腳本 5.1.5. mysqld_multi:管理多個(gè)MySQL服務(wù)器的程序 5.2. mysqlmanager:MySQL實(shí)例管理器 5.2.1. 用MySQL實(shí)例管理器啟動MySQL服務(wù)器 5.2.2. 連接到MySQL實(shí)例管理器并創(chuàng)建用戶賬戶 5.2.3. MySQL實(shí)例管理器命令行選項(xiàng) 5.2.4. MySQL實(shí)例管理器配置文件 5.2.5. MySQL實(shí)例管理器識別的命令 5.3. mysqld:MySQL服務(wù)器 5.3.1. mysqld命令行選項(xiàng) 5.3.2. SQL服務(wù)器模式 5.3.3. 服務(wù)器系統(tǒng)變量 5.3.4. 服務(wù)器狀態(tài)變量 5.4. mysql_fix_privilege_tables:升級MySQL系統(tǒng)表 5.5. MySQL服務(wù)器關(guān)機(jī)進(jìn)程 5.6. 一般安全問題 5.6.1. 通用安全指南 5.6.2. 使MySQL在攻擊者面前保持安全 5.6.3. Mysqld安全相關(guān)啟動選項(xiàng) 5.6.4. LOAD DATA LOCAL安全問題 5.7. MySQL訪問權(quán)限系統(tǒng) 5.7.1. 權(quán)限系統(tǒng)的作用 5.7.2. 權(quán)限系統(tǒng)工作原理 5.7.3. MySQL提供的權(quán)限 5.7.4. 與MySQL服務(wù)器連接 5.7.5. 訪問控制 5.7.6. 訪問控制 5.7.7. 權(quán)限更改何時(shí)生效 5.7.8. 拒絕訪問錯(cuò)誤的原因 5.7.9. MySQL 4.1中的密碼哈希處理 5.8. MySQL用戶賬戶管理 5.8.1. MySQL用戶名和密碼 5.8.2. 向MySQL增加新用戶賬戶 5.8.3. 從MySQL刪除用戶賬戶 5.8.4. 限制賬戶資源 5.8.5. 設(shè)置賬戶密碼 5.8.6. 使你的密碼安全 5.8.7. 使用安全連接 5.9. 備份與恢復(fù) 5.9.1. 數(shù)據(jù)庫備份 5.9.2. 示例用備份與恢復(fù)策略 5.9.3. 自動恢復(fù) 5.9.4. 表維護(hù)和崩潰恢復(fù) 5.9.5. myisamchk:MyISAM表維護(hù)實(shí)用工具 5.9.6. 建立表維護(hù)計(jì)劃 5.9.7. 獲取關(guān)于表的信息 5.10. MySQL本地化和國際應(yīng)用 5.10.1. 數(shù)據(jù)和排序用字符集 5.10.2. 設(shè)置錯(cuò)誤消息語言 5.10.3. 添加新的字符集 5.10.4. 字符定義數(shù)組 5.10.5. 字符串比較支持 5.10.6. 多字節(jié)字符支持 5.10.7. 字符集問題 5.10.8. MySQL服務(wù)器時(shí)區(qū)支持 5.11. MySQL日志文件 5.11.1. 錯(cuò)誤日志 5.11.2. 通用查詢?nèi)罩?/a> 5.11.3. 二進(jìn)制日志 5.11.4. 慢速查詢?nèi)罩?/a> 5.11.5. 日志文件維護(hù) 5.12. 在同一臺機(jī)器上運(yùn)行多個(gè)MySQL服務(wù)器 5.12.1. 在Windows下運(yùn)行多個(gè)服務(wù)器 5.12.2. 在Unix中運(yùn)行多個(gè)服務(wù)器 5.12.3. 在多服務(wù)器環(huán)境中使用客戶端程序 5.13. MySQL查詢高速緩沖 5.13.1. 查詢高速緩沖如何工作 5.13.2. 查詢高速緩沖SELECT選項(xiàng) 5.13.3. 查詢高速緩沖配置 5.13.4. 查詢高速緩沖狀態(tài)和維護(hù) 6. MySQL中的復(fù)制 6.1. 復(fù)制介紹 6.2. 復(fù)制實(shí)施概述 6.3. 復(fù)制實(shí)施細(xì)節(jié) 6.3.1. 復(fù)制主線程狀態(tài) 6.3.2. 復(fù)制從I/O線程狀態(tài) 6.3.3. 復(fù)制從SQL線程狀態(tài) 6.3.4. 復(fù)制傳遞和狀態(tài)文件 6.4. 如何設(shè)置復(fù)制 6.5. 不同MySQL版本之間的復(fù)制兼容性 6.6. 升級復(fù)制設(shè)置 6.6.1. 將復(fù)制升級到5.0版 6.7. 復(fù)制特性和已知問題 6.8. 復(fù)制啟動選項(xiàng) 6.9. 復(fù)制FAQ 6.10. 復(fù)制故障診斷與排除 6.11. 通報(bào)復(fù)制缺陷 6.12. 多服務(wù)器復(fù)制中的Auto-Increment 7. 優(yōu)化 7.1. 優(yōu)化概述 7.1.1. MySQL設(shè)計(jì)局限與折衷 7.1.2. 為可移植性設(shè)計(jì)應(yīng)用程序 7.1.3. 我們已將MySQL用在何處? 7.1.4. MySQL基準(zhǔn)套件 7.1.5. 使用自己的基準(zhǔn) 7.2. 優(yōu)化SELECT語句和其它查詢 7.2.1. EXPLAIN語法(獲取SELECT相關(guān)信息) 7.2.2. 估計(jì)查詢性能 7.2.3. SELECT查詢的速度 7.2.4. MySQL怎樣優(yōu)化WHERE子句 7.2.5. 范圍優(yōu)化 7.2.6. 索引合并優(yōu)化 7.2.7. MySQL如何優(yōu)化IS NULL 7.2.8. MySQL如何優(yōu)化DISTINCT 7.2.9. MySQL如何優(yōu)化LEFT JOIN和RIGHT JOIN 7.2.10. MySQL如何優(yōu)化嵌套Join 7.2.11. MySQL如何簡化外部聯(lián)合 7.2.12. MySQL如何優(yōu)化ORDER BY 7.2.13. MySQL如何優(yōu)化GROUP BY 7.2.14. MySQL如何優(yōu)化LIMIT 7.2.15. 如何避免表掃描 7.2.16. INSERT語句的速度 7.2.17. UPDATE語句的速度 7.2.18. DELETE語句的速度 7.2.19. 其它優(yōu)化技巧 7.3. 鎖定事宜 7.3.1. 鎖定方法 7.3.2. 表鎖定事宜 7.4. 優(yōu)化數(shù)據(jù)庫結(jié)構(gòu) 7.4.1. 設(shè)計(jì)選擇 7.4.2. 使你的數(shù)據(jù)盡可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM鍵高速緩沖 7.4.7. MyISAM索引統(tǒng)計(jì)集合 7.4.8. MySQL如何計(jì)算打開的表 7.4.9. MySQL如何打開和關(guān)閉表 7.4.10. 在同一個(gè)數(shù)據(jù)庫中創(chuàng)建多個(gè)表的缺陷 7.5. 優(yōu)化MySQL服務(wù)器 7.5.1. 系統(tǒng)因素和啟動參數(shù)的調(diào)節(jié) 7.5.2. 調(diào)節(jié)服務(wù)器參數(shù) 7.5.3. 控制查詢優(yōu)化器的性能 7.5.4. 編譯和鏈接怎樣影響MySQL的速度 7.5.5. MySQL如何使用內(nèi)存 7.5.6. MySQL如何使用DNS 7.6. 磁盤事宜 7.6.1. 使用符號鏈接 8. 客戶端和實(shí)用工具程序 8.1. 客戶端腳本和實(shí)用工具概述 8.2. myisampack:生成壓縮、只讀MyISAM表 8.3. mysql:MySQL命令行工具 8.3.1. 選項(xiàng) 8.3.2. mysql命令 8.3.3. 怎樣從文本文件執(zhí)行SQL語句 8.3.4. mysql技巧 8.4. mysqlaccess:用于檢查訪問權(quán)限的客戶端 8.5. mysqladmin:用于管理MySQL服務(wù)器的客戶端 8.6. mysqlbinlog:用于處理二進(jìn)制日志文件的實(shí)用工具 8.7. mysqlcheck:表維護(hù)和維修程序 8.8. mysqldump:數(shù)據(jù)庫備份程序 8.9. mysqlhotcopy:數(shù)據(jù)庫備份程序 8.10. mysqlimport:數(shù)據(jù)導(dǎo)入程序 8.11. mysqlshow-顯示數(shù)據(jù)庫、表和列信息 8.12. myisamlog:顯示MyISAM日志文件內(nèi)容 8.13. perror:解釋錯(cuò)誤代碼 8.14. replace:字符串替換實(shí)用工具 8.15. mysql_zap:殺死符合某一模式的進(jìn)程 9. 語言結(jié)構(gòu) 9.1. 文字值 9.1.1. 字符串 9.1.2. 數(shù)值 9.1.3. 十六進(jìn)制值 9.1.4. 布爾值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 數(shù)據(jù)庫、表、索引、列和別名 9.2.1. 識別符限制條件 9.2.2. 識別符大小寫敏感性 9.3. 用戶變量 9.4. 系統(tǒng)變量 9.4.1. 結(jié)構(gòu)式系統(tǒng)變量 9.5. 注釋語法 9.6. MySQL中保留字的處理 10. 字符集支持 10.1. 常規(guī)字符集和校對 10.2. MySQL中的字符集和校對 10.3. 確定默認(rèn)字符集和校對 10.3.1. 服務(wù)器字符集和校對 10.3.2. 數(shù)據(jù)庫字符集和校對 10.3.3. 表字符集和校對 10.3.4. 列字符集和校對 10.3.5. 字符集和校對分配示例 10.3.6. 連接字符集和校對 10.3.7. 字符串文字字符集和校對 10.3.8. 在SQL語句中使用COLLATE 10.3.9. COLLATE子句優(yōu)先 10.3.10. BINARY操作符 10.3.11. 校對確定較為復(fù)雜的一些特殊情況 10.3.12. 校對必須適合字符集 10.3.13. 校對效果的示例 10.4. 字符集支持影響到的操作 10.4.1. 結(jié)果字符串 10.4.2. CONVERT() 10.4.3. CAST() 10.4.4. SHOW語句 10.5. Unicode支持 10.6. 用于元數(shù)據(jù)的UTF8 10.7. 與其它DBMS的兼容性 10.8. 新字符集配置文件格式 10.9. 國家特有字符集 10.10. MySQL支持的字符集和校對 10.10.1. Unicode字符集 10.10.2. 西歐字符集 10.10.3. 中歐字符集 10.10.4. 南歐與中東字符集 10.10.5. 波羅的海字符集 10.10.6. 西里爾字符集 10.10.7. 亞洲字符集 11. 列類型 11.1. 列類型概述 11.1.1. 數(shù)值類型概述 11.1.2. 日期和時(shí)間類型概述 11.1.3. 字符串類型概述 11.2. 數(shù)值類型 11.3. 日期和時(shí)間類型 11.3.1. DATETIME、DATE和TIMESTAMP類型 11.3.2. TIME類型 11.3.3. YEAR類型 11.3.4. Y2K事宜和日期類型 11.4. String類型 11.4.1. CHAR和VARCHAR類型 11.4.2. BINARY和VARBINARY類型 11.4.3. BLOB和TEXT類型 11.4.4. ENUM類型 11.4.5. SET類型 11.5. 列類型存儲需求 11.6. 選擇正確的列類型 11.7. 使用來自其他數(shù)據(jù)庫引擎的列類型 12. 函數(shù)和操作符 12.1. 操作符 12.1.1. 操作符優(yōu)先級 12.1.2. 圓括號 12.1.3. 比較函數(shù)和操作符 12.1.4. 邏輯操作符 12.2. 控制流程函數(shù) 12.3. 字符串函數(shù) 12.3.1. 字符串比較函數(shù) 12.4. 數(shù)值函數(shù) 12.4.1. 算術(shù)操作符 12.4.2. 數(shù)學(xué)函數(shù) 12.5. 日期和時(shí)間函數(shù) 12.6. MySQL使用什么日歷? 12.7. 全文搜索功能 12.7.1. 布爾全文搜索 12.7.2. 全文搜索帶查詢擴(kuò)展 12.7.3. 全文停止字 12.7.4. 全文限定條件 12.7.5. 微調(diào)MySQL全文搜索 12.8. Cast函數(shù)和操作符 12.9. 其他函數(shù) 12.9.1. 位函數(shù) 12.9.2. 加密函數(shù) 12.9.3. 信息函數(shù) 12.9.4. 其他函數(shù) NoName 12.10.1. GROUP BY(聚合)函數(shù) 12.10.2. GROUP BY修改程序 12.10.3. 具有隱含字段的GROUP BY 13. SQL語句語法 13.1. 數(shù)據(jù)定義語句 13.1.1. ALTER DATABASE語法 13.1.2. ALTER TABLE語法 13.1.3. CREATE DATABASE語法 13.1.4. CREATE INDEX語法 13.1.5. CREATE TABLE語法 13.1.6. DROP DATABASE語法 13.1.7. DROP INDEX語法 13.1.8. DROP TABLE語法 13.1.9. RENAME TABLE語法 13.2. 數(shù)據(jù)操作語句 13.2.1. DELETE語法 13.2.2. DO語法 13.2.3. HANDLER語法 13.2.4. INSERT語法 13.2.5. LOAD DATA INFILE語法 13.2.6. REPLACE語法 13.2.7. SELECT語法 13.2.8. Subquery語法 13.2.9. TRUNCATE語法 13.2.10. UPDATE語法 13.3. MySQL實(shí)用工具語句 13.3.1. DESCRIBE語法(獲取有關(guān)列的信息) 13.3.2. USE語法 13.4. MySQL事務(wù)處理和鎖定語句 13.4.1. START TRANSACTION 13.4.2. 不能回滾的語句 13.4.3. 會造成隱式提交的語句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT語法 13.4.5. LOCK TABLES和UNLOCK TABLES語法 13.4.6. SET TRANSACTION語法 13.4.7. XA事務(wù) 13.5. 數(shù)據(jù)庫管理語句 13.5.1. 賬戶管理語句 13.5.2. 表維護(hù)語句 13.5.3. SET語法 13.5.4. SHOW語法 13.5.5. 其它管理語句 13.6. 復(fù)制語句 13.6.1. 用于控制主服務(wù)器的SQL語句 13.6.2. 用于控制從服務(wù)器的SQL語句 13.7. 用于預(yù)處理語句的SQL語法 14. 插件式存儲引擎體系結(jié)構(gòu) 14.1. 前言 14.2. 概述 14.3. 公共MySQL數(shù)據(jù)庫服務(wù)器層 14.4. 選擇存儲引擎 14.5. 將存儲引擎指定給表 14.6. 存儲引擎和事務(wù) 14.7. 插入存儲引擎 14.8. 拔出存儲引擎 14.9. 插件式存儲器的安全含義 15. 存儲引擎和表類型 15.1. MyISAM存儲引擎 15.1.1. MyISAM啟動選項(xiàng) 15.1.2. 鍵所需的空間 15.1.3. MyISAM表的存儲格式 15.1.4. MyISAM表方面的問題 15.2. InnoDB存儲引擎 15.2.1. InnoDB概述 15.2.2. InnoDB聯(lián)系信息 15.2.3. InnoDB配置 15.2.4. InnoDB啟動選項(xiàng) 15.2.5. 創(chuàng)建InnoDB表空間 15.2.6. 創(chuàng)建InnoDB表 15.2.7. 添加和刪除InnoDB數(shù)據(jù)和日志文件 15.2.8. InnoDB數(shù)據(jù)庫的備份和恢復(fù) 15.2.9. 將InnoDB數(shù)據(jù)庫移到另一臺機(jī)器上 15.2.10. InnoDB事務(wù)模型和鎖定 15.2.11. InnoDB性能調(diào)節(jié)提示 15.2.12. 多版本的實(shí)施 15.2.13. 表和索引結(jié)構(gòu) 15.2.14. 文件空間管理和磁盤I/O 15.2.15. InnoDB錯(cuò)誤處理 15.2.16. 對InnoDB表的限制 15.2.17. InnoDB故障診斷與排除 15.3. MERGE存儲引擎 15.3.1. MERGE表方面的問題 15.4. MEMORY (HEAP)存儲引擎 15.5. BDB (BerkeleyDB)存儲引擎 15.5.1. BDB支持的操作系統(tǒng) 15.5.2. 安裝BDB 15.5.3. BDB啟動選項(xiàng) 15.5.4. BDB表的特性 15.5.5. 修改BDB所需的事宜 15.5.6. 對BDB表的限制 15.5.7. 使用BDB表時(shí)可能出現(xiàn)的錯(cuò)誤 15.6. EXAMPLE存儲引擎 15.7. FEDERATED存儲引擎 15.7.1. 安裝FEDERATED存儲引擎 15.7.2. FEDERATED存儲引擎介紹 15.7.3. 如何使用FEDERATED表 15.7.4. FEDERATED存儲引擎的局限性 15.8. ARCHIVE存儲引擎 15.9. CSV存儲引擎 15.10. BLACKHOLE存儲引擎 16. 編寫自定義存儲引擎 16.1. 前言 16.2. 概述 16.3. 創(chuàng)建存儲引擎源文件 NoName 16.5. 對處理程序進(jìn)行實(shí)例化處理 16.6. 定義表擴(kuò)展 16.7. 創(chuàng)建表 16.8. 打開表 16.9. 實(shí)施基本的表掃描功能 16.9.1. 實(shí)施store_lock()函數(shù) 16.9.2. 實(shí)施external_lock()函數(shù) 16.9.3. 實(shí)施rnd_init()函數(shù) 16.9.4. 實(shí)施info()函數(shù) 16.9.5. 實(shí)施extra()函數(shù) 16.9.6. 實(shí)施rnd_next()函數(shù) 16.10. 關(guān)閉表 NoName NoName NoName 16.14. API引用 16.14.1. bas_ext 16.14.2. close 16.14.3. create 16.14.4. delete_row 16.14.5. delete_table 16.14.6. external_lock 16.14.7. extra 16.14.8. info 16.14.9. open 16.14.10. rnd_init 16.14.11. rnd_next 16.14.12. store_lock 16.14.13. update_row 16.14.14. write_row 17. MySQL簇 17.1. MySQL簇概述 17.2. MySQL簇的基本概念 17.3. 多計(jì)算機(jī)的簡單基礎(chǔ)知識 17.3.1. 硬件、軟件和聯(lián)網(wǎng) 17.3.2. 安裝 17.3.3. 配置 17.3.4. 首次啟動 17.3.5. 加載示例數(shù)據(jù)并執(zhí)行查詢 17.3.6. 安全關(guān)閉和重啟 17.4. MySQL簇的配置 17.4.1. 從源碼創(chuàng)建MySQL簇 17.4.2. 安裝軟件 17.4.3. MySQL簇的快速測試設(shè)置 17.4.4. 配置文件 17.5. MySQL簇中的進(jìn)程管理 17.5.1. 用于MySQL簇的MySQL服務(wù)器進(jìn)程使用 17.5.2. ndbd,存儲引擎節(jié)點(diǎn)進(jìn)程 17.5.3. ndb_mgmd,“管理服務(wù)器”進(jìn)程 17.5.4. ndb_mgm,“管理客戶端”進(jìn)程 17.5.5. 用于MySQL簇進(jìn)程的命令選項(xiàng) 17.6. MySQL簇的管理 17.6.1. MySQL簇的啟動階段 17.6.2. “管理客戶端”中的命令 17.6.3. MySQL簇中生成的事件報(bào)告 17.6.4. 單用戶模式 17.6.5. MySQL簇的聯(lián)機(jī)備份 17.7. 使用與MySQL簇的高速互連 17.7.1. 配置MySQL簇以使用SCI套接字 17.7.2. 理解簇互連的影響 17.8. MySQL簇的已知限制 17.9. MySQL簇發(fā)展的重要?dú)v程 17.9.1. MySQL 5.0中的MySQL簇變化 17.9.2. 關(guān)于MySQL簇的MySQL 5.1發(fā)展歷程 17.10. MySQL簇常見問題解答 17.11. MySQL簇術(shù)語表 18. 分區(qū) 18.1. MySQL中的分區(qū)概述 18.2. 分區(qū)類型 18.2.1. RANGE分區(qū) 18.2.2. LIST分區(qū) 18.2.3. HASH分區(qū) 18.2.4. KEY分區(qū) 18.2.5. 子分區(qū) 18.2.6. MySQL分區(qū)處理NULL值的方式 18.3. 分區(qū)管理 18.3.1. RANGE和LIST分區(qū)的管理 18.3.2. HASH和KEY分區(qū)的管理 18.3.3. 分區(qū)維護(hù) 18.3.4. 獲取關(guān)于分區(qū)的信息 19. MySQL中的空間擴(kuò)展 19.1. 前言 19.2. OpenGIS幾何模型 19.2.1. Geometry類的層次 19.2.2. 類Geometry 19.2.3. 類Point 19.2.4. 類Curve 19.2.5. 類LineString 19.2.6. 類Surface 19.2.7. 類Polygon 19.2.8. 類GeometryCollection 19.2.9. 類MultiPoint 19.2.10. 類MultiCurve 19.2.11. 類MultiLineString 19.2.12. 類MultiSurface 19.2.13. 類MultiPolygon 19.3. 支持的空間數(shù)據(jù)格式 19.3.1. 著名的文本(WKT)格式 19.3.2. 著名的二進(jìn)制(WKB)格式 19.4. 創(chuàng)建具備空間功能的MySQL數(shù)據(jù)庫 19.4.1. MySQL空間數(shù)據(jù)類型 19.4.2. 創(chuàng)建空間值 19.4.3. 創(chuàng)建空間列 19.4.4. 填充空間列 19.4.5. 獲取空間數(shù)據(jù) 19.5. 分析空間信息 19.5.1. Geometry格式轉(zhuǎn)換函數(shù) 19.5.2. Geometry函數(shù) 19.5.3. 從已有Geometry創(chuàng)建新Geometry的函數(shù) 19.5.4. 測試幾何對象間空間關(guān)系的函數(shù) 19.5.5. 關(guān)于幾何最小邊界矩形(MBR)的關(guān)系 19.5.6. 測試幾何類之間空間關(guān)系的函數(shù) 19.6. 優(yōu)化空間分析 19.6.1. 創(chuàng)建空間索引 19.6.2. 使用空間索引 19.7. MySQL的一致性和兼容性 19.7.1. 尚未實(shí)施的GIS特性 20. 存儲程序和函數(shù) 20.1. 存儲程序和授權(quán)表 20.2. 存儲程序的語法 20.2.1. CREATE PROCEDURE和CREATE FUNCTION 20.2.2. ALTER PROCEDURE和ALTER FUNCTION 20.2.3. DROP PROCEDURE和DROP FUNCTION 20.2.4.SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION 20.2.5.SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS 20.2.6. CALL語句 20.2.7. BEGIN ... END復(fù)合語句 20.2.8. DECLARE語句 20.2.9. 存儲程序中的變量 20.2.10. 條件和處理程序 20.2.11. 光標(biāo) 20.2.12. 流程控制構(gòu)造 20.3. 存儲程序、函數(shù)、觸發(fā)程序和復(fù)制:常見問題 20.4. 存儲子程序和觸發(fā)程序的二進(jìn)制日志功能 21. 觸發(fā)程序 21.1. CREATE TRIGGER語法 21.2. DROP TRIGGER語法 21.3. 使用觸發(fā)程序 22. 視圖 22.1. ALTER VIEW語法 22.2. CREATE VIEW語法 22.3. DROP VIEW語法 22.4. SHOW CREATE VIEW語法 23. INFORMATION_SCHEMA信息數(shù)據(jù)庫 23.1. INFORMATION_SCHEMA表 23.1.1. INFORMATION_SCHEMA SCHEMATA表 23.1.2. INFORMATION_SCHEMA TABLES表 23.1.3. INFORMATION_SCHEMA COLUMNS表 23.1.4. INFORMATION_SCHEMA STATISTICS表 23.1.5. INFORMATION_SCHEMA USER_PRIVILEGES表 23.1.6. INFORMATION_SCHEMA SCHEMA_PRIVILEGES表 23.1.7. INFORMATION_SCHEMA TABLE_PRIVILEGES表 23.1.8. INFORMATION_SCHEMA COLUMN_PRIVILEGES表 23.1.9. INFORMATION_SCHEMA CHARACTER_SETS表 23.1.10. INFORMATION_SCHEMA COLLATIONS表 23.1.11. INFORMATION_SCHEMA COLLATION_CHARACTER_SET_APPLICABILITY表 23.1.12. INFORMATION_SCHEMA TABLE_CONSTRAINTS表 23.1.13. INFORMATION_SCHEMA KEY_COLUMN_USAGE表 23.1.14. INFORMATION_SCHEMA ROUTINES表 23.1.15. INFORMATION_SCHEMA VIEWS表 23.1.16. INFORMATION_SCHEMA TRIGGERS表 23.1.17. 其他INFORMATION_SCHEMA表 NoName 24. 精度數(shù)學(xué) 24.1. 數(shù)值的類型 24.2. DECIMAL數(shù)據(jù)類型更改 24.3. 表達(dá)式處理 24.4. 四舍五入 24.5. 精度數(shù)學(xué)示例 25. API和庫 25.1. libmysqld,嵌入式MySQL服務(wù)器庫 25.1.1. 嵌入式MySQL服務(wù)器庫概述 25.1.2. 使用libmysqld編譯程序 25.1.3. 使用嵌入式MySQL服務(wù)器時(shí)的限制 25.1.4. 與嵌入式服務(wù)器一起使用的選項(xiàng) 25.1.5. 嵌入式服務(wù)器中尚需完成的事項(xiàng)(TODO) 25.1.6. 嵌入式服務(wù)器示例 25.1.7. 嵌入式服務(wù)器的許可 25.2. MySQL C API 25.2.1. C API數(shù)據(jù)類型 25.2.2. C API函數(shù)概述 25.2.3. C API函數(shù)描述 25.2.4. C API預(yù)處理語句 25.2.5. C API預(yù)處理語句的數(shù)據(jù)類型 25.2.6. C API預(yù)處理語句函數(shù)概述 25.2.7. C API預(yù)處理語句函數(shù)描述 25.2.8. C API預(yù)處理語句方面的問題 25.2.9. 多查詢執(zhí)行的C API處理 25.2.10. 日期和時(shí)間值的C API處理 25.2.11. C API線程函數(shù)介紹 25.2.12. C API嵌入式服務(wù)器函數(shù)介紹 25.2.13. 使用C API時(shí)的常見問題 25.2.14. 創(chuàng)建客戶端程序 25.2.15. 如何生成線程式客戶端 25.3. MySQL PHP API 25.3.1. 使用MySQL和PHP的常見問題 25.4. MySQL Perl API 25.5. MySQL C++ API 25.5.1. Borland C++ 25.6. MySQL Python API 25.7. MySQL Tcl API 25.8. MySQL Eiffel Wrapper 25.9. MySQL程序開發(fā)實(shí)用工具 25.9.1. msql2mysql:轉(zhuǎn)換mSQL程序以用于MySQL 25.9.2. mysql_config:獲取編譯客戶端的編譯選項(xiàng) 26. 連接器 26.1. MySQL Connector/ODBC 26.1.1. MyODBC介紹 26.1.2. 關(guān)于ODBC和MyODBC的一般信息 26.1.3. 如何安裝MyODBC 26.1.4. 在Windows平臺上從二進(jìn)制版本安裝MyODBC 26.1.5. I在Unix平臺上從二進(jìn)制版本安裝MyODBC 26.1.6. 在Windows平臺上從源碼版本安裝MyODBC 26.1.7. 在Unix平臺上從源碼版本安裝MyODBC 26.1.8. 從BitKeeper開發(fā)源碼樹安裝MyODBC 26.1.9. MyODBC配置 26.1.10. 與MyODBC連接相關(guān)的事宜 26.1.11. MyODBC和Microsoft Access 26.1.12. MyODBC和Microsoft VBA及ASP 26.1.13. MyODBC和第三方ODBC工具 26.1.14. MyODBC通用功能 26.1.15. 基本的MyODBC應(yīng)用步驟 26.1.16. MyODBC API引用 26.1.17. MyODBC數(shù)據(jù)類型 26.1.18. MyODBC錯(cuò)誤代碼 26.1.19. MyODBC與VB:ADO、DAO和RDO 26.1.20. MyODBC與Microsoft.NET 26.1.21. 感謝 26.2. MySQL Connector/NET 26.2.1. 前言 26.2.2. 下載并安裝MySQL Connector/NET 26.2.3. Connector/NET體系結(jié)構(gòu) 26.2.4. 使用MySQL Connector/NET 26.2.5. MySQL Connector/NET變更史 26.3. MySQL Connector/J 26.3.1. 基本的JDBC概念 26.3.2. 安裝 Connector/J 26.3.3. JDBC引用 26.3.4. 與J2EE和其他Java框架一起使用 Connector/J 26.3.5. 診斷 Connector/J方面的問題 26.3.6. Changelog 26.4. MySQL Connector/MXJ 26.4.1. 前言 26.4.2. 支持平臺: 26.4.3. Junit測試要求 26.4.4. 運(yùn)行Junit測試 26.4.5. 作為JDBC驅(qū)動程序的一部分運(yùn)行 26.4.6. 在Java對象中運(yùn)行 26.4.7. MysqldResource API 26.4.8. 在JMX代理(custom)中運(yùn)行 26.4.9. 部署在標(biāo)準(zhǔn)的JMX代理環(huán)境下 (JBoss) 26.4.10. 安裝 27. 擴(kuò)展MySQL 27.1. MySQL內(nèi)部控件 27.1.1. MySQL線程 27.1.2. MySQL測試套件 27.2. 為MySQL添加新函數(shù) 27.2.1. 自定義函數(shù)接口的特性 27.2.2. CREATE FUNCTION/DROP FUNCTION語法 27.2.3. 添加新的自定義函數(shù) 27.2.4. 添加新的固有函數(shù) 27.3. 為MySQL添加新步驟 27.3.1. 步驟分析 27.3.2. 編寫步驟 A. 問題和常見錯(cuò)誤 A.1. 如何確定導(dǎo)致問題的原因 A.2. 使用MySQL程序時(shí)的常見錯(cuò)誤 A.2.1. 拒絕訪問 A.2.2. 無法連接到[local] MySQL服務(wù)器 A.2.3. 客戶端不支持鑒定協(xié)議 A.2.4. 輸入密碼時(shí)出現(xiàn)密碼錯(cuò)誤 NoName A.2.6. 連接數(shù)過多 A.2.7. 內(nèi)存溢出 A.2.8. MySQL服務(wù)器不可用 A.2.9. 信息包過大 A.2.10. 通信錯(cuò)誤和失效連接 A.2.11. 表已滿 A.2.12. 無法創(chuàng)建文件/寫入文件 A.2.13. 命令不同步 A.2.14. 忽略用戶 A.2.15. 表tbl_name不存在 A.2.16. 無法初始化字符集 A.2.17. 文件未找到 A.3. 與安裝有關(guān)的事宜 A.3.1. 與MySQL客戶端庫的鏈接問題 A.3.2. 如何以普通用戶身份運(yùn)行MySQL A.3.3. 與文件許可有關(guān)的問題 A.4. 與管理有關(guān)的事宜 A.4.1. 如何復(fù)位根用戶密碼 A.4.2. 如果MySQL依然崩潰,應(yīng)作些什么 A.4.3. MySQL處理磁盤滿的方式 A.4.4. MySQL將臨時(shí)文件儲存在哪里 A.4.5. 如何保護(hù)或更改MySQL套接字文件/tmp/mysql.sock A.4.6. 時(shí)區(qū)問題 A.5. 與查詢有關(guān)的事宜 A.5.1. 搜索中的大小寫敏感性 A.5.2. 使用DATE列方面的問題 A.5.3. 與NULL值有關(guān)的問題 A.5.4. 與列別名有關(guān)的問題 A.5.5. 非事務(wù)表回滾失敗 A.5.6. 從相關(guān)表刪除行 A.5.7. 解決與不匹配行有關(guān)的問題 A.5.8. 與浮點(diǎn)比較有關(guān)的問題 A.6. 與優(yōu)化器有關(guān)的事宜 A.7. 與表定義有關(guān)的事宜 A.7.1. 與ALTER TABLE有關(guān)的問題 A.7.2. 如何更改表中的列順序 A.7.3. TEMPORARY TABLE問題 A.8. MySQL中的已知事宜 A.8.1. MySQL中的打開事宜 B. 錯(cuò)誤代碼和消息 B.1. 服務(wù)器錯(cuò)誤代碼和消息 B.2. 客戶端錯(cuò)誤代碼和消息 C. 感謝 C.1. MySQL AB處的開發(fā)人 C.2. MySQL貢獻(xiàn)人 C.3. 資料員和譯員 C.4. MySQL使用和包含的庫 C.5. 支持MySQL的軟件包 C.6. 用于創(chuàng)建MySQL的工具 C.7. MySQL支持人員 D. MySQL變更史 D.1. 5.1.x版中的變更情況(開發(fā)) D.1.1. 5.1.2版中的變更情況(尚未發(fā)布) D.1.2. 5.1.1版中的變更情況(尚未發(fā)布) D.2. MyODBC的變更情況 D.2.1. MyODBC 3.51.12的變更情況 D.2.2. MyODBC 3.51.11的變更情況 E. 移植到其他系統(tǒng) E.1. 調(diào)試MySQL服務(wù)器 E.1.1. 針對調(diào)試編譯MySQL E.1.2. 創(chuàng)建跟蹤文件 E.1.3. 在gdb環(huán)境下調(diào)試mysqld E.1.4. 使用堆棧跟蹤 E.1.5. 使用日志文件找出mysqld中的錯(cuò)誤原因 E.1.6. 如果出現(xiàn)表崩潰,請生成測試案例 E.2. 調(diào)試MySQL客戶端 E.3. DBUG軟件包 E.4. 關(guān)于RTS線程的注釋 E.5. 線程軟件包之間的差異 F. 環(huán)境變量 G. MySQL正則表達(dá)式 H. MySQL中的限制 H.1. 聯(lián)合的限制 I. 特性限制 I.1. 對存儲子程序和觸發(fā)程序的限制 I.2. 對服務(wù)器端光標(biāo)的限制 I.3. 對子查詢的限制 I.4. 對視圖的限制 I.5. 對XA事務(wù)的限制 J. GNU通用公共許可 K. MySQL FLOSS許可例外 索引
文字

第20章:存儲程序和函數(shù)

目錄

20.1. 存儲程序和授權(quán)表

20.2. 存儲程序的語法

20.2.1. CREATE PROCEDURE和CREATE FUNCTION

20.2.2. ALTER PROCEDURE和ALTER FUNCTION

20.2.3. DROP PROCEDURE和和DROP FUNCTION

20.2.4. SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION

20.2.5. SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS

20.2.6. CALL語句

20.2.7. BEGIN ... END復(fù)合語句

20.2.8. DECLARE語句

20.2.9. 存儲程序中的變量

20.2.10. 條件和處理程序

20.2.11. 光標(biāo)

20.2.12. 流程控制構(gòu)造

20.3. 存儲程序、函數(shù)、觸發(fā)程序和復(fù)制:常見問題

20.4. 存儲子程序和觸發(fā)程序的二進(jìn)制日志功能

MySQL 5.1版支持存儲程序和函數(shù)。一個(gè)存儲程序是可以被存儲在服務(wù)器中的一套SQL語句。一旦它被存儲了,客戶端不需要再重新發(fā)布單獨(dú)的語句,而是可以引用存儲程序來替代。

下面一些情況下存儲程序尤其有用:

·???????? 當(dāng)用不同語言編寫多客戶應(yīng)用程序,或多客戶應(yīng)用程序在不同平臺上運(yùn)行且需要執(zhí)行相同的數(shù)據(jù)庫操作之時(shí)。

·???????? 安全極為重要之時(shí)。比如,銀行對所有普通操作使用存儲程序。這提供一個(gè)堅(jiān)固而安全的環(huán)境,程序可以確保每一個(gè)操作都被妥善記入日志。在這樣一個(gè)設(shè)置中,應(yīng)用程序和用戶不可能直接訪問數(shù)據(jù)庫表,但是僅可以執(zhí)行指定的存儲程序。

儲程序可以提供改良后的性能,因?yàn)橹挥休^少的信息需要在服務(wù)器和客戶算之間傳送。代價(jià)是增加數(shù)據(jù)庫服務(wù)器系統(tǒng)的負(fù)荷,因?yàn)楦嗟墓ぷ髟诜?wù)器這邊完成,更少的在客戶端(應(yīng)用程序)那邊完成上。如果許多客戶端機(jī)器(比如網(wǎng)頁服務(wù)器)只由一個(gè)或少數(shù)幾個(gè)數(shù)據(jù)庫服務(wù)器提供服務(wù),可以考慮一下存儲程序。

存儲程序也允許你在數(shù)據(jù)庫服務(wù)器上有函數(shù)庫。這是一個(gè)被現(xiàn)代應(yīng)用程序語言共享的特征,它允許這樣的內(nèi)部設(shè)計(jì),比如通過使用類。使用這些客戶端應(yīng)用程序語言特征對甚至于數(shù)據(jù)庫使用范圍以外的編程人員都有好處。

MySQL為存儲程序遵循SQL:2003語法,這個(gè)語法也被用在IBM的DB2數(shù)據(jù)庫上。

MySQL對存儲程序的實(shí)現(xiàn)還在進(jìn)度中。所有本章敘述的語法都被支持,在有限制或擴(kuò)展的地方會恰當(dāng)?shù)刂赋鰜怼S嘘P(guān)使用 存儲程序的限制的更多討論在附錄?I, 特性限制 里提到。

如20.4節(jié),“存儲子程序和觸發(fā)程序的二進(jìn)制日志功能” 里所說的, 存儲子程序的二進(jìn)制日志功能已經(jīng)完成。

20.1.?存儲程序和授權(quán)表

存儲程序需要在mysql數(shù)據(jù)庫中有proc表。這個(gè)表在MySQL 5.1安裝過程中創(chuàng)建。如果你從早期的版本升級到MySQL 5.1 ,請確定更新你的授權(quán)表以確保proc表的存在。請參閱2.10.2節(jié) “升級授權(quán)表” 。

在MySQL 5.1中,授權(quán)系統(tǒng)如下考慮存儲子程序:

·???????? 創(chuàng)建存儲子程序需要CREATE ROUTINE權(quán)限。

·???????? 提醒或移除存儲子程序需要ALTER ROUTINE權(quán)限。這個(gè)權(quán)限自動授予子程序的創(chuàng)建者。

·???????? 執(zhí)行子程序需要EXECUTE權(quán)限。然而,這個(gè)權(quán)限自動授予 子程序的創(chuàng)建者。同樣,子程序默認(rèn)的SQL SECURITY 特征是DEFINER,它允許用該子程序訪問數(shù)據(jù)庫的用戶與執(zhí)行子程序聯(lián)系到一起。

20.2.?存儲程序的語法

20.2.1. CREATE PROCEDURE和CREATE FUNCTION

20.2.2. ALTER PROCEDURE和ALTER FUNCTION

20.2.3. DROP PROCEDURE和DROP FUNCTION

20.2.4. SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION

20.2.5. SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS

20.2.6. CALL語句

20.2.7. BEGIN ... END復(fù)合語句

20.2.8. DECLARE語句

20.2.9. 存儲程序中的變量

20.2.10. 條件和處理程序

20.2.11. 光標(biāo)

20.2.12. 流程控制構(gòu)造

存儲程序和函數(shù)是用CREATE PROCEDURE和CREATE FUNCTION語句創(chuàng)建的子程序。一個(gè)子程序要么是一個(gè)程序要么是一個(gè)函數(shù)。使用CALL語句來調(diào)用 程序,程序只能用輸出變量傳回值。就像別其它函數(shù)調(diào)用一樣,函數(shù)可以被從語句外調(diào)用(即通過引用函數(shù)名),函數(shù)能返回標(biāo)量值。 存儲子程序也可以調(diào)用其它存儲子程序。

在MySQL 5.1中,一個(gè)存儲子程序或函數(shù)與特定的數(shù)據(jù)庫相聯(lián)系。這里有幾個(gè)意思:

·???????? 當(dāng)一個(gè)子程序被調(diào)用時(shí),一個(gè)隱含的USE db_name 被執(zhí)行(當(dāng)子程序終止時(shí)停止執(zhí)行)。存儲子程序內(nèi)的USE語句時(shí)不允許的。

·???????? 你可以使用數(shù)據(jù)庫名限定子程序名。這可以被用來引用一個(gè)不在當(dāng)前數(shù)據(jù)庫中的子程序。比如,要引用一個(gè)與test數(shù)據(jù)庫關(guān)聯(lián)的存儲程序p或函數(shù)f,你可以說CALL test.p()或test.f()。

·???????? 數(shù)據(jù)庫移除的時(shí)候,與它關(guān)聯(lián)的所有存儲子程序也都被移除。

MySQL 支持非常有用的擴(kuò)展,即它允許在存儲程序中使用常規(guī)的SELECT語句(那就是說,不使用光標(biāo)或 局部變量)。這個(gè)一個(gè)查詢的結(jié)果包被簡單地直接送到客戶端。多SELECT語句生成多個(gè)結(jié)果包,所以客戶端必須使用支持多結(jié)果包的MySQL客戶端庫。這意味這客戶端必須 使用至少MySQL 4.1以來的近期版本上的客戶端庫。

下面一節(jié)描述用來創(chuàng)建,改變,移除和查詢存儲程序和函數(shù)的語法。

20.2.1.?CREATE PROCEDURECREATE FUNCTION

CREATE PROCEDURE sp_name ([proc_parameter[,...]])

??? [characteristic ...] routine_body

?

CREATE FUNCTION sp_name ([func_parameter[,...]])

??? RETURNS type

??? [characteristic ...] routine_body

??? 

????proc_parameter:

??? [ IN | OUT | INOUT ] param_name type

??? 

????func_parameter:

??? param_name type

?

type:

??? Any valid MySQL data type

?

characteristic:

??? LANGUAGE SQL

? | [NOT] DETERMINISTIC

? | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }

? | SQL SECURITY { DEFINER | INVOKER }

? | COMMENT 'string'

?

routine_body:

??? Valid SQL procedure statement or statements

這些語句創(chuàng)建存儲子程序。要在MySQL 5.1中創(chuàng)建子程序,必須具有CREATE ROUTINE權(quán)限,并且ALTER ROUTINE和EXECUTE權(quán)限被自動授予它的創(chuàng)建者。如果二進(jìn)制日志功能被允許,你也可能需要SUPER權(quán)限,請參閱 20.4節(jié)“存儲子程序和觸發(fā)程序的二進(jìn)制日志功能” 。

默認(rèn)地,子程序與當(dāng)前數(shù)據(jù)庫關(guān)聯(lián)。要明確地把子程序與一個(gè)給定數(shù)據(jù)庫關(guān)聯(lián)起來,可以在創(chuàng)建子程序的時(shí)候指定其名字為db_name.sp_name

如果子程序名和內(nèi)建的SQL函數(shù)名一樣,定義子程序時(shí),你需要在這個(gè)名字和隨后括號中間插入一個(gè)空格,否則發(fā)生語法錯(cuò)誤。當(dāng)你隨后調(diào)用子程序的時(shí)候也要插入。為此,即使有可能出現(xiàn)這種情況,我們還是建議最好避免給你自己的 存儲子程序取與存在的SQL函數(shù)一樣的名字。

由括號包圍的參數(shù)列必須總是存在。如果沒有參數(shù),也該使用一個(gè)空參數(shù)列()。每個(gè)參數(shù) 默認(rèn)都是一個(gè)IN參數(shù)。要指定為其它參數(shù),可在參數(shù)名之前使用關(guān)鍵詞 OUT或INOUT

注意: 指定參數(shù)為IN, OUT, 或INOUT 只對PROCEDURE是合法的。(FUNCTION參數(shù)總是被認(rèn)為是IN參數(shù))

RETURNS字句只能對FUNCTION指定,對函數(shù)而言這是強(qiáng)制的。它用來指定函數(shù)的返回類型,而且函數(shù)體必須包含一個(gè)RETURN value語句。

routine_body 包含合法的SQL過程語句??梢允褂脧?fù)合語句語法,請參閱20.2.7節(jié),“BEGIN ... END復(fù)合語句 。復(fù)合語句可以包含 聲明,循環(huán)和其它控制結(jié)構(gòu)語句。這些語句的語法在本章后免介紹,舉例,請參閱20.2.8節(jié),“DECLARE語句 和20.2.12節(jié),“流程控制構(gòu)造” 。

CREATE FUNCTION語句被用在更早的MySQL版本上支持UDF (自定義函數(shù))。請參閱27.2節(jié),“給MySQL添加新函數(shù)” 。 UDF繼續(xù)被支持,即使現(xiàn)在 有了存儲函數(shù)。UDF會被認(rèn)為一個(gè)外部存儲函數(shù)。然而,不要讓存儲函數(shù)與UDF函數(shù)共享名字空間。

外部存儲程序的框架將在不久的將來引入。這將允許你用SQL之外的語言編寫存儲程序。最可能的是,第一個(gè)被支持語言是PHP,因?yàn)楹诵腜HP引擎很小,線程安全,且可以被方便地嵌入。因?yàn)榭蚣苁枪_的,它希望許多其它語言也能被支持。

如果程序或線程總是對同樣的輸入?yún)?shù)產(chǎn)生同樣的結(jié)果,則被認(rèn)為它是“確定的”,否則就是“非確定”的。如果既沒有給定DETERMINISTIC也沒有給定NOT DETERMINISTIC,默認(rèn)的就是NOT DETERMINISTIC。

為進(jìn)行復(fù)制,使用NOW()函數(shù)(或它的同義詞)或RAND()函數(shù)會不必要地使得一個(gè)子程序非確定。對NOW()而言,二進(jìn)制日志包括時(shí)間戳并被正確復(fù)制。RAND() 只要在一個(gè)子程序被內(nèi)應(yīng)用一次也會被正確復(fù)制。(你可以把子程序執(zhí)行時(shí)間戳和隨機(jī)數(shù)種子認(rèn)為強(qiáng)制輸入,它們在主從上是同樣的。)

當(dāng)前來講,DETERMINISTIC特征被接受,但還沒有被優(yōu)化程序所使用。然而如果二進(jìn)制日志功能被允許了,這個(gè)特征影響到MySQL是否會接受子程序定義。請參閱20.4 節(jié),“存儲子程序和觸發(fā)程序的二進(jìn)制日志功能”

一些特征提供子程序使用數(shù)據(jù)的內(nèi)在信息。CONTAINS SQL表示子程序不包含讀或?qū)憯?shù)據(jù)的語句。NO SQL表示子程序不包含SQL語句。READS SQL DATA表示子程序包含讀數(shù)據(jù)的語句,但不包含寫數(shù)據(jù)的語句。MODIFIES SQL DATA表示子程序包含寫數(shù)據(jù)的語句。如果這些特征沒有明確給定,默認(rèn)的是CONTAINS SQL。

SQL SECURITY特征可以用來指定 子程序該用創(chuàng)建子程序者的許可來執(zhí)行,還是使用調(diào)用者的許可來執(zhí)行。默認(rèn)值是DEFINER。在SQL:2003中者是一個(gè)新特性。創(chuàng)建者或調(diào)用者必須由訪問 子程序關(guān)聯(lián)的數(shù)據(jù)庫的許可。在MySQL 5.1中,必須有EXECUTE權(quán)限才能執(zhí)行子程序。必須擁有這個(gè)權(quán)限的用戶要么是定義者,要么是調(diào)用者,這取決于SQL SECURITY特征是如何設(shè)置的。

MySQL存儲sql_mode系統(tǒng)變量設(shè)置,這個(gè)設(shè)置在子程序被創(chuàng)建的時(shí)候起作用,MySQL總是強(qiáng)制使用這個(gè)設(shè)置來執(zhí)行 子程序。

COMMENT子句是一個(gè)MySQL的擴(kuò)展,它可以被用來描述 存儲程序。這個(gè)信息被SHOW CREATE PROCEDURE和 SHOW CREATE FUNCTION語句來顯示。

MySQL允許子程序包含DDL語句,如CREATE和DROP。MySQL也允許存儲程序(但不是 存儲函數(shù))包含SQL 交互語句,如COMMIT。存儲函數(shù)不可以包含那些做明確的和絕對的提交或者做回滾的語。SQL標(biāo)準(zhǔn)不要求對這些語句的支持,SQL標(biāo)準(zhǔn)聲明每個(gè)DBMS提供商可以決定是否允許支持這些語句。

存儲子程序不能使用LOAD DATA INFILE。

返回結(jié)果包的語句不能被用在存儲函數(shù)種。這包括不使用INTO給變量讀取 列值的SELECT語句,SHOW 語句,及其它諸如EXPLAIN這樣的語句。對于可在函數(shù)定義時(shí)間被決定要返回一個(gè)結(jié)果包的語句,發(fā)生一個(gè)允許從函數(shù)錯(cuò)誤返回結(jié)果包的Not(ER_SP_NO_RETSET_IN_FUNC)。對于只可在運(yùn)行時(shí)決定要返回一個(gè)結(jié)果包的語句, 發(fā)生一個(gè)不能在給定上下文錯(cuò)誤返回結(jié)果包的PROCEDURE %s (ER_SP_BADSELECT)。

下面是一個(gè)使用OUT參數(shù)的簡單的存儲程序的例子。例子為,在 程序被定義的時(shí)候,用mysql客戶端delimiter命令來把語句定界符從 ;變?yōu)?/。這就允許用在 程序體中的;定界符被傳遞到服務(wù)器而不是被mysql自己來解釋。

mysql> delimiter //

?

mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)

??? -> BEGIN

??? ->?? SELECT COUNT(*) INTO param1 FROM t;

??? -> END

??? -> //

Query OK, 0 rows affected (0.00 sec)

?

mysql> delimiter ;

?

mysql> CALL simpleproc(@a);

Query OK, 0 rows affected (0.00 sec)

?

mysql> SELECT @a;

+------+

| @a?? |

+------+

| 3??? |

+------+

1 row in set (0.00 sec)

當(dāng)使用delimiter命令時(shí),你應(yīng)該避免使用反斜杠(\)字符,因?yàn)槟鞘荕ySQL的 轉(zhuǎn)義字符。

下列是一個(gè)例子,一個(gè)采用參數(shù)的函數(shù)使用一個(gè)SQL函數(shù)執(zhí)行一個(gè)操作,并返回結(jié)果:

mysql> delimiter //

?

mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)

??? -> RETURN CONCAT('Hello, ',s,'!');

??? -> //

Query OK, 0 rows affected (0.00 sec)

?

mysql> delimiter ;

?

mysql> SELECT hello('world');

+----------------+

| hello('world') |

+----------------+

| Hello, world!? |

+----------------+

1 row in set (0.00 sec)

如果在存儲函數(shù)中的RETURN語句返回一個(gè)類型不同于在函數(shù)的RETURNS子句中指定類型的值,返回值被強(qiáng)制為恰當(dāng)?shù)念愋?。比如,如果一個(gè)函數(shù)返回一個(gè)ENUM或SET值,但是RETURN語句返回一個(gè)整數(shù),對于SET成員集的相應(yīng)的ENUM成員,從函數(shù)返回的值是字符串。

20.2.2.?ALTER PROCEDUREALTER FUNCTION

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]

?

characteristic:

??? { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }

? | SQL SECURITY { DEFINER | INVOKER }

? | COMMENT 'string'

這個(gè)語句可以被用來改變一個(gè)存儲程序或函數(shù)的特征。在MySQL 5.1中,你必須用ALTER ROUTINE權(quán)限才可用此子程序。這個(gè)權(quán)限被自動授予子程序的創(chuàng)建者。如20.4節(jié),“存儲子程序和觸發(fā)程序的二進(jìn)制日志功能”中所述, 如果二進(jìn)制日志功能被允許了,你可能也需要SUPER權(quán)限。

在ALTER PROCEDURE和ALTER FUNCTION語句中,可以指定超過一個(gè)的改變。

20.2.3.?DROP PROCEDUREDROP FUNCTION

DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name

這個(gè)語句被用來移除一個(gè)存儲程序或函數(shù)。即,從服務(wù)器移除一個(gè)制定的子程序。在MySQL 5.1中,你必須有ALTER ROUTINE權(quán)限才可用此子程序。這個(gè)權(quán)限被自動授予子程序的創(chuàng)建者。

IF EXISTS 子句是一個(gè)MySQL的擴(kuò)展。如果程序或函數(shù)不存儲,它防止發(fā)生錯(cuò)誤。產(chǎn)生一個(gè)可以用SHOW WARNINGS查看的警告。

20.2.4.?SHOW CREATE PROCEDURESHOW CREATE FUNCTION

SHOW CREATE {PROCEDURE | FUNCTION} sp_name

這個(gè)語句是一個(gè)MySQL的擴(kuò)展。類似于SHOW CREATE TABLE,它返回一個(gè)可用來重新創(chuàng)建已命名 子程序的確切字符串。

mysql> SHOW CREATE FUNCTION test.hello\G

*************************** 1. row ***************************

?????? Function: hello

?????? sql_mode:

Create Function: CREATE FUNCTION `test`.`hello`(s CHAR(20)) RETURNS CHAR(50)

RETURN CONCAT('Hello, ',s,'!')

20.2.5.?SHOW PROCEDURE STATUSSHOW FUNCTION STATUS

SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'pattern']

這個(gè)語句是一個(gè)MySQL的擴(kuò)展。它返回子程序的特征,如數(shù)據(jù)庫,名字,類型,創(chuàng)建者及創(chuàng)建和修改日期。如果沒有指定樣式,根據(jù)你使用的語句,所有 存儲程序和所有存儲函數(shù)的信息都被列出。

mysql> SHOW FUNCTION STATUS LIKE 'hello'\G

*************************** 1. row ***************************

?????????? Db: test

???????? Name: hello

???????? Type: FUNCTION

????? Definer: testuser@localhost

???? Modified: 2004-08-03 15:29:37

????? Created: 2004-08-03 15:29:37

Security_type: DEFINER

????? Comment:

你可以從INFORMATION_SCHEMA中的ROUTINES表獲得有關(guān)存儲子程序的信息。請參閱23.1.14節(jié),“INFORMATION_SCHEMA ROUTINES 表 。

20.2.6.?CALL語句

CALL sp_name([parameter[,...]])

CALL語句調(diào)用一個(gè)先前用CREATE PROCEDURE創(chuàng)建的程序。

CALL語句可以用 聲明為OUT或的INOUT參數(shù)的參數(shù)給它的調(diào)用者傳回值。它也“返回”受影響的行數(shù),客戶端程序可以在SQL級別通過調(diào)用ROW_COUNT()函數(shù)獲得這個(gè)數(shù),從C中是調(diào)用the mysql_affected_rows() C API函數(shù)獲得。

20.2.7.?BEGIN ... END復(fù)合語句

[begin_label:] BEGIN

??? [statement_list]

END [end_label]

存儲子程序可以使用BEGIN ... END復(fù)合語句來包含多個(gè)語句。statement_list 代表一個(gè)或多個(gè)語句的列表。statement_list之內(nèi)每個(gè)語句都必須用分號(;)來結(jié)尾。

復(fù)合語句可以被標(biāo)記。除非begin_label存在,否則end_label不能被給出,并且如果二者都存在,他們必須是同樣的。

請注意,可選的[NOT] ATOMIC子句現(xiàn)在還不被支持。這意味著在指令塊的開始沒有交互的存儲點(diǎn)被設(shè)置,并且在上下文中用到的BEGIN子句對當(dāng)前交互動作沒有影響。

使用多重語句需要客戶端能發(fā)送包含語句定界符;的查詢字符串。這個(gè)符號在命令行客戶端被用delimiter命令來處理。改變查詢結(jié)尾定界符;(比如改變?yōu)?/)使得; 可被用在子程序體中。

20.2.8.?DECLARE語句

DECLARE語句被用來把不同項(xiàng)目局域到一個(gè) 子程序:局部變量(請參閱20.2.9節(jié),“存儲程序中的變量”),條件和 處理程序(請參閱20.2.10節(jié),“條件和處理程序”) 及光標(biāo)(請參閱20.2.11節(jié),“光標(biāo)”)。SIGNAL和RESIGNAL語句當(dāng)前還不被支持。

DECLARE僅被用在BEGIN ... END復(fù)合語句里,并且必須在復(fù)合語句的開頭,在任何其它語句之前。

光標(biāo)必須在聲明處理程序之前被聲明,并且變量和條件必須在聲明光標(biāo)或處理程序之前被聲明。

20.2.9.?存儲程序中的變量

20.2.9.1. DECLARE局部變量

20.2.9.2. 變量SET語句

20.2.9.3. SELECT ... INTO語句

你可以在子程序中聲明并使用變量。

20.2.9.1.?DECLARE局部變量

DECLARE var_name[,...] type [DEFAULT value]

這個(gè)語句被用來聲明局部變量。要給變量提供一個(gè)默認(rèn)值,請包含一個(gè)DEFAULT子句。值可以被指定為一個(gè)表達(dá)式,不需要為一個(gè)常數(shù)。如果沒有DEFAULT子句,初始值為NULL。

局部變量的作用范圍在它被聲明的BEGIN ... END塊內(nèi)。它可以被用在嵌套的塊中,除了那些用相同名字 聲明變量的塊。

20.2.9.2. 變量SET語句

SET var_name = expr [, var_name = expr] ...

在存儲程序中的SET語句是一般SET語句的擴(kuò)展版本。被參考變量可能是子程序內(nèi)聲明的變量,或者是全局服務(wù)器變量。

在存儲程序中的SET語句作為預(yù)先存在的SET語法的一部分來實(shí)現(xiàn)。這允許SET a=x, b=y, ...這樣的擴(kuò)展語法。其中不同的變量類型(局域 聲明變量及全局和集體變量)可以被混合起來。這也允許把局部變量和一些只對系統(tǒng)變量有意義的選項(xiàng)合并起來。在那種情況下,此選項(xiàng)被識別,但是被忽略了。

20.2.9.3.?SELECT ... INTO語句

SELECT col_name[,...] INTO var_name[,...] table_expr

這個(gè)SELECT語法把選定的列直接存儲到變量。因此,只有單一的行可以被取回。

SELECT id,data INTO x,y FROM test.t1 LIMIT 1;

注意,用戶變量名在MySQL 5.1中是對大小寫不敏感的。請參閱9.3節(jié),“用戶變量”。

重要: SQL變量名不能和列名一樣。如果SELECT ... INTO這樣的SQL語句包含一個(gè)對列的參考,并包含一個(gè)與列相同名字的 局部變量,MySQL當(dāng)前把參考解釋為一個(gè)變量的名字。例如,在下面的語句中,xname 被解釋為到xname variable 的參考而不是到xname column的:

CREATE PROCEDURE sp1 (x VARCHAR(5))

? BEGIN

??? DECLARE xname VARCHAR(5) DEFAULT 'bob';

??? DECLARE newname VARCHAR(5);

??? DECLARE xid INT;

??? 

????SELECT xname,id INTO newname,xid 

??????FROM table1 WHERE xname = xname;

??? SELECT newname;

? END;

當(dāng)這個(gè)程序被調(diào)用的時(shí)候,無論table.xname列的值是什么,變量newname將返回值‘bob’。

請參閱I.1節(jié),“存儲子程序和觸發(fā)程序的限制”

20.2.10.?條件和處理程序

20.2.10.1. DECLARE條件

20.2.10.2. DECLARE處理程序

特定條件需要特定處理。這些條件可以聯(lián)系到錯(cuò)誤,以及子程序中的一般流程控制。

20.2.10.1.?DECLARE條件

DECLARE condition_name CONDITION FOR condition_value

?

condition_value:

??? SQLSTATE [VALUE] sqlstate_value

? | mysql_error_code

這個(gè)語句指定需要特殊處理的條件。它將一個(gè)名字和指定的錯(cuò)誤條件關(guān)聯(lián)起來。這個(gè)名字可以隨后被用在DECLARE HANDLER語句中。請參閱20.2.10.2節(jié),“DECLARE處理程序 。

除了SQLSTATE值,也支持MySQL錯(cuò)誤代碼。

20.2.10.2.?DECLARE處理程序

DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement

?

handler_type:

??? CONTINUE

? | EXIT

? | UNDO

?

condition_value:

??? SQLSTATE [VALUE] sqlstate_value

? | condition_name

? | SQLWARNING

? | NOT FOUND

? | SQLEXCEPTION

? | mysql_error_code

這個(gè)語句指定每個(gè)可以處理一個(gè)或多個(gè)條件的處理程序。如果產(chǎn)生一個(gè)或多個(gè)條件,指定的語句被執(zhí)行。

對一個(gè)CONTINUE處理程序,當(dāng)前子程序的執(zhí)行在執(zhí)行 處理程序語句之后繼續(xù)。對于EXIT處理程序,當(dāng)前BEGIN...END復(fù)合語句的執(zhí)行被終止。UNDO 處理程序類型語句還不被支持。

·???????? SQLWARNING是對所有以01開頭的SQLSTATE代碼的速記。

·???????? NOT FOUND是對所有以02開頭的SQLSTATE代碼的速記。

·???????? SQLEXCEPTION是對所有沒有被SQLWARNING或NOT FOUND捕獲的SQLSTATE代碼的速記。

除了SQLSTATE值,MySQL錯(cuò)誤代碼也不被支持。

例如:

mysql> CREATE TABLE test.t (s1 int,primary key (s1));

Query OK, 0 rows affected (0.00 sec)

?

mysql> delimiter //

?

mysql> CREATE PROCEDURE handlerdemo ()

??? -> BEGIN

??? ->?? DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;

??? ->?? SET @x = 1;

??? ->?? INSERT INTO test.t VALUES (1);

??? ->?? SET @x = 2;

??? ->?? INSERT INTO test.t VALUES (1);

??? ->?? SET @x = 3;

??? -> END;

??? -> //

Query OK, 0 rows affected (0.00 sec)

?

mysql> CALL handlerdemo()//

Query OK, 0 rows affected (0.00 sec)

?

mysql> SELECT @x//

??? +------+

??? | @x?? |

??? +------+

??? | 3??? |

??? +------+

??? 1 row in set (0.00 sec)

注意到,@x是3,這表明MySQL被執(zhí)行到程序的末尾。如果DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; 這一行不在,第二個(gè)INSERT因PRIMARY KEY強(qiáng)制而失敗之后,MySQL可能已經(jīng)采取 默認(rèn)(EXIT)路徑,并且SELECT @x可能已經(jīng)返回2。

20.2.11.?光標(biāo)

20.2.11.1.聲明光標(biāo)

20.2.11.2. 光標(biāo)OPEN語句

20.2.11.3. 光標(biāo)FETCH語句

20.2.11.4. 光標(biāo)CLOSE語句

簡單光標(biāo)在存儲程序和函數(shù)內(nèi)被支持。語法如同在嵌入的SQL中。光標(biāo)當(dāng)前是不敏感的,只讀的及不滾動的。不敏感意為服務(wù)器可以活不可以復(fù)制它的結(jié)果表。

光標(biāo)必須在聲明處理程序之前被聲明,并且變量和條件必須在聲明光標(biāo)或處理程序之前被聲明。

例如:

CREATE PROCEDURE curdemo()

BEGIN

? DECLARE done INT DEFAULT 0;

? DECLARE a CHAR(16);

? DECLARE b,c INT;

? DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;

? DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;

? DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

?

? OPEN cur1;

? OPEN cur2;

?

? REPEAT

??? FETCH cur1 INTO a, b;

??? FETCH cur2 INTO c;

??? IF NOT done THEN

?????? IF b < c THEN

????????? INSERT INTO test.t3 VALUES (a,b);

?????? ELSE

????????? INSERT INTO test.t3 VALUES (a,c);

?????? END IF;

??? END IF;

? UNTIL done END REPEAT;

?

? CLOSE cur1;

? CLOSE cur2;

END

20.2.11.1.聲明光標(biāo)

DECLARE cursor_name CURSOR FOR select_statement

這個(gè)語句聲明一個(gè)光標(biāo)。也可以在子程序中定義多個(gè)光標(biāo),但是一個(gè)塊中的每一個(gè)光標(biāo)必須有唯一的名字。

SELECT語句不能有INTO子句。

20.2.11.2.?光標(biāo)OPEN語句

OPEN cursor_name

這個(gè)語句打開先前聲明的光標(biāo)。

20.2.11.3.?光標(biāo)FETCH語句

FETCH cursor_name INTO var_name [, var_name] ...

這個(gè)語句用指定的打開光標(biāo)讀取下一行(如果有下一行的話),并且前進(jìn)光標(biāo)指針。

20.2.11.4.?光標(biāo)CLOSE語句

CLOSE cursor_name

這個(gè)語句關(guān)閉先前打開的光標(biāo)。

如果未被明確地關(guān)閉,光標(biāo)在它被聲明的復(fù)合語句的末尾被關(guān)閉。

20.2.12. 流程控制構(gòu)造

20.2.12.1. IF語句

20.2.12.2. CASE語句

20.2.12.3. LOOP語句

20.2.12.4. LEAVE語句

20.2.12.5. ITERATE語句

20.2.12.6. REPEAT語句

20.2.12.7. WHILE語句

IF, CASE, LOOP, WHILE, ITERATE, 及 LEAVE 構(gòu)造被完全實(shí)現(xiàn)。

這些構(gòu)造可能每個(gè)包含要么一個(gè)單獨(dú)語句,要么是使用BEGIN ... END復(fù)合語句的一塊語句。構(gòu)造可以被嵌套。

目前還不支持FOR循環(huán)。

20.2.12.1.?IF語句

IF search_condition THEN statement_list

??? [ELSEIF search_condition THEN statement_list] ...

??? [ELSE statement_list]

END IF

IF實(shí)現(xiàn)了一個(gè)基本的條件構(gòu)造。如果search_condition求值為真,相應(yīng)的SQL語句列表被執(zhí)行。如果沒有search_condition匹配,在ELSE子句里的語句列表被執(zhí)行。statement_list可以包括一個(gè)或多個(gè)語句。

請注意,也有一個(gè)IF() 函數(shù),它不同于這里描述的IF語句。請參閱12.2節(jié),“控制流程函數(shù)”。

20.2.12.2.?CASE語句

CASE case_value

??? WHEN when_value THEN statement_list

??? [WHEN when_value THEN statement_list] ...

??? [ELSE statement_list]

END CASE

Or:

CASE

??? WHEN search_condition THEN statement_list

??? [WHEN search_condition THEN statement_list] ...

??? [ELSE statement_list]

END CASE

存儲程序的CASE語句實(shí)現(xiàn)一個(gè)復(fù)雜的條件構(gòu)造。如果search_condition 求值為真,相應(yīng)的SQL被執(zhí)行。如果沒有搜索條件匹配,在ELSE子句里的語句被執(zhí)行。

注意:這里介紹的用在 存儲程序里的CASE語句與12.2節(jié),“控制流程函數(shù)”里描述的SQL CASE表達(dá)式的CASE語句有輕微不同。這里的CASE語句不能有ELSE NULL子句,并且用END CASE替代END來終止。

20.2.12.3.?LOOP語句

[begin_label:] LOOP

??? statement_list

END LOOP [end_label]

LOOP允許某特定語句或語句群的重復(fù)執(zhí)行,實(shí)現(xiàn)一個(gè)簡單的循環(huán)構(gòu)造。在循環(huán)內(nèi)的語句一直重復(fù)直循環(huán)被退出,退出通常伴隨著一個(gè)LEAVE 語句。

LOOP語句可以被標(biāo)注。除非begin_label存在,否則end_label不能被給出,并且如果兩者都出現(xiàn),它們必須是同樣的。

20.2.12.4.?LEAVE語句

LEAVE label

這個(gè)語句被用來退出任何被標(biāo)注的流程控制構(gòu)造。它和BEGIN ... END或循環(huán)一起被使用。

20.2.12.5.?ITERATE語句

ITERATE label

ITERATE只可以出現(xiàn)在LOOP, REPEAT, 和WHILE語句內(nèi)。ITERATE意思為:“再次循環(huán)?!?

例如:

CREATE PROCEDURE doiterate(p1 INT)

BEGIN

? label1: LOOP

??? SET p1 = p1 + 1;

??? IF p1 < 10 THEN ITERATE label1; END IF;

??? LEAVE label1;

? END LOOP label1;

? SET @x = p1;

END

20.2.12.6.?REPEAT語句

[begin_label:] REPEAT

??? statement_list

UNTIL search_condition

END REPEAT [end_label]

REPEAT語句內(nèi)的語句或語句群被重復(fù),直至search_condition 為真。

REPEAT 語句可以被標(biāo)注。 除非begin_label也存在,end_label才能被用,如果兩者都存在,它們必須是一樣的。

例如

mysql> delimiter //

?

mysql> CREATE PROCEDURE dorepeat(p1 INT)

??? -> BEGIN

??? ->?? SET @x = 0;

??? ->?? REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;

??? -> END

??? -> //

Query OK, 0 rows affected (0.00 sec)

?

mysql> CALL dorepeat(1000)//

Query OK, 0 rows affected (0.00 sec)

?

mysql> SELECT @x//

+------+

| @x?? |

+------+

| 1001 |

+------+

1 row in set (0.00 sec)

20.2.12.7.?WHILE語句

[begin_label:] WHILE search_condition DO

??? statement_list

END WHILE [end_label]

WHILE語句內(nèi)的語句或語句群被重復(fù),直至search_condition 為真。

WHILE語句可以被標(biāo)注。 除非begin_label也存在,end_label才能被用,如果兩者都存在,它們必須是一樣的。

例如:

CREATE PROCEDURE dowhile()

BEGIN

? DECLARE v1 INT DEFAULT 5;

?

? WHILE v1 > 0 DO

??? ...

??? SET v1 = v1 - 1;

? END WHILE;

END

20.3.?存儲程序 、函數(shù)、觸發(fā)程序及復(fù)制:常見問題

  • MySQL 5.1存儲程序和函數(shù)對復(fù)制起作用嗎??

    是的,在存儲程序和函數(shù)中被執(zhí)行標(biāo)準(zhǔn)行為被從主MySQL服務(wù)器復(fù)制到從服務(wù)器。有少數(shù)限制,它們在20.4節(jié),“存儲子程序和 觸發(fā)程序二進(jìn)制日志功能”中詳述。

  • 在主服務(wù)器上創(chuàng)建的存儲程序和函數(shù)可以被復(fù)制到從服務(wù)器上么?

    是的,通過一般DDL語句執(zhí)行的存儲程序和函數(shù),其在主服務(wù)器上的創(chuàng)建被復(fù)制到從服務(wù)器,所以目標(biāo)將存在兩個(gè)服務(wù)器上。對存儲程序和函數(shù)的ALTER 和DROP語句也被復(fù)制。

  • 行為如何在已復(fù)制的存儲程序和函數(shù)里發(fā)生?

    MySQL紀(jì)錄每個(gè)發(fā)生在存儲程序和函數(shù)里的DML事件,并復(fù)制這些單獨(dú)的行為到從服務(wù)器。執(zhí)行存儲程序和函數(shù)的切實(shí)調(diào)用不被復(fù)制。

  • 對一起使用存儲程序,函數(shù)和復(fù)制有什么特別的安全要求么?

    是的,因?yàn)橐粋€(gè)從服務(wù)器有權(quán)限來執(zhí)行任何讀自主服務(wù)器的二進(jìn)制日志的語句,指定的安全約束因與復(fù)制一起使用的存儲程序和函數(shù)而存在。如果復(fù)制或二進(jìn)制日志大體上是激活的(為point-in-time恢復(fù)的目的),那么MySQL DBA 有兩個(gè)安全選項(xiàng)可選:

    • 任何想創(chuàng)建存儲程序的用戶必須被賦予SUPER權(quán)限。
    • 作為選擇,一個(gè)DBA可以設(shè)置log_bin_trust_routine_creators系統(tǒng)變量為1,它將會允許有標(biāo)準(zhǔn)CREATE ROUTINE權(quán)限的人來創(chuàng)建一個(gè)存儲程序和函數(shù)。
    ?
  • 對復(fù)制存儲程序和函數(shù)的行為有什么限制?

    嵌入到存儲程序中的不確定(隨機(jī))或時(shí)基行不能適當(dāng)?shù)貜?fù)制。隨機(jī)產(chǎn)生的結(jié)果,僅因其本性,是你可預(yù)測的和不能被確實(shí)克隆的。因此,復(fù)制到從服務(wù)器的隨機(jī)行為將不會鏡像那些產(chǎn)生在主服務(wù)器上的。注意, 聲明存儲程序或函數(shù)為DETERMINISTIC或者在log_bin_trust_routine_creators中設(shè)置系統(tǒng)變量為0 將會允許隨即值操作被調(diào)用。

    此外,時(shí)基行為不能在從服務(wù)器上重新產(chǎn)生,因?yàn)樵诖鎯Τ绦蛑型ㄟ^對復(fù)制使用的二進(jìn)制日志來計(jì)時(shí)這樣的時(shí)基行為是不可重新產(chǎn)生的,因?yàn)樵摱M(jìn)制日志僅紀(jì)錄DML事件且不包括計(jì)時(shí)約束。

    最后,在大型DML行為(如大批插入)中非交互表發(fā)生錯(cuò)誤,該非交互表可能經(jīng)歷復(fù)制,在復(fù)制版的非交互表中主服務(wù)器可以被部分地從DML行為更新。但是因?yàn)榘l(fā)生的那個(gè)錯(cuò)誤,對從服務(wù)器沒有更新。 對函數(shù)的DML行為,工作區(qū)將被用IGNORE關(guān)鍵詞來執(zhí)行,以便于在主服務(wù)器上導(dǎo)致錯(cuò)誤的更新被忽略,并且不會導(dǎo)致錯(cuò)誤的更新被復(fù)制到從服務(wù)器。

    ?

  • 上述的限制會影響MySQL作 point-in-time恢復(fù)的能力嗎?

    影響復(fù)制的同一限制會影響point-in-time恢復(fù)。

  • ?MySQL要做什么來改正前述的限制呢?

    將來發(fā)行的MySQL預(yù)期有一個(gè)功能去選擇復(fù)制該如何被處理:

    • ?基于語句的復(fù)制(當(dāng)前實(shí)現(xiàn))。
    • 行級別復(fù)制(它將解決所有早先描述的限制)。
  • 觸發(fā)程序?qū)?fù)制起作用么?

    MySQL 5.1中的觸發(fā)程序和復(fù)制象在大多數(shù)其它數(shù)據(jù)庫引擎中一樣工作,在那些引擎中,通過觸發(fā)程序在主服務(wù)器上執(zhí)行的行為不被復(fù)制到從服務(wù)器。取而代之的是,位于主MySQL服務(wù)器的表中的 觸發(fā)程序需要在那些存在于任何MySQL從服務(wù)器上的表內(nèi)被創(chuàng)建,以便于觸發(fā)程序可以也可以在從服務(wù)器上被激活。

    ?

  • ?一個(gè)行為如何通過從主服務(wù)器上復(fù)制到從服務(wù)器上的觸發(fā)程序來執(zhí)行呢?

    首先,主服務(wù)器上的觸發(fā)程序必須在從服務(wù)器上重建。一旦重建了,復(fù)制流程就象其它參與到復(fù)制中的標(biāo)準(zhǔn)DML語句一樣工作。例如:考慮一個(gè)已經(jīng)插入觸發(fā)程序AFTER的EMP表,它位于主MySQL服務(wù)器上。同樣的EMP表和AFTER插入 觸發(fā)程序也存在于從服務(wù)器上。復(fù)制流程可能是:

1.??? 對EMP做一個(gè)INSERT語句。

2.???EMP上的AFTER觸發(fā)程序激活。

3.??? INSERT語句被寫進(jìn)二進(jìn)制日志。

4.??? 從服務(wù)器上的復(fù)制拾起INSERT語句給EMP表,并在從服務(wù)器上執(zhí)行它。

5.??? 位于從服務(wù)器EMP上的AFTER觸發(fā)程序激活。

20.4.?存儲子程序和觸發(fā)程序的二進(jìn)制日志功能

,這一節(jié)介紹MySQL 5.1如何考慮二進(jìn)制日志功能來處理存儲子程序(程序和函數(shù)) 。這一節(jié)也適用于觸發(fā)程序。

二進(jìn)制日志包含修改數(shù)據(jù)庫內(nèi)容的SQL語句的信息。這個(gè)信息以描述修改的事件的形式保存起來。

二進(jìn)制日志有兩個(gè)重要目的:

·???????? 復(fù)制的基礎(chǔ)是主服務(wù)器發(fā)送包含在二進(jìn)制日志里的事件到從服務(wù)器,從服務(wù)器執(zhí)行這些事件來造成與對主服務(wù)器造成的同樣的數(shù)據(jù)改變,請參閱6.2節(jié),“復(fù)制概述”。

·???????? 特定的數(shù)據(jù)恢復(fù)操作許要使用二進(jìn)制日志。備份的文件被恢復(fù)之后,備份后紀(jì)錄的二進(jìn)制日志里的事件被重新執(zhí)行。這些事件把數(shù)據(jù)庫帶從備份點(diǎn)的日子帶到當(dāng)前。請參閱5.9.2.2節(jié),“使用備份恢復(fù)”。

MySQL中,以存儲子程序的二進(jìn)制日志功能引發(fā)了很多問題,這些在下面討論中列出,作為參考信息。

除了要另外注意的之外,這些談?wù)摷僭O(shè)你已經(jīng)通過用--log-bin選項(xiàng)啟動服務(wù)器允許了二進(jìn)制日志功能。(如果二進(jìn)制日志功能不被允許,復(fù)制將不可能,為數(shù)據(jù)恢復(fù)的二進(jìn)制日志也不存在。)請參閱5.11.3節(jié),“二進(jìn)制日志”。

對存儲子程序語句的二進(jìn)制日志功能的特征在下面列表中描述。一些條目指出你應(yīng)該注意到的問題。但是在一些情況下,有你可以更改的婦五七設(shè)置或你可以用來處理它們的工作區(qū)。

·???????? CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE,和ALTER FUNCTION 語句被寫進(jìn)二進(jìn)制日志,CALL, DROP PROCEDURE, 和DROP FUNCTION 也一樣。

盡管如此,對復(fù)制有一個(gè)安全暗示:要?jiǎng)?chuàng)建一個(gè)子程序,用戶必須有CREATE ROUTINE權(quán)限,但有這個(gè)權(quán)限的用戶不能寫一個(gè) 子程序在從服務(wù)器上執(zhí)行任何操作。因?yàn)樵趶姆?wù)器上的SQL線程用完全權(quán)限來運(yùn)行。例如,如果主服務(wù)器和從服務(wù)器分別有服務(wù)器ID值1和2,在主服務(wù)器上的用戶可能創(chuàng)建并調(diào)用如下一個(gè) 程序:

mysql> delimiter //

mysql> CREATE PROCEDURE mysp ()

??? -> BEGIN

??? ->?? IF @@server_id=2 THEN DROP DATABASE accounting; END IF;

??? -> END;

??? -> //

mysql> delimiter ;

mysql> CALL mysp();

CREATE PROCEDURE和CALL語句將被寫進(jìn)二進(jìn)制日志,所以從服務(wù)器將執(zhí)行它們。因?yàn)閺腟QL線程有完全權(quán)限,它將移除accounting數(shù)據(jù)庫。

要使允許二進(jìn)制日志功能的服務(wù)器避免這個(gè)危險(xiǎn),MySQL 5.1已經(jīng)要求 存儲程序和函數(shù)的創(chuàng)建者除了通常需要的CREATE ROUTINE的權(quán)限外,還必須有SUPER 權(quán)限。類似地,要使用ALTER PROCEDURE或ALTER FUNCTION,除了ALTER ROUTINE權(quán)限外你必須有SUPER權(quán)限。沒有SUPER權(quán)限,將會發(fā)生一個(gè)錯(cuò)誤:

ERROR 1419 (HY000): You do not have the SUPER privilege and

binary logging is enabled (you *might* want to use the less safe

log_bin_trust_routine_creators variable)

你可能不想強(qiáng)制要求子程序創(chuàng)建者必須有SUPER權(quán)限。例如,你系統(tǒng)上所有有CREATE ROUTINE權(quán)限的用戶可能是有經(jīng)驗(yàn)的應(yīng)用程序開發(fā)者。要禁止掉對SUPER權(quán)限的要求,設(shè)置log_bin_trust_routine_creators 全局系統(tǒng)變量為1。默認(rèn)地,這個(gè)變量值為0,但你可以象這樣改變這樣:

mysql> SET GLOBAL log_bin_trust_routine_creators = 1;

你也可以在啟動服務(wù)器之時(shí)用--log-bin-trust-routine-creators選項(xiàng)來設(shè)置允許這個(gè)變量。

如果二進(jìn)制日志功能不被允許,log_bin_trust_routine_creators 沒有被用上,子程序創(chuàng)建需要SUPER權(quán)限。

·???????? 一個(gè)執(zhí)行更新的非確定子程序是不可重復(fù)的,它能有兩個(gè)不如意的影響:

o??????? 它會使得從服務(wù)器不同于主服務(wù)器

-??????? 恢復(fù)的數(shù)據(jù)與原始數(shù)據(jù)不同。

要解決這些問題,MySQL強(qiáng)制做下面要求:在主服務(wù)器上,除非子程序被聲明為確定性的或者不更改數(shù)據(jù),否則創(chuàng)建或者替換子程序?qū)⒈痪芙^。這意味著當(dāng)你創(chuàng)建一個(gè)子程序的時(shí)候,你必須要么聲明它是確定性的,要么它不改變數(shù)據(jù)。兩套子程序特征在這里適用:

-??????? DETERMINISTIC和NOT DETERMINISTIC指出一個(gè)子程序是否對給定的輸入總是產(chǎn)生同樣的結(jié)果。如果沒有給定任一特征,默認(rèn)是NOT DETERMINISTIC,所以你必須明確指定DETERMINISTIC來 聲明一個(gè) 子程序是確定性的。

使用NOW() 函數(shù)(或它的同義)或者RAND() 函數(shù)不是必要地使也一個(gè)子程序非確定性。對NOW()而言,二進(jìn)制日志包括時(shí)間戳并正確復(fù)制。RAND()只要在一個(gè) 子程序內(nèi)被調(diào)用一次也可以正確復(fù)制。(你可以認(rèn)為子程序執(zhí)行時(shí)間戳和隨機(jī)數(shù)種子作為毫無疑問地輸入,它們在主服務(wù)器和從服務(wù)器上是一樣的。)

-??????? CONTAINS SQL, NO SQL, READS SQL DATA, 和 MODIFIES SQL數(shù)據(jù)提供子程序是讀還是寫數(shù)據(jù)的信息。無論NO SQL 還是READS SQL DATA i都指出,子程序沒有改變數(shù)據(jù),但你必須明白地指明這些中的一個(gè),因?yàn)槿绻魏芜@些特征沒有被給出, 默認(rèn)的特征是CONTAINS SQL。

默認(rèn)地,要一個(gè)CREATE PROCEDURE 或 CREATE FUNCTION 語句被接受,DETERMINISTIC 或 NO SQL與READS SQL DATA 中的一個(gè)必須明白地指定,否則會產(chǎn)生如下錯(cuò)誤:

ERROR 1418 (HY000): This routine has none of DETERMINISTIC, NO SQL,

or READS SQL DATA in its declaration and binary logging is enabled

(you *might* want to use the less safe log_bin_trust_routine_creators

variable)

如果設(shè)置log_bin_trust_routine_creators 為1, 移除對子程序必須是確定的或不修改數(shù)據(jù)的要求。

注意,子程序本性的評估是基于創(chuàng)建者的“誠實(shí)度” :MySQL不檢查聲明為確定性的子程序是否不含產(chǎn)生非確定性結(jié)果的語句。

·???????? 如果子程序返回?zé)o錯(cuò),CALL語句被寫進(jìn)二進(jìn)制日志,否則就不寫。當(dāng)一個(gè)子程序修改數(shù)據(jù)失敗了,你會得到這樣的警告:

·??????????????? ERROR 1417 (HY000): A routine failed and has neither NO SQL nor

·??????????????? READS SQL DATA in its declaration and binary logging is enabled; if

·??????????????? non-transactional tables were updated, the binary log will miss their

·??????????????? changes

這個(gè)記日志行為潛在地導(dǎo)致問題.如果一個(gè)子程序部分地修改一個(gè)非交互表(比如一個(gè)MyISAM表able)并且返回一個(gè)錯(cuò)誤,二進(jìn)制日志將反映這些變化。要防止這種情況,你應(yīng)該在 子程序中使用交互表并且在交互動作內(nèi)修改表。

在一個(gè)子程序內(nèi),如果你在INSERT, DELETE, 或者UPDATE里使用IGNORE關(guān)鍵詞來忽略錯(cuò)誤,可能發(fā)生一個(gè)部分更新,但沒有錯(cuò)誤產(chǎn)生。這樣的語句被記錄日志,且正常復(fù)制。

·???????? 如果一個(gè)存儲函數(shù)在一個(gè)如SELECT這樣不修改數(shù)據(jù)的語句內(nèi)被調(diào)用,即使函數(shù)本身更改數(shù)據(jù),函數(shù)的執(zhí)行也將不被寫進(jìn)二進(jìn)制日志里。這個(gè)記錄日志的行為潛在地導(dǎo)致問題。假設(shè)函數(shù)myfunc()如下定義:

·??????????????? CREATE FUNCTION myfunc () RETURNS INT

·??????????????? BEGIN

·??????????????? ??INSERT INTO t (i) VALUES(1);

·??????????????? ??RETURN 0;

·??????????????? END;

按照上面定義,下面的語句修改表t,因?yàn)閙yfunc()修改表t, 但是語句不被寫進(jìn)二進(jìn)制日志,因?yàn)樗且粋€(gè)SELECT語句:

SELECT myfunc();

對這個(gè)問題的工作區(qū)將調(diào)用在做更新的語句里做更新的函數(shù)。注意,雖然DO語句有時(shí)為了其估算表達(dá)式的副效應(yīng)而被執(zhí)行,DO在這里不是一個(gè)工作區(qū),因?yàn)樗槐粚戇M(jìn)二進(jìn)制日志。

·???????? 在一個(gè)子程序內(nèi)執(zhí)行的語句不被寫進(jìn)二進(jìn)制日志。假如你發(fā)布下列語句:

·??????????????? CREATE PROCEDURE mysp INSERT INTO t VALUES(1);

·??????????????? CALL mysp;

對于這個(gè)例子來說,CREATE PROCEDURE 和CALL語句出現(xiàn)在二進(jìn)制日志里,但I(xiàn)NSERT語句并未出現(xiàn)。

·???????? 在從服務(wù)器上,當(dāng)決定復(fù)制哪個(gè)來自主服務(wù)器的事件時(shí),下列限制被應(yīng)用:--replicate-*-table規(guī)則不適用于CALL語句或子程序內(nèi)的語句:在這些情況下,總是返回“復(fù)制!”

觸發(fā)程序類似于存儲函數(shù),所以前述的評論也適用于觸發(fā)程序,除了下列情況: CREATE TRIGGER沒有可選的DETERMINISTIC特征,所以觸發(fā)程序被假定為總是確定性的。然而,這個(gè)假設(shè)在一些情況下是非法的。比如,UUID()函數(shù)是非確定性的(不能復(fù)制)。你應(yīng)該小心在 觸發(fā)程序中使用這個(gè)函數(shù)。

觸發(fā)程序目前不能更新表,但是在將來會支持。因?yàn)檫@個(gè)原因,如果你沒有SUPER權(quán)限且log_bin_trust_routine_creators 被設(shè)為0,得到的錯(cuò)誤信息類似于存儲子程序與CREATE TRIGGER產(chǎn)生的錯(cuò)誤信息。

在本節(jié)中敘述的問題來自發(fā)生在SQL語句級別的二進(jìn)制日志記錄的事實(shí)。未來發(fā)行的MySQL期望能實(shí)現(xiàn)行級的二進(jìn)制日志記錄,記錄發(fā)生在更 細(xì)致的級別并且指出哪個(gè)改變作為執(zhí)行SQL的結(jié)果對單個(gè)記錄而做。


這是MySQL參考手冊的翻譯版本,關(guān)于MySQL參考手冊,請?jiān)L問dev.mysql.com。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。


?

?

上一篇: 下一篇: