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

directory search
目錄 前言 1. 一般信息 1.1. 關(guān)于本手冊(cè) 1.2. 本手冊(cè)采用的慣例 1.3. MySQL AB概述 1.4. MySQL數(shù)據(jù)庫(kù)管理系統(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ù)庫(kù)管理系統(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對(duì)標(biāo)準(zhǔn)SQL的擴(kuò)展 1.8.5. MySQL與標(biāo)準(zhǔn)SQL的差別 1.8.6. MySQL處理約束的方式 2. 安裝MySQL 2.1. 一般安裝問(wèn)題 2.1.1. MySQL支持的操作系統(tǒng) 2.1.2. 選擇要安裝的MySQL分發(fā)版 2.1.3. 怎樣獲得MySQL 2.1.4. 通過(guò)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. 用自動(dòng)安裝器安裝MySQL 2.3.4. 使用MySQL安裝向?qū)?/a> 2.3.5. 使用配置向?qū)?/a> 2.3.6. 通過(guò)非安裝Zip文件安裝MySQL 2.3.7. 提取安裝檔案文件 2.3.8. 創(chuàng)建選項(xiàng)文件 2.3.9. 選擇MySQL服務(wù)器類型 2.3.10. 首次啟動(dòng)服務(wù)器 2.3.11. 從Windows命令行啟動(dòng)MySQL 2.3.12. 以Windows服務(wù)方式啟動(dòng)MySQL 2.3.13. 測(cè)試MySQL安裝 2.3.14. 在Windows環(huán)境下對(duì)MySQL安裝的故障診斷與排除 2.3.15. 在Windows下升級(jí)MySQL 2.3.16. Windows版MySQL同Unix版MySQL對(duì)比 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編譯問(wèn)題 2.8.5. MIT-pthreads注意事項(xiàng) 2.8.6. 在Windows下從源碼安裝MySQL 2.8.7. 在Windows下編譯MySQL客戶端 2.9. 安裝后的設(shè)置和測(cè)試 2.9.1. Windows下安裝后的過(guò)程 2.9.2. Unix下安裝后的過(guò)程 2.9.3. 使初始MySQL賬戶安全 2.10. 升級(jí)MySQL 2.10.1. 從5.0版升級(jí) 2.10.2. 升級(jí)授權(quán)表 2.10.3. 將MySQL數(shù)據(jù)庫(kù)拷貝到另一臺(tái)機(jī)器 2.11. 降級(jí)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接口的問(wèn)題 3. 教程 3.1. 連接與斷開服務(wù)器 3.2. 輸入查詢 3.3. 創(chuàng)建并使用數(shù)據(jù)庫(kù) 3.3.1. 創(chuàng)建并選擇數(shù)據(jù)庫(kù) 3.3.2. 創(chuàng)建表 3.3.3. 將數(shù)據(jù)裝入表中 3.3.4. 從表檢索信息 3.4. 獲得數(shù)據(jù)庫(kù)和表的信息 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ì)算訪問(wèn)量 3.6.9. 使用AUTO_INCREMENT 3.7. 孿生項(xiàng)目的查詢 3.7.1. 查找所有未分發(fā)的孿生項(xiàng) 3.7.2. 顯示孿生對(duì)狀態(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ù)庫(kù)管理 5.1. MySQL服務(wù)器和服務(wù)器啟動(dòng)腳本 5.1.1. 服務(wù)器端腳本和實(shí)用工具概述 5.1.2. mysqld-max擴(kuò)展MySQL服務(wù)器 5.1.3. mysqld_safe:MySQL服務(wù)器啟動(dòng)腳本 5.1.4. mysql.server:MySQL服務(wù)器啟動(dòng)腳本 5.1.5. mysqld_multi:管理多個(gè)MySQL服務(wù)器的程序 5.2. mysqlmanager:MySQL實(shí)例管理器 5.2.1. 用MySQL實(shí)例管理器啟動(dòng)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í)例管理器識(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:升級(jí)MySQL系統(tǒng)表 5.5. MySQL服務(wù)器關(guān)機(jī)進(jìn)程 5.6. 一般安全問(wèn)題 5.6.1. 通用安全指南 5.6.2. 使MySQL在攻擊者面前保持安全 5.6.3. Mysqld安全相關(guān)啟動(dòng)選項(xiàng) 5.6.4. LOAD DATA LOCAL安全問(wèn)題 5.7. MySQL訪問(wèn)權(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. 訪問(wèn)控制 5.7.6. 訪問(wèn)控制 5.7.7. 權(quán)限更改何時(shí)生效 5.7.8. 拒絕訪問(wèn)錯(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ù)庫(kù)備份 5.9.2. 示例用備份與恢復(fù)策略 5.9.3. 自動(dòng)恢復(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本地化和國(guó)際應(yīng)用 5.10.1. 數(shù)據(jù)和排序用字符集 5.10.2. 設(shè)置錯(cuò)誤消息語(yǔ)言 5.10.3. 添加新的字符集 5.10.4. 字符定義數(shù)組 5.10.5. 字符串比較支持 5.10.6. 多字節(jié)字符支持 5.10.7. 字符集問(wèn)題 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. 在同一臺(tái)機(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. 升級(jí)復(fù)制設(shè)置 6.6.1. 將復(fù)制升級(jí)到5.0版 6.7. 復(fù)制特性和已知問(wèn)題 6.8. 復(fù)制啟動(dòng)選項(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語(yǔ)句和其它查詢 7.2.1. EXPLAIN語(yǔ)法(獲取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如何簡(jiǎn)化外部聯(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語(yǔ)句的速度 7.2.17. UPDATE語(yǔ)句的速度 7.2.18. DELETE語(yǔ)句的速度 7.2.19. 其它優(yōu)化技巧 7.3. 鎖定事宜 7.3.1. 鎖定方法 7.3.2. 表鎖定事宜 7.4. 優(yōu)化數(shù)據(jù)庫(kù)結(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ù)庫(kù)中創(chuàng)建多個(gè)表的缺陷 7.5. 優(yōu)化MySQL服務(wù)器 7.5.1. 系統(tǒng)因素和啟動(dò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. 使用符號(hào)鏈接 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語(yǔ)句 8.3.4. mysql技巧 8.4. mysqlaccess:用于檢查訪問(wèn)權(quán)限的客戶端 8.5. mysqladmin:用于管理MySQL服務(wù)器的客戶端 8.6. mysqlbinlog:用于處理二進(jìn)制日志文件的實(shí)用工具 8.7. mysqlcheck:表維護(hù)和維修程序 8.8. mysqldump:數(shù)據(jù)庫(kù)備份程序 8.9. mysqlhotcopy:數(shù)據(jù)庫(kù)備份程序 8.10. mysqlimport:數(shù)據(jù)導(dǎo)入程序 8.11. mysqlshow-顯示數(shù)據(jù)庫(kù)、表和列信息 8.12. myisamlog:顯示MyISAM日志文件內(nèi)容 8.13. perror:解釋錯(cuò)誤代碼 8.14. replace:字符串替換實(shí)用工具 8.15. mysql_zap:殺死符合某一模式的進(jìn)程 9. 語(yǔ)言結(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ù)庫(kù)、表、索引、列和別名 9.2.1. 識(shí)別符限制條件 9.2.2. 識(shí)別符大小寫敏感性 9.3. 用戶變量 9.4. 系統(tǒng)變量 9.4.1. 結(jié)構(gòu)式系統(tǒng)變量 9.5. 注釋語(yǔ)法 9.6. MySQL中保留字的處理 10. 字符集支持 10.1. 常規(guī)字符集和校對(duì) 10.2. MySQL中的字符集和校對(duì) 10.3. 確定默認(rèn)字符集和校對(duì) 10.3.1. 服務(wù)器字符集和校對(duì) 10.3.2. 數(shù)據(jù)庫(kù)字符集和校對(duì) 10.3.3. 表字符集和校對(duì) 10.3.4. 列字符集和校對(duì) 10.3.5. 字符集和校對(duì)分配示例 10.3.6. 連接字符集和校對(duì) 10.3.7. 字符串文字字符集和校對(duì) 10.3.8. 在SQL語(yǔ)句中使用COLLATE 10.3.9. COLLATE子句優(yōu)先 10.3.10. BINARY操作符 10.3.11. 校對(duì)確定較為復(fù)雜的一些特殊情況 10.3.12. 校對(duì)必須適合字符集 10.3.13. 校對(duì)效果的示例 10.4. 字符集支持影響到的操作 10.4.1. 結(jié)果字符串 10.4.2. CONVERT() 10.4.3. CAST() 10.4.4. SHOW語(yǔ)句 10.5. Unicode支持 10.6. 用于元數(shù)據(jù)的UTF8 10.7. 與其它DBMS的兼容性 10.8. 新字符集配置文件格式 10.9. 國(guó)家特有字符集 10.10. MySQL支持的字符集和校對(duì) 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. 列類型存儲(chǔ)需求 11.6. 選擇正確的列類型 11.7. 使用來(lái)自其他數(shù)據(jù)庫(kù)引擎的列類型 12. 函數(shù)和操作符 12.1. 操作符 12.1.1. 操作符優(yōu)先級(jí) 12.1.2. 圓括號(hào) 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語(yǔ)句語(yǔ)法 13.1. 數(shù)據(jù)定義語(yǔ)句 13.1.1. ALTER DATABASE語(yǔ)法 13.1.2. ALTER TABLE語(yǔ)法 13.1.3. CREATE DATABASE語(yǔ)法 13.1.4. CREATE INDEX語(yǔ)法 13.1.5. CREATE TABLE語(yǔ)法 13.1.6. DROP DATABASE語(yǔ)法 13.1.7. DROP INDEX語(yǔ)法 13.1.8. DROP TABLE語(yǔ)法 13.1.9. RENAME TABLE語(yǔ)法 13.2. 數(shù)據(jù)操作語(yǔ)句 13.2.1. DELETE語(yǔ)法 13.2.2. DO語(yǔ)法 13.2.3. HANDLER語(yǔ)法 13.2.4. INSERT語(yǔ)法 13.2.5. LOAD DATA INFILE語(yǔ)法 13.2.6. REPLACE語(yǔ)法 13.2.7. SELECT語(yǔ)法 13.2.8. Subquery語(yǔ)法 13.2.9. TRUNCATE語(yǔ)法 13.2.10. UPDATE語(yǔ)法 13.3. MySQL實(shí)用工具語(yǔ)句 13.3.1. DESCRIBE語(yǔ)法(獲取有關(guān)列的信息) 13.3.2. USE語(yǔ)法 13.4. MySQL事務(wù)處理和鎖定語(yǔ)句 13.4.1. START TRANSACTION 13.4.2. 不能回滾的語(yǔ)句 13.4.3. 會(huì)造成隱式提交的語(yǔ)句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT語(yǔ)法 13.4.5. LOCK TABLES和UNLOCK TABLES語(yǔ)法 13.4.6. SET TRANSACTION語(yǔ)法 13.4.7. XA事務(wù) 13.5. 數(shù)據(jù)庫(kù)管理語(yǔ)句 13.5.1. 賬戶管理語(yǔ)句 13.5.2. 表維護(hù)語(yǔ)句 13.5.3. SET語(yǔ)法 13.5.4. SHOW語(yǔ)法 13.5.5. 其它管理語(yǔ)句 13.6. 復(fù)制語(yǔ)句 13.6.1. 用于控制主服務(wù)器的SQL語(yǔ)句 13.6.2. 用于控制從服務(wù)器的SQL語(yǔ)句 13.7. 用于預(yù)處理語(yǔ)句的SQL語(yǔ)法 14. 插件式存儲(chǔ)引擎體系結(jié)構(gòu) 14.1. 前言 14.2. 概述 14.3. 公共MySQL數(shù)據(jù)庫(kù)服務(wù)器層 14.4. 選擇存儲(chǔ)引擎 14.5. 將存儲(chǔ)引擎指定給表 14.6. 存儲(chǔ)引擎和事務(wù) 14.7. 插入存儲(chǔ)引擎 14.8. 拔出存儲(chǔ)引擎 14.9. 插件式存儲(chǔ)器的安全含義 15. 存儲(chǔ)引擎和表類型 15.1. MyISAM存儲(chǔ)引擎 15.1.1. MyISAM啟動(dòng)選項(xiàng) 15.1.2. 鍵所需的空間 15.1.3. MyISAM表的存儲(chǔ)格式 15.1.4. MyISAM表方面的問(wèn)題 15.2. InnoDB存儲(chǔ)引擎 15.2.1. InnoDB概述 15.2.2. InnoDB聯(lián)系信息 15.2.3. InnoDB配置 15.2.4. InnoDB啟動(dòng)選項(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ù)庫(kù)的備份和恢復(fù) 15.2.9. 將InnoDB數(shù)據(jù)庫(kù)移到另一臺(tái)機(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. 對(duì)InnoDB表的限制 15.2.17. InnoDB故障診斷與排除 15.3. MERGE存儲(chǔ)引擎 15.3.1. MERGE表方面的問(wèn)題 15.4. MEMORY (HEAP)存儲(chǔ)引擎 15.5. BDB (BerkeleyDB)存儲(chǔ)引擎 15.5.1. BDB支持的操作系統(tǒng) 15.5.2. 安裝BDB 15.5.3. BDB啟動(dòng)選項(xiàng) 15.5.4. BDB表的特性 15.5.5. 修改BDB所需的事宜 15.5.6. 對(duì)BDB表的限制 15.5.7. 使用BDB表時(shí)可能出現(xiàn)的錯(cuò)誤 15.6. EXAMPLE存儲(chǔ)引擎 15.7. FEDERATED存儲(chǔ)引擎 15.7.1. 安裝FEDERATED存儲(chǔ)引擎 15.7.2. FEDERATED存儲(chǔ)引擎介紹 15.7.3. 如何使用FEDERATED表 15.7.4. FEDERATED存儲(chǔ)引擎的局限性 15.8. ARCHIVE存儲(chǔ)引擎 15.9. CSV存儲(chǔ)引擎 15.10. BLACKHOLE存儲(chǔ)引擎 16. 編寫自定義存儲(chǔ)引擎 16.1. 前言 16.2. 概述 16.3. 創(chuàng)建存儲(chǔ)引擎源文件 NoName 16.5. 對(duì)處理程序進(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ī)的簡(jiǎn)單基礎(chǔ)知識(shí) 17.3.1. 硬件、軟件和聯(lián)網(wǎng) 17.3.2. 安裝 17.3.3. 配置 17.3.4. 首次啟動(dòng) 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簇的快速測(cè)試設(shè)置 17.4.4. 配置文件 17.5. MySQL簇中的進(jìn)程管理 17.5.1. 用于MySQL簇的MySQL服務(wù)器進(jìn)程使用 17.5.2. ndbd,存儲(chǔ)引擎節(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簇的啟動(dòng)階段 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簇常見問(wèn)題解答 17.11. MySQL簇術(shù)語(yǔ)表 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ù)庫(kù) 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. 測(cè)試幾何對(duì)象間空間關(guān)系的函數(shù) 19.5.5. 關(guān)于幾何最小邊界矩形(MBR)的關(guān)系 19.5.6. 測(cè)試幾何類之間空間關(guān)系的函數(shù) 19.6. 優(yōu)化空間分析 19.6.1. 創(chuàng)建空間索引 19.6.2. 使用空間索引 19.7. MySQL的一致性和兼容性 19.7.1. 尚未實(shí)施的GIS特性 20. 存儲(chǔ)程序和函數(shù) 20.1. 存儲(chǔ)程序和授權(quán)表 20.2. 存儲(chǔ)程序的語(yǔ)法 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語(yǔ)句 20.2.7. BEGIN ... END復(fù)合語(yǔ)句 20.2.8. DECLARE語(yǔ)句 20.2.9. 存儲(chǔ)程序中的變量 20.2.10. 條件和處理程序 20.2.11. 光標(biāo) 20.2.12. 流程控制構(gòu)造 20.3. 存儲(chǔ)程序、函數(shù)、觸發(fā)程序和復(fù)制:常見問(wèn)題 20.4. 存儲(chǔ)子程序和觸發(fā)程序的二進(jìn)制日志功能 21. 觸發(fā)程序 21.1. CREATE TRIGGER語(yǔ)法 21.2. DROP TRIGGER語(yǔ)法 21.3. 使用觸發(fā)程序 22. 視圖 22.1. ALTER VIEW語(yǔ)法 22.2. CREATE VIEW語(yǔ)法 22.3. DROP VIEW語(yǔ)法 22.4. SHOW CREATE VIEW語(yǔ)法 23. INFORMATION_SCHEMA信息數(shù)據(jù)庫(kù) 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和庫(kù) 25.1. libmysqld,嵌入式MySQL服務(wù)器庫(kù) 25.1.1. 嵌入式MySQL服務(wù)器庫(kù)概述 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ù)處理語(yǔ)句 25.2.5. C API預(yù)處理語(yǔ)句的數(shù)據(jù)類型 25.2.6. C API預(yù)處理語(yǔ)句函數(shù)概述 25.2.7. C API預(yù)處理語(yǔ)句函數(shù)描述 25.2.8. C API預(yù)處理語(yǔ)句方面的問(wèn)題 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í)的常見問(wèn)題 25.2.14. 創(chuàng)建客戶端程序 25.2.15. 如何生成線程式客戶端 25.3. MySQL PHP API 25.3.1. 使用MySQL和PHP的常見問(wèn)題 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平臺(tái)上從二進(jìn)制版本安裝MyODBC 26.1.5. I在Unix平臺(tái)上從二進(jìn)制版本安裝MyODBC 26.1.6. 在Windows平臺(tái)上從源碼版本安裝MyODBC 26.1.7. 在Unix平臺(tái)上從源碼版本安裝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方面的問(wèn)題 26.3.6. Changelog 26.4. MySQL Connector/MXJ 26.4.1. 前言 26.4.2. 支持平臺(tái): 26.4.3. Junit測(cè)試要求 26.4.4. 運(yùn)行Junit測(cè)試 26.4.5. 作為JDBC驅(qū)動(dòng)程序的一部分運(yùn)行 26.4.6. 在Java對(duì)象中運(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測(cè)試套件 27.2. 為MySQL添加新函數(shù) 27.2.1. 自定義函數(shù)接口的特性 27.2.2. CREATE FUNCTION/DROP FUNCTION語(yǔ)法 27.2.3. 添加新的自定義函數(shù) 27.2.4. 添加新的固有函數(shù) 27.3. 為MySQL添加新步驟 27.3.1. 步驟分析 27.3.2. 編寫步驟 A. 問(wèn)題和常見錯(cuò)誤 A.1. 如何確定導(dǎo)致問(wèn)題的原因 A.2. 使用MySQL程序時(shí)的常見錯(cuò)誤 A.2.1. 拒絕訪問(wèn) A.2.2. 無(wú)法連接到[local] MySQL服務(wù)器 A.2.3. 客戶端不支持鑒定協(xié)議 A.2.4. 輸入密碼時(shí)出現(xiàn)密碼錯(cuò)誤 NoName A.2.6. 連接數(shù)過(guò)多 A.2.7. 內(nèi)存溢出 A.2.8. MySQL服務(wù)器不可用 A.2.9. 信息包過(guò)大 A.2.10. 通信錯(cuò)誤和失效連接 A.2.11. 表已滿 A.2.12. 無(wú)法創(chuàng)建文件/寫入文件 A.2.13. 命令不同步 A.2.14. 忽略用戶 A.2.15. 表tbl_name不存在 A.2.16. 無(wú)法初始化字符集 A.2.17. 文件未找到 A.3. 與安裝有關(guān)的事宜 A.3.1. 與MySQL客戶端庫(kù)的鏈接問(wèn)題 A.3.2. 如何以普通用戶身份運(yùn)行MySQL A.3.3. 與文件許可有關(guān)的問(wèn)題 A.4. 與管理有關(guān)的事宜 A.4.1. 如何復(fù)位根用戶密碼 A.4.2. 如果MySQL依然崩潰,應(yīng)作些什么 A.4.3. MySQL處理磁盤滿的方式 A.4.4. MySQL將臨時(shí)文件儲(chǔ)存在哪里 A.4.5. 如何保護(hù)或更改MySQL套接字文件/tmp/mysql.sock A.4.6. 時(shí)區(qū)問(wèn)題 A.5. 與查詢有關(guān)的事宜 A.5.1. 搜索中的大小寫敏感性 A.5.2. 使用DATE列方面的問(wèn)題 A.5.3. 與NULL值有關(guān)的問(wèn)題 A.5.4. 與列別名有關(guān)的問(wèn)題 A.5.5. 非事務(wù)表回滾失敗 A.5.6. 從相關(guān)表刪除行 A.5.7. 解決與不匹配行有關(guān)的問(wèn)題 A.5.8. 與浮點(diǎn)比較有關(guān)的問(wèn)題 A.6. 與優(yōu)化器有關(guān)的事宜 A.7. 與表定義有關(guān)的事宜 A.7.1. 與ALTER TABLE有關(guān)的問(wèn)題 A.7.2. 如何更改表中的列順序 A.7.3. TEMPORARY TABLE問(wèn)題 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使用和包含的庫(kù) 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. 針對(duì)調(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)表崩潰,請(qǐng)生成測(cè)試案例 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. 對(duì)存儲(chǔ)子程序和觸發(fā)程序的限制 I.2. 對(duì)服務(wù)器端光標(biāo)的限制 I.3. 對(duì)子查詢的限制 I.4. 對(duì)視圖的限制 I.5. 對(duì)XA事務(wù)的限制 J. GNU通用公共許可 K. MySQL FLOSS許可例外 索引
characters

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

目錄

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

20.2. 存儲(chǔ)程序的語(yǔ)法

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語(yǔ)句

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

20.2.8. DECLARE語(yǔ)句

20.2.9. 存儲(chǔ)程序中的變量

20.2.10. 條件和處理程序

20.2.11. 光標(biāo)

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

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

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

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

下面一些情況下存儲(chǔ)程序尤其有用:

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

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

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

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

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

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

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

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

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

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

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

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

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

20.2.?存儲(chǔ)程序的語(yǔ)法

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語(yǔ)句

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

20.2.8. DECLARE語(yǔ)句

20.2.9. 存儲(chǔ)程序中的變量

20.2.10. 條件和處理程序

20.2.11. 光標(biāo)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

存儲(chǔ)子程序不能使用LOAD DATA INFILE。

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

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

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)

如果在存儲(chǔ)函數(shù)中的RETURN語(yǔ)句返回一個(gè)類型不同于在函數(shù)的RETURNS子句中指定類型的值,返回值被強(qiáng)制為恰當(dāng)?shù)念愋汀1热?,如果一個(gè)函數(shù)返回一個(gè)ENUM或SET值,但是RETURN語(yǔ)句返回一個(gè)整數(shù),對(duì)于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è)語(yǔ)句可以被用來(lái)改變一個(gè)存儲(chǔ)程序或函數(shù)的特征。在MySQL 5.1中,你必須用ALTER ROUTINE權(quán)限才可用此子程序。這個(gè)權(quán)限被自動(dòng)授予子程序的創(chuàng)建者。如20.4節(jié),“存儲(chǔ)子程序和觸發(fā)程序的二進(jìn)制日志功能”中所述, 如果二進(jìn)制日志功能被允許了,你可能也需要SUPER權(quán)限。

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

20.2.3.?DROP PROCEDUREDROP FUNCTION

DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name

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

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

20.2.4.?SHOW CREATE PROCEDURESHOW CREATE FUNCTION

SHOW CREATE {PROCEDURE | FUNCTION} sp_name

這個(gè)語(yǔ)句是一個(gè)MySQL的擴(kuò)展。類似于SHOW CREATE TABLE,它返回一個(gè)可用來(lái)重新創(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è)語(yǔ)句是一個(gè)MySQL的擴(kuò)展。它返回子程序的特征,如數(shù)據(jù)庫(kù),名字,類型,創(chuàng)建者及創(chuàng)建和修改日期。如果沒有指定樣式,根據(jù)你使用的語(yǔ)句,所有 存儲(chǔ)程序和所有存儲(chǔ)函數(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)存儲(chǔ)子程序的信息。請(qǐng)參閱23.1.14節(jié),“INFORMATION_SCHEMA ROUTINES 表 。

20.2.6.?CALL語(yǔ)句

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

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

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

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

[begin_label:] BEGIN

??? [statement_list]

END [end_label]

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

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

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

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

20.2.8.?DECLARE語(yǔ)句

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

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

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

20.2.9.?存儲(chǔ)程序中的變量

20.2.9.1. DECLARE局部變量

20.2.9.2. 變量SET語(yǔ)句

20.2.9.3. SELECT ... INTO語(yǔ)句

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

20.2.9.1.?DECLARE局部變量

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

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

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

20.2.9.2. 變量SET語(yǔ)句

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

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

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

20.2.9.3.?SELECT ... INTO語(yǔ)句

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

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

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

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

重要: SQL變量名不能和列名一樣。如果SELECT ... INTO這樣的SQL語(yǔ)句包含一個(gè)對(duì)列的參考,并包含一個(gè)與列相同名字的 局部變量,MySQL當(dāng)前把參考解釋為一個(gè)變量的名字。例如,在下面的語(yǔ)句中,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í)候,無(wú)論table.xname列的值是什么,變量newname將返回值‘bob’。

請(qǐng)參閱I.1節(jié),“存儲(chǔ)子程序和觸發(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è)語(yǔ)句指定需要特殊處理的條件。它將一個(gè)名字和指定的錯(cuò)誤條件關(guān)聯(lián)起來(lái)。這個(gè)名字可以隨后被用在DECLARE HANDLER語(yǔ)句中。請(qǐng)參閱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è)語(yǔ)句指定每個(gè)可以處理一個(gè)或多個(gè)條件的處理程序。如果產(chǎn)生一個(gè)或多個(gè)條件,指定的語(yǔ)句被執(zhí)行。

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

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

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

·???????? SQLEXCEPTION是對(duì)所有沒有被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語(yǔ)句

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

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

簡(jiǎn)單光標(biāo)在存儲(chǔ)程序和函數(shù)內(nèi)被支持。語(yǔ)法如同在嵌入的SQL中。光標(biāo)當(dāng)前是不敏感的,只讀的及不滾動(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è)語(yǔ)句聲明一個(gè)光標(biāo)。也可以在子程序中定義多個(gè)光標(biāo),但是一個(gè)塊中的每一個(gè)光標(biāo)必須有唯一的名字。

SELECT語(yǔ)句不能有INTO子句。

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

OPEN cursor_name

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

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

FETCH cursor_name INTO var_name [, var_name] ...

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

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

CLOSE cursor_name

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

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

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

20.2.12.1. IF語(yǔ)句

20.2.12.2. CASE語(yǔ)句

20.2.12.3. LOOP語(yǔ)句

20.2.12.4. LEAVE語(yǔ)句

20.2.12.5. ITERATE語(yǔ)句

20.2.12.6. REPEAT語(yǔ)句

20.2.12.7. WHILE語(yǔ)句

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

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

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

20.2.12.1.?IF語(yǔ)句

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語(yǔ)句列表被執(zhí)行。如果沒有search_condition匹配,在ELSE子句里的語(yǔ)句列表被執(zhí)行。statement_list可以包括一個(gè)或多個(gè)語(yǔ)句。

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

20.2.12.2.?CASE語(yǔ)句

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

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

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

20.2.12.3.?LOOP語(yǔ)句

[begin_label:] LOOP

??? statement_list

END LOOP [end_label]

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

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

20.2.12.4.?LEAVE語(yǔ)句

LEAVE label

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

20.2.12.5.?ITERATE語(yǔ)句

ITERATE label

ITERATE只可以出現(xiàn)在LOOP, REPEAT, 和WHILE語(yǔ)句內(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語(yǔ)句

[begin_label:] REPEAT

??? statement_list

UNTIL search_condition

END REPEAT [end_label]

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

REPEAT 語(yǔ)句可以被標(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語(yǔ)句

[begin_label:] WHILE search_condition DO

??? statement_list

END WHILE [end_label]

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

WHILE語(yǔ)句可以被標(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.?存儲(chǔ)程序 、函數(shù)、觸發(fā)程序及復(fù)制:常見問(wèn)題

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

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

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

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

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

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

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

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

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

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

    此外,時(shí)基行為不能在從服務(wù)器上重新產(chǎn)生,因?yàn)樵诖鎯?chǔ)程序中通過(guò)對(duì)復(fù)制使用的二進(jìn)制日志來(lái)計(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ò)誤,對(duì)從服務(wù)器沒有更新。 對(duì)函數(shù)的DML行為,工作區(qū)將被用IGNORE關(guān)鍵詞來(lái)執(zhí)行,以便于在主服務(wù)器上導(dǎo)致錯(cuò)誤的更新被忽略,并且不會(huì)導(dǎo)致錯(cuò)誤的更新被復(fù)制到從服務(wù)器。

    ?

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

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

  • ?MySQL要做什么來(lái)改正前述的限制呢?

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

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

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

    ?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

盡管如此,對(duì)復(fù)制有一個(gè)安全暗示:要?jiǎng)?chuàng)建一個(gè)子程序,用戶必須有CREATE ROUTINE權(quán)限,但有這個(gè)權(quán)限的用戶不能寫一個(gè) 子程序在從服務(wù)器上執(zhí)行任何操作。因?yàn)樵趶姆?wù)器上的SQL線程用完全權(quán)限來(lái)運(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語(yǔ)句將被寫進(jìn)二進(jìn)制日志,所以從服務(wù)器將執(zhí)行它們。因?yàn)閺腟QL線程有完全權(quán)限,它將移除accounting數(shù)據(jù)庫(kù)。

要使允許二進(jìn)制日志功能的服務(wù)器避免這個(gè)危險(xiǎn),MySQL 5.1已經(jīng)要求 存儲(chǔ)程序和函數(shù)的創(chuàng)建者除了通常需要的CREATE ROUTINE的權(quán)限外,還必須有SUPER 權(quán)限。類似地,要使用ALTER PROCEDURE或ALTER FUNCTION,除了ALTER ROUTINE權(quán)限外你必須有SUPER權(quán)限。沒有SUPER權(quán)限,將會(huì)發(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ā)者。要禁止掉對(duì)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;

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

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

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

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

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

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

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

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

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

默認(rèn)地,要一個(gè)CREATE PROCEDURE 或 CREATE FUNCTION 語(yǔ)句被接受,DETERMINISTIC 或 NO SQL與READS SQL DATA 中的一個(gè)必須明白地指定,否則會(huì)產(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, 移除對(duì)子程序必須是確定的或不修改數(shù)據(jù)的要求。

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

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

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

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

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

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

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

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

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

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

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

SELECT myfunc();

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

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

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

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

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

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

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

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

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


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


?

?

Previous article: Next article: