易语言3

易语言3.6版外部数据库使用

Sql server 2000数据库安装

Mysql 数据库服务器安装和基本使用

Mysql 数据库支持库使用及edb to Mysql转换程序使用

易语言3.6版外部数据库使用例程 下载

mysql 支持库基本及edb to Mysql转换程下载

作者：世恒

2004年4月22日

QQ:25631887

E-mail:sh-soft@sohu.com

易语言教学资源网：http://www.eyuyan.net


SQL Server 2000简单介绍和安装

易语言之外部数据库使用

一．access数据库

新版外部数据库支持库提供类似ADO数据库访问方式，外部数据库的访问基本思路是这样的：通过连接控件连接到数据库，表操作控件取得连接，并内部表操作控件对数据库进行操作，现在对它的使用方法作些介绍。

准备工作：

建立窗口，放置控件（数据库连接、记录集、按钮，显示记录的控件（这里用了超级列表框），并且用access建立一个空的数据库，字段信息如下：

程序界面如图1所示。

图1

1.连接数据库

使用前，易语言首要要通知到数据库，然后和其达成连接协议。有两种连接方式。

（1）ADO连接方式

命令及格式：〈逻辑型〉 对象．连接Access （文件名，密码）

参数<1>的名称为“文件名”，类型为“文本型（text）”。Access数据库文件的完整路径名。

参数<2>的名称为“密码”，类型为“文本型（text）”，初始值为“”。Access数据库的作密码。本参数可以为空，若为空，表示Access数据库没有密码。

例句：信息框 (选择 (数据库连接1.连接Access (“SoccerPlayer DB.mdb”, “”), “连接成功”, “连接失败”), 0, )，返回真说明连接成功，否则连接失败。运行程序，点击“连接access”，成功后如图2显示：

图2

(2) access通用连接

命令及格式：〈逻辑型〉 对象．连接 （连接文本）

参数<1>的名称为“连接文本”，类型为“文本型（text）”。本参数提供连接时使用的连接文本。

例句：信息框 (数据库连接1.连接 (“Provider=Microsoft.Jet.OLEDB.4.0;Data Source=SoccerPlayer DB.mdb”), 0, )，返回真说明连接成功，否则连接失败。运行程序，点击“通用连接access”连接，显示真假信息。

2.设置连接

连接后，将操作权限设置给记录集之后记录集将对数据库进行操作。

命令及格式：〈逻辑型〉 对象．设连接 （连接）

参数<1>的名称为“连接”，类型为“数据库连接（CommonConnection）”。要设置的数据库连接。

例句：信息框 (选择 (记录集1.设连接 (数据库连接1), “设置成功”, “设置失败”), 0, )，返回真说明设置成功，否则设置失败。如图3显示：

图3

3.打开表

设置好连接之后，就可以打开数据库中的表进行具体操作了，先在看如何打开表，以下命令。

命令及格式：〈逻辑型〉 对象．打开 （打开表，打开选项）

参数<1>的名称为“打开表”，类型为“文本型（text）”。输入数据库中的某一个表名或SQL语句。

参数<2>的名称为“打开选项”，类型为“整数型（int）”。打开表时的动作类型，可以为以下常量或数值之一：1、#打开普通SQL； 2、#打开表名。

例句：信息框 (选择 (记录集1.打开 (“基本信息”, #打开表名), “打开表成功”, “打开表失败”), 0, )，返回真说明打开表成功，否则打开表失败。如图4显示：

图4

4.移动读写位置

数据库打开后，默认读写位置在尾记录，我们常规是从首记录开始操作，我们需要移动到我们指定记录。

(1) 到首记录

命令及格式：〈逻辑型〉 对象．到首记录 （）

例句：信息框 (选择 (记录集1.到首记录 (), “移动位置成功”, “移动位置失败”), 0, )，返回真说明移动位置成功，否则移动位置失败。如图5显示：

图5

同时还有其他移动记录的命令，相关如下：

(2) 到尾记录

命令及格式：〈逻辑型〉 对象．到尾记录 （）

例句：信息框 (选择 (记录集1.到尾记录 (), “移动位置成功”, “移动位置失败”), 0, )，返回真说明移动位置成功，否则移动位置失败。

(3) 到下一条

命令及格式：〈逻辑型〉 对象．到下一条 （）

例句：信息框 (选择 (记录集1. 到下一条 （）, “移动位置成功”, “移动位置失败”), 0, )，返回真说明移动位置成功，否则移动位置失败。

(4) 到前一条

命令及格式：〈逻辑型〉 对象．到前一条（）

例句：信息框 (选择 (记录集1. 到前一条 （）, “移动位置成功”, “移动位置失败”), 0, )，返回真说明移动位置成功，否则移动位置失败。

(5) 移到

命令及格式：〈逻辑型〉 对象．移到 （目标记录号）

参数<1>的名称为“目标记录号”，类型为“整数型（int）”。本参数提供目标记录号值，该值从 0 开始。

例句：信息框 (记录集1.移到 (超级列表框1.现行选中项), 0, ), 0, )，返回真说明移动位置成功，否则移动位置失败。

5.添加记录

新版外部数据库记录添加方式有了改变，按照以下步骤进行：

添加空记录→分别写字段→更新数据

(1) 添加空记录

命令及格式：〈逻辑型〉 对象．添加 （）

例句：信息框 (选择 (记录集1.添加 (), “添加空记录成功”, “添加空记录失败”), 0, ) ，返回真说明添加空记录成功，否则添加空记录失败。如图6显示：

图6

(2) 写文本型字段

命令及格式：〈逻辑型〉 对象．写文本 （序号或字段名，文本）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“文本”，类型为“文本型（text）”。要写入的文本。

例句： 信息框 (选择 (记录集1.写文本 (1, “世恒”), “写文本字段成功”, “写文本字段失败”), 0, )，返回真说明写文本字段成功，否则写文本字段失败。如图7显示：

图7

(3) 写日期型字段

命令及格式：〈逻辑型〉 对象．写日期 （序号或字段名，日期）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“日期”，类型为“日期时间型（date）”。要写入的日期变量。

例句： 信息框 (选择 (记录集1.写日期 (2, 到时间 (“1980-2-21”)), “写日期字段成功”, “写日期字段失败”), 0, )，返回真说明写日期字段成功，否则写日期字段失败。如图8显示：

图8

(4) 写单精度型字段

命令及格式：〈逻辑型〉 对象．写单精度 （序号或字段名，双精度）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“双精度”，类型为“小数型（float）”。要写入的双精度值。例句： 信息框 (选择 (记录集1.写单精度 (3, 1.7), “写单精度字段成功”, “写单精度字段失败”), 0, )，返回真说明写单精度字段成功，否则写单精度字段失败。如图9显示：

图9

（5）写双精度型字段

命令及格式：〈逻辑型〉 对象．写双精度 （序号或字段名，双精度）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“双精度”，类型为“双精度小数型（double）”。要写入的双精度值。

例句： 信息框 (选择 (记录集1.写双精度 (4, 68.55), “写双精度字段成功”, “写双精度字段失败”), 0, )，返回真说明写双精度字段成功，否则写双精度字段失败。如图10显示：

图10

（6）写逻辑型字段

命令及格式：〈逻辑型〉 对象．写逻辑 （序号或字段名，逻辑）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。参数<2>的名称为“逻辑”，类型为“逻辑型（bool）”。要写入的逻辑型值。

例句： 信息框 (选择 (记录集1.写逻辑 (5, 假), “写逻辑字段成功”, “写逻辑字段失败”), 0, )，返回真说明写逻辑字段成功，否则写逻辑字段失败。如图11显示：

图11

货币型字段的写入按照双精度写入即可。

（7）更新记录

字段写入后，我们需要刷新一下显示。

命令及格式：〈逻辑型〉 对象．更新 （）

例句： 信息框 (选择 (记录集1.更新 (), “更新记录成功”, “更新记录失败”), 0, )，返回真说明更新成功，否则更新失败。如图12显示：

如图12

到这里，我已经为数据库写入了数据，如何检验呢，我们读取数据来看看是否存在数据。

6.读取记录

新版数据库支持库采用ADO方式操作数据库，读取方式与以往不同，基本过程：

建立存储变量→读取字段到变量→取出变量数据到目的处

为此我们首先建立系列局部存储变量,格式如下：

(1)读整型字段

命令及格式： 记录集1.读整型 (0, 整型变量)）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“整型变量”，类型为“整数型（int）”，提供参数数据时只能提供变量。要读取的整型变量。

例句： 记录集1.读整型 (0, 整型变量) ，说明：数据库中的1字段在这里用0序号去读取。

(2)读文本型字段

命令及格式：〈逻辑型〉 对象．读文本 （序号或字段名，文本变量）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“文本变量”，类型为“文本型（text）”，提供参数数据时只能提供变量。要读取的文本变量。

例句： 〈逻辑型〉 对象．读文本 （序号或字段名，文本变量）

(3)读日期型字段

命令及格式：〈逻辑型〉 对象．读日期 （序号或字段名，日期变量）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段序号或者字段名。

参数<2>的名称为“日期变量”，类型为“日期时间型（date）”，提供参数数据时只能提供变量。要读取的日期变量。

例句： 记录集1.读日期 (2, 日期变量)

(4)读单精度型字段

命令及格式：〈逻辑型〉 对象．读单精度 （序号或字段名，单精度变量）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或者字段名。

参数<2>的名称为“单精度变量”，类型为“小数型（float）”，提供参数数据时只能提供变量。要读取的单精度变量。

例句： 记录集1.读单精度 (3, 单精度变量)

(5)读双精度型字段

命令及格式：〈逻辑型〉 对象．读双精度 （序号或字段名，双精度变量）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。字段的序号或字段名。

参数<2>的名称为“双精度变量”，类型为“双精度小数型（double）”，提供参数数据时只能提供变量。要读取的双精度变量。

例句： 记录集1.读双精度 (4, 双精度变量)

(6)读逻辑型字段

命令及格式：〈逻辑型〉 对象．读逻辑 （序号或字段名，逻辑变量）

参数<1>的名称为“序号或字段名”，类型为“通用型（all）”。序号或者字段名。

参数<2>的名称为“逻辑变量”，类型为“逻辑型（bool）”，提供参数数据时只能提供变量。要读取的逻辑变量。

例句： 记录集1.读逻辑 (5, 逻辑变量)

货币型读取按照双精度型读取即可。

现在数据都已经读入到各自类型的存储变量中，下面我们通过超级列表框去显示一下数据，看看是否存在，以下代码是用来设置超级列表框的，不属于当前内容，您可以看一下。

好了，设置好了超级列表框，我们先在把记录显示在里面：

代码如下：

显示结果如下图13所示：

图13

到此，数据读取结束，现在我们对他进一步操作，包括查询，过滤，删除，修改，关闭等。

7.查询记录

(1)查找

命令及格式：〈逻辑型〉 对象．查找 （查找条件，查找方向）

参数<1>的名称为“查找条件”，类型为“文本型（text）”。本参数提供在数据表中查找的条件。

参数<2>的名称为“查找方向”，类型为“整数型（int）”。本参数指定在数据表中查找的方向。可以为以下数值或常量之一：1、正向搜索； 2、反向搜索。

例句： 信息框 (记录集1.查找 (组合框3.内容 ＋ “ ” ＋ 组合框4.内容 ＋ “ '” ＋ 编辑框1.内容 ＋ “'”, 组合框5.现行选中项 ＋ 1), 0, )，暂时不支持多条件查找，写法规则同sql常规,文本型，日期型等要用单引号。

(2)查找下一条

当有多个符合条件的记录时，用此命令到下一条符合条件的记录。

命令及格式：〈逻辑型〉 对象．查找下一个 （）

例句： 信息框 (记录集1.查找下一个 (), 0, )

过滤记录

(3)过滤记录

命令及格式：〈逻辑型〉 对象．过滤记录 （过滤条件）

参数<1>的名称为“过滤条件”，类型为“文本型（text）”。过滤的条件。

例句： 信息框 (记录集1.过滤记录 (“id > 20 and 姓名 like '王%' and 身高 >1.4 and 身高 <1.9”), 0, )，支持多条件过滤，写法规则同sql常规,文本型，日期型等要用单引号，过滤后将符合条件的记录放在临时库中。

图14 为过滤后的显示情况：

图14

8.修改记录

新版支持库没有直接的修改命令，修改时，将记录指针移到要修改的记录上，然后直接使用写字段就可以修改，但保证修改后要用更新命令。例如想把第一条记录的姓名由“世恒”改为“史世恒”，用以下命令：

记录集1.到首记录 ()

*备注：将记录指针移到要修改的记录上

信息框 (记录集1.写文本 (1, “史世恒”), 0, )

*备注：执行写入新的数据

记录集1.更新 ()

*备注：更新数据

其他写入命令参考添加记录命令即可。

8.删除记录

当我们要删除不需要的记录时，这时有两种可能，一种时删除部分记录，一种是删除全部记录。

(1) 删除记录

命令及格式：〈逻辑型〉 对象．删除 （删除选项）

参数<1>的名称为“删除选项”，类型为“整数型（int）”。本参数为以下常量或数值之一：1、删除当前记录； 3、删除全部记录。

例句： 信息框 (记录集1.删除 (#删除全部记录), 0, )，返回真说明记录删除成功，否则记录删除失败。

二． sql server数据库

Sql 数据库的连接和access有所不同，这是因其本身的特点决定，它具有网络操作和验证特性，它的使用流程是：易语言首要要通知到数据库服务器要求取得与某数据连接请求，数据库服务器验证客户通过后，和其达成连接协议。但其操作和access唯一不同的就是连接方式，我们并对连接方式作以解释，其他参照access操作即可。

1．ADO方式连接sql数据库

命令及格式：〈逻辑型〉 对象．连接SQLServer （服务器名，数据库名，用户名，密码）

参数<1>的名称为“服务器名”，类型为“文本型（text）”。本参数提供 SQL SERVER 服务器名。

参数<2>的名称为“数据库名”，类型为“文本型（text）”。

参数<3>的名称为“用户名”，类型为“文本型（text）”。

参数<4>的名称为“密码”，类型为“文本型（text）”。

例句：信息框 (选择 (数据库连接1.连接SQLServer (“192.168.0.19”, “test”, “user”, “123”), “连接成功”, “连接失败”), 0, )，返回真说明连接成功，否则连接失败。运行程序，点击“连接sql”，成功后如图15显示：

图15

2． Sql通用连接数据库

命令及格式：〈逻辑型〉 对象．连接 （连接文本）

参数<1>的名称为“连接文本”，类型为“文本型（text）”。本参数提供连接时使用的连接文本。

例句：信息框 (数据库连接1.连接（“DRIVER=SQLServer;SERVER=192.168.0.19;UID=user;PWD=123;WSID=BOOK9;DATABASE=test;LANGUAGE=简体中文;QueryLog_On=Yes;StatsLog_On=Yes”）, “连接成功”, “连接失败”), 0, )，返回真说明连接成功，否则连接失败。运行程序，点击“连接sql”，成功后如图16显示：

图16

三． mysql数据库

整理中。。。


SQL Server 2000简单介绍和安装

在易语言新版本中，外部数据库操支持有了很大的改进，考虑到大家以后对外部数据库的大量使用，这里介绍常用SQL Server 2000数据库服务器的安装和基本配置，以方便大家使用。下面从几个方面介绍一下SQL Server。

一、服务器组件

SQL Server 2000由两个部分组成：服务器组件和客户端工具。

1.内容

SQL Server的服务器组件是以 Windows 服务（Windows Services）方式运行的。一般认为SQL Server包含四种Windows服务（这里我们关注OLTP、暂时不考虑 OLAP）,分别是：MS Sql Server、DTC Distributed Transaction coordinator、SQLServerAgent、Search Service。

MSSqlServer 是最常用的服务，一般的数据库功能都是由它提供的，例如文件管理、查询处理、数据存储等；DTC是分布式事务协调器，支持跨越两个或多个服务器的更新操作来保证事务的完整性；SQLServerAgent负责SQL Server自动化工作，如果需要SQL Server在指定时间执行某一个存储过程，就需要用到这个服务了；Search Service是全文查询服务，负责全文检索方面的工作。

2.一分为四的理由

现在我们知道了 SQL Server 的核心是四个服务器组件，它们是以 Windows 服务的形式运行的。聪明的读者也许会思考这样的问题：为什么服务器组件以 Windows 服务方式运行?为什么需要把完整的系统分割成四个服务器组件?

●之所以把SQL Server服务器组件作为Windows服务程序，主要是因为Windows 服务程序能够在用户没有登录的情况下使用。

●之所以把SQL Server的核心功能分为四个Windows 服务程序，主要是考虑了以下因素：这些Windows 服务程序各自负担的任务功能上是可分割的，这是前提条件；不是每个应用都需要使用四个服务所提供的所有功能，让用户有选择的关闭一些服务，无疑可以节省系统的资源，也可以节省用户花在管理上的精力；最后，分开成为多个服务程序，就可以为每一个服务设定操作系统级的安全策略。

二、客户端工具

SQL Server 2000 的核心是上文讨论的那些服务器组件，但用户直接接触的却不是它们（虽然真正干活的是它们），而是客户端工具。服务器组件是引擎，客户端工具是用户界面，两者是相辅相成的。

让我们看看SQL Server 2000 的客户端工具到底有哪些——企业管理器、查询分析器、事件探查器、服务管理器、客户端网络实用工具、服务器网络实用工具、导入和导出数据（DTS）等等。

服务器组件与客户端工具功能上是配套的，客户端工具需要用最简单的形式表达最丰富的服务器组件的功能；服务器组件和客户端工具物理上是离散的，说句大白话：它们不是同一个程序!客户端工具要与服务器组件连通，需要一些用于通讯的动态链接库，SQL Server 2000 的通讯库支持多种网络协议，例如TCP/IP、命名管道等。

说到这里问题就很清楚了：只要客户端工具与服务器组件与功能上是配套（兼容）的，就可以通过一定的协议连接，所以我们只要在自己的机器上装一套客户端工具，就可以连接世界各地的SQL Server 服务器，当然这需要对方开放足够的权限。

提示：安装 SQL Server 2000 实际上就是安装服务器组件和客户端工具。当然，我们可以选择同时安装服务器组件和客户端工具，或者只安装其中的一个，甚至只选择安装更少的东西。

三、版本问题

SQL Server 2000有很多版本：企业版、开发版、标准版、个人版等。每一个版本包含的客户端工具基本上是一样的，而服务器组件可能有些不同。所以在安装 SQL Server 之前必须参考“操作系统和SQL Server”版本兼容表（图1），根据操作系统选择合适的 SQL Server 版本。

图1

四、关于实例

在开始安装SQL Server之前，还有一个概念需要讲解，那就是SQL Server实例。前文我们提到SQL Server服务器组件是由四个Windows 服务程序构成，在实践中我们可能安装所有的服务器组件，也可能只安装其中的一部分，但是我们都需要一个统一的概念来标志一组SQL Server 服务，这个概念就是SQL Server 实例。
    提示：可以这样理解，安装SQL Server 服务器组件，就是创建一个新的SQL Server 实例（当然也可能是在原有实例中增减服务组件）。SQL Server 2000 允许在同一个操作系统中创建多个实例，虽然一般情况下我们不会这么做。
    ●如果只安装一个 SQL Server 实例，不需要在SQL Server安装时指定实例名称，自动使用默认名称。那么在Windows域里计算机的名称就是 SQL Server 实例的名称；使用TCP/IP协议连接SQL Server 实例时，可以用IP地址表示SQL Server 2000实例。
    ●如果一个操作系统中安装了多个SQL Server 2000的实例，则需要在SQL Server安装时指定实例名称。
Windows域里可以用“计算机名称\实例名称”的形式标志SQL Server 2000实例；使用TCP/IP协议连接SQL Server 实例时，可以用“IP地址\实例名称”表示SQL Server 2000实例。

五、安装实战

SQL Server 2000的安装程序是非常智能化的，基本上用户只需要跟着提示，选择默认项。下面笔者以标准版为例挑选一些需要注意的设定画面进行讲解。

●安装启动后，选择“安装SQL Server 2000 组件”，如图2：

图2

●选择“安装数据库服务器”，如图3：

图3

●经过以下安装准备，如图4：

图4

●选择“下一步”，如图5：

图5

●进入计算机名设置界面，如果安装在本地计算机，请选择“本地计算机”，然后单击“下一步”按钮，如图6：

图6

●选择创建新的实例选项，并且单击“下一步”，如图7：

图7

●这里您可以修改您的计算机名，但一般情况下不用修改，直接点击“下一步”，如图8：

图8

●出现软件安装许可协议，直接点击“是”按钮， 如图9：

图9

●这里选择您要安装的模式，一般默认安装“服务器和客户端工具”，如图10：

图10

●如果是首次安装，直接选择默认实例名，否则系统会提示您输入，之后点击“下一步”，如图11：

图11

●选择“典型”安装类型即可，默认安装位置，如图12：

图12

●为服务设定启动方式，这里有两个服务，分别是SQL Server和SQL Server 代理。其实就是前文提到的MSSqlServer和SQLServerAgent。这里我们操作系统以“本地系统账户”启动它们，如图13：

图13

●初学可以直接选择混合模式验证，设置空密码即可，如图14：

图14

●选择“下一步”开始复制文件，如图15：

图15

●按默认选择许可模式即可，如图16：

图16

●安装过程，如图17：

图17

●复制文件进程，如图18：

图18

●安装过程完成，如图19：

图19

六、一窥芳容

    安装完毕，你肯定迫不及待地要领略它的风采。不要着急，让我们先确认数据库服务器是否已经启动。前文我们提到SQL Server 2000核心是由四个服务器组件构成的，其中提供数据库服务的就是 MSSqlServer，现在我们就是要确认它是否已经启动。

1.服务管理器

    ●在“服务器”栏选择本机 SQL Server 实例的名称；

    ●在“服务”栏选择SQL Server（就是上文的MSSqlServer）；

    ●按下“开始/继续”按钮，启动 MSSqlServer 服务；

●正常启动:

2.企业管理器

    打开“企业管理器”，展开数据库本机SQL Server 实例节点的数据库项目，可以发现SQL Server 已经自动安装了六个数据库。

    ●master数据库记录SQL Server系统的所有系统级别信息。

    ●tempdb数据库保存所有的临时表和临时存储过程。

    ●model数据库是为用户创建数据库提供的模板。

    ●msdb数据库供SQL Server代理程序调度警报和作业以及记录各种操作。

    ●northwind和pubs是示例数据库，以后我们要经常利用它们做演示。

    除了 northwind和 pubs之外，其他四个数据库都是由 SQL Server 自行维护的，一般不需要用户干预。

到此，SQL Server 2000数据库安装完毕，如果您还不会使用它，请看后续sql在易语言中的使用说明。


Mysql 数据库服务器安装

新版易语言提供了mysql数据库支持，很多人并不熟悉mysql,这里对mysql数据库的安装作一介绍,我们这里提供了mysql从下载到安装的过程。

下载mysql，依照下图1在mysql官方网站找到mysql 5.0下载地址。

图1

按照箭头位置点击下载，显示如图2，选择保存文件。

图2

按照箭头位置点击保存，显示如图3。

图3

点击保存，保存文件到选定位置，之后出现图4下载进度。

图4

下载结束后，我们打开保存位置，看到压缩文件包，如图5

图5

我们用压缩软件（推荐winrar）解压文件，之后如图6

图6

双击文件setup.exe,出现安装界面开始安装，如图7

图7

点击“next”(下一步)，进入安装进程，之后如图8

图8

阅读安装协议后，选择“next”,继续，之后出现图9界面

图9

这里选择安装位置，默认为“c:\mysql”,我们一般保留默认，点击“next”，出现图10选择安装类型

图10

保留默认类型（典型安装），点击“next”，出现图11复制文件进度界面

图11

文件复制结束后，出现安装完成界面，如图12

图12

这是，安装过程结束，我们看看mysql到底什么样子啊，不着急，跟我来。

我们先找到mysql安装位置，如图13

图13

看到很多文件夹，我们打开“bin”文件夹，看到如图14

图14

可能到文件，双击图上箭头所指文件，出现mysql服务器管理界面，如图15

图15

这下就详细看看吧，界面显示一下设置和版本信息，我们跳到数据库界面，如图16，看到有test数据，好了安装过程到这里结束，具体操作请看mysql数据库操作说明。

图16

2、Mysql 入门图解教程

2.1 连接服务器

我们以下以windows2000以上系统作例子说明.

Mysql操作皆为dos界面，所以要做一下准备工作。

1、 复制 cmd.exe到mysql 安装目录

如图17、图18

图17

图18

2、 运行cmd.exe,出现dos窗口，如图19。

图19

格式： mysql -h 主机地址 -u 用户名 －p 用户密码
3、连接到本机上的 MYSQL

在DOS窗口，键入命令 mysql -h localhost -u root -p，回车后提示你输密码，如果刚安装好MYSQL，超级用户root是没有密码的，故直接回车即可进入到MYSQL中了，MYSQL的提示符是：mysql>

效果如图20：

图20

4、连接到远程主机上的MYSQL

假设远程主机的IP为：110.110.110.110，用户名为root,密码为abcd123。则键入以下命令：
mysql -h 110.110.110.110 -u root -p abcd123
（注:u与root可以不用加空格，其它也一样）

2.2 断开服务器

1、退出MYSQL命令1： quit （回车）退出mysql,断开连接，如图21。

图21

2、退出MYSQL命令2： exit （回车），此命令回到windows,当然自动断开mysql。

2.3查看数据库

命令格式：show databases;

键入命令后，显示如图22

图22

2.4选择数据库

命令格式：use 数据库名;

键入命令后，显示如图23

图23

2.5查看表

命令格式：show tables;

键入命令后，显示如图24

图24

2.6查看表结构

命令格式：describe 表名;

键入命令后，显示test表的字段结构，如图25

图25

2.7插入记录

命令格式：insert into 表名 set 字段名=值;

键入命令后，显示test表中的记录，如图26

图26

2.8查看表中的所有记录

命令格式：select * from 表名;

键入命令后，显示test表中的记录，如图27

图27

2.9条件查询

命令格式：select * from 表名 where 条件;

键入命令后，显示指定表中符合条件的记录，如图28

图28

2.10条件查询

命令格式：select * from 表名 where 条件;

键入命令后，显示指定表中符合条件的记录，如图29

图29

2.11修改记录

命令格式：update 表名 set 更改值 where 条件;

修改指定表中符合条件的记录，键入如图命令后，回车显示如图30

图30

2.12删除记录

命令格式：delete from 表名 where 条件;

提示：如果清空记录，则用delete from 表名；

删除指定表中符合条件的记录，键入如图命令后，回车显示如图31。

图31

2.13创建数据库

命令格式：create database 库名;

创建数据库，键入如图命令后，回车成功显示如图32。

图32

2.14创建表

命令格式：create table 表名（字段信息）;

创建表，键入如图命令后，回车成功显示如图33。

图33

2.15删除表

命令格式：drop table 表名;

删除表，键入如图命令后，回车成功显示如图34。

图34

以上就是mysql的常用操作，请大家参照学习，如要详细学习，请参照第3节详细了解。

3、Mysql 详细说明

本章通过演示如何使用Mysql客户程序创造和使用一个简单的数据库，提供一个 Mysql 的入门教程。Mysql（有时称为“终端监视器”或只是“监视”)是一个交互式程序，允许你连接一个 Mysql 服务器，运行查询并察看结果。Mysql可以用于批模式：你预先把查询放在一个文件中，然后告诉Mysql执行文件的内容。使用Mysql的两个方法都在这里涉及。

为了看清由Mysql提供的一个选择项目表了，用--help选项调用它：

shell> Mysql --help

本章假定Mysql已经被安装在你的机器上，并且有一个 Mysql 服务器你可以连接。如果这不是真的，联络你的 Mysql 管理员。（如果你是管理员，你将需要请教这本手册的其他章节。）

本章描述建立和使用一个数据库的全过程。如果你仅仅对存取一个已经存在数据库感兴趣，你可能想要跳过描述怎样创建数据库及它所包含的表的章节。

既然本章本质上是一个教程，许多细节有必要被省略。对于这里所涉及的话题的更多信息，咨询本手册的相关章节。

3.1 连接与断开服务者

为了连接服务器，当你调用Mysql时，你通常将需要提供一个 Mysql 用户名和很可能，一个口令。如果服务器运行在不是你登录的一台机器上，你也将需要指定主机名。联系你的管理员以找出你应该使用什么连接参数进行连接(即，那个主机，用户名字和使用的口令)。一旦你知道正确的参数，你应该能象这样连接：

shell> Mysql -h host -u user -p

Enter password: ********

********代表你的口令；当Mysql显示Enter password:提示时输入它。

如果能工作，你应该看见Mysql>提示后的一些介绍信息：

shell> Mysql -h host -u user -p

Enter password: ********

Welcome to the Mysql monitor. Commands end with ; or \g.

Your Mysql connection id is 459 to server version: 3.22.20a-log

Type 'help' for help.

Mysql>

提示符告诉你Mysql准备为你输入命令。

一些 Mysql 安装允许用户以“anoymous”(匿名)用户连接在本地主机上运行的服务器。如果在你的机器是这种情况，你应该能通过没有任何选项地调用Mysql与该服务器连接：

shell> Mysql

在你成功地连接后，你可以在Mysql>提示下打入QUIT随时断开：

Mysql> QUIT

Bye

你也可以键入control-D断开。

在下列章节的大多数例子都假设你连接到服务器。由Mysql>提示指明他们。

3.2 输入查询

确保你连接上了服务器，如在先前的章节讨论的。这样做本身将不选择任何数据库来工作，但是那很好。从这点讲，知道关于如何出询问的一点知识，比马上跳至创建表、给他们装载数据并且从他们检索数据要来的重要写。本节描述输入命令的基本原则，使用几个查询，你能尝试让自己Mysql是如何工作的。

这是一个简单的命令，要求服务器告诉你它的版本号和当前日期。在Mysql>提示打入如下命令并按回车键：

Mysql> SELECT VERSION(), CURRENT_DATE;

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

| version() | CURRENT_DATE |

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

| 3.22.20a-log | 1999-03-19 |

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

1 row in set (0.01 sec)

Mysql>

这询问说明关于Mysql几件事:

  • 一个命令通常由SQL语句组成，随后有一个分号。（有一些例外不需要一个分号。早先提到的QUIT是他们之一。我们将以后看到其它。）
  • 当你发出一个命令时，Mysql发送它给服务器并显示结果，然后打出另外一个Mysql>显示它准备好接受另外的命令。
  • Mysql以一张表格(行和列)显示查询输出。第一行包含列的标签，随后的行是询问结果。通常， 列标签是你取自数据库表的列的名字。如果你正在检索一个表达式而非表列的值(如刚才的例子)，Mysql用表达式本身标记列。
  • Mysql显示多少行被返回，和查询花了多长执行，它给你提供服务器性能的一个大致概念。因为他们表示时钟时间(不是 CPU 或机器时间)，并且因为他们受到诸如服务器负载和网络延时的影响，因此这些值是不精确的。（为了简洁，在本章剩下的例子中不再显示“集合中的行”。）

关键词可以以任何大小写字符被输入。下列询问是等价的：

Mysql> SELECT VERSION(), CURRENT_DATE;

Mysql> select version(), current_date;

Mysql> SeLeCt vErSiOn(), current_DATE;

这里有另外一个查询，它说明你能将Mysql用作一个简单的计算器：

Mysql> SELECT SIN(PI()/4), (4+1)*5;

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

| SIN(PI()/4) | (4+1)*5 |

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

| 0.707107 | 25 |

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

至今显示的命令是相当短的，单行语句。你甚至能在单行上输入多条语句，只是以一个分号结束每一条：

Mysql> SELECT VERSION(); SELECT NOW();

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

| version() |

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

| 3.22.20a-log |

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

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

| NOW() |

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

| 1999-03-19 00:15:33 |

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

一个命令不必全在一个单独行给出，所以需要多行的较长命令不是一个问题。Mysql通过寻找终止的分号而不是寻找输入行的结束来决定你的语句在哪儿结束。（换句话说，Mysql接受自由格式输入：它收集输入行但执行他们直到它看见分号。）

这里是一个简单的多行语句的例子：

Mysql> SELECT

-> USER()

-> ,

-> CURRENT_DATE;

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

| USER() | CURRENT_DATE |

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

| joesmith@localhost | 1999-03-18 |

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

在这个例子中，在你输入一个多行查询的第一行后，要注意提示符如何从Mysql>变为->，这正是Mysql如何指出它没见到完整的语句并且正在等待剩余的部分。提示符是你的朋友，因为它提供有价值的反馈，如果你使用该反馈，你将总是知道Mysql正在等待什么。

如果你决定，你不想要执行你在输入过程中输入的一个命令，打入\c取消它：

Mysql> SELECT

-> USER()

-> \c

Mysql>

这里也要注意提示符，在你打入\c以后，它切换回到Mysql>，提供反馈以表明Mysql准备接受一个新命令。

下表显示出你可以看见的各个提示符并总结他们意味着Mysql在什么状态下：

提示符 | 意思
Mysql> | 准备好接受新命令
-> | 等待多行命令的下一行
'> | 等待下一行，收集以单引号(“'”)开始的字符串
"> | 等待下一行，收集以双引号(“"”)开始的字符串

当你打算在一个单行上发出一个命令时，多行语句通常“偶然”出现，但是忘记终止的分号。在这种情况中，Mysql等待进一步输入：

Mysql> SELECT USER()

->

如果这发生在你身上(你认为你输完了语句但是唯一的反应是一个->提示符)，很可能Mysql正在等待分号。如果你没有注意到提示符正在告诉你什么，在认识到你需要做什么之前，你可能花一会儿时间呆坐在那儿。进入一个分号完成语句，并且Mysql将执行它：

Mysql> SELECT USER()

-> ;

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

| USER() |

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

| joesmith@localhost |

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

'>和">提示符出现在在字符串收集期间。在 Mysql 中，你可以写由“'”或“"”字符括起来的字符串 (例如，'hello'或"goodbye")，并且Mysql让你进入跨越多行的字符串。当你看到一个'>或">提示符时，这意味着你已经输入了包含以“'”或“"”括号字符开始的字符串的一行，但是还没有输入终止字符串的匹配引号。如果你确实正在输入一个多行字符串，很好，但是果真如此吗？不尽然。更常见的，'>和">提示符显示你粗心地省掉了一个引号字符。例如：

Mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;

">

如果你输入该SELECT语句，然后按回车键并等待结果，什么都没有出现。不要惊讶，“为什么该查询这么长呢？”，注意">提示符提供的线索。它告诉你Mysql期望见到一个未终止字符串的余下部分。（你在语句中看见错误吗？字符串"Smith正好丢失第二个引号。）

走到这一步，你该做什么？最简单的是取消命令。然而，在这种情况下，你不能只是打入\c，因为Mysql作为它正在收集的字符串的一部分来解释它！相反，输入关闭的引号字符(这样Mysql知道你完成了字符串)，然后打入\c：

Mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;

"> "\c

Mysql>

提示符回到Mysql>，显示Mysql准备好接受一个新命令了。

知道'>和">提示符意味着什么是很重要的，因为如果你错误地输入一个未终止的字符串，任何比你下一步输入的行好象将要被Mysql忽略--包括包含QUIT的行！这可能相当含糊，特别是在你能取消当前命令前，如果你不知道你需要提出终止引号。

3.3 常用查询的例子

下面是一些学习如何用 Mysql 解决一些常见问题的例子。

一些例子使用数据库表“shop”，包含某个商人的每篇文章(物品号)的价格。假定每个商人的每篇文章有一个单独的固定价格，那么(物品，商人)是记录的主键。

你能这样创建例子数据库表：

CREATE TABLE shop (

article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,

dealer CHAR(20) DEFAULT '' NOT NULL,

price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,

PRIMARY KEY(article, dealer));

INSERT INTO shop VALUES

(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),

(3,'D',1.25),(4,'D',19.95);

好了，例子数据是这样的：

SELECT * FROM shop

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

| article | dealer | price |

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

| 0001 | A | 3.45 |

| 0001 | B | 3.99 |

| 0002 | A | 10.99 |

| 0003 | B | 1.45 |

| 0003 | C | 1.69 |

| 0003 | D | 1.25 |

| 0004 | D | 19.95 |

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

3.3.1 列的最大值

“最大的物品号是什么？”

SELECT MAX(article) AS article FROM shop

+---------+

| article |

+---------+

| 4 |

+---------+

3.3.2 拥有某个列的最大值的行

“找出最贵的文章的编号、商人和价格”

在ANSI-SQL中这很容易用一个子查询做到：

SELECT article, dealer, price

FROM shop

WHERE price=(SELECT MAX(price) FROM shop)

在 Mysql 中（还没有子查询)就用2步做到：

1. 用一个SELECT语句从表中得到最大值。

2. 使用该值编出实际的查询：

3. SELECT article, dealer, price

4. FROM shop

5. WHERE price=19.95

另一个解决方案是按价格降序排序所有行并用 Mysql 特定LIMIT子句只得到的第一行：

SELECT article, dealer, price

FROM shop

ORDER BY price DESC

LIMIT 1

注意:如果有多个最贵的文章( 例如每个19.95)，LIMIT解决方案仅仅显示他们之一！

3.3.3 列的最大值：按组：只有值

“每篇文章的最高的价格是什么？”

SELECT article, MAX(price) AS price

FROM shop

GROUP BY article

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

| article | price |

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

| 0001 | 3.99 |

| 0002 | 10.99 |

| 0003 | 1.69 |

| 0004 | 19.95 |

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

3.3.4 拥有某个字段的组间最大值的行

“对每篇文章，找出有最贵的价格的交易者。”

在ANSI SQL中，我可以用这样一个子查询做到：

SELECT article, dealer, price

FROM shop s1

WHERE price=(SELECT MAX(s2.price)

FROM shop s2

WHERE s1.article = s2.article)

在 Mysql 中，最好是分几步做到：

1. 得到一个表(文章，maxprice)。见8.3.4 拥有某个域的组间最大值的行。

2. 对每篇文章，得到对应于存储最大价格的行。

这可以很容易用一个临时表做到：

CREATE TEMPORARY TABLE tmp (

article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,

price DOUBLE(16,2) DEFAULT '0.00' NOT NULL);

LOCK TABLES article read;

INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;

SELECT article, dealer, price FROM shop, tmp

WHERE shop.article=tmp.articel AND shop.price=tmp.price;

UNLOCK TABLES;

DROP TABLE tmp;

如果你不使用一个TEMPORARY表，你也必须锁定“tmp”表。

“它能一个单个查询做到吗？”

是的，但是只有使用我称之为“MAX-CONCAT诡计”的一个相当低效的诡计：

SELECT article,

SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer,

0.00+LEFT( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price

FROM shop

GROUP BY article;

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

| article | dealer | price |

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

| 0001 | B | 3.99 |

| 0002 | A | 10.99 |

| 0003 | C | 1.69 |

| 0004 | D | 19.95 |

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

最后例子当然能通过在客户程序中分割连结的列使它更有效一点。

3.3.5 使用外键

不需要外键联结2个表。

Mysql唯一不做的事情是CHECK以保证你使用的键确实在你正在引用表中存在，并且它不自动从有一个外键定义的表中删除行。如果你象平常那样使用你的键值，它将工作得很好！

CREATE TABLE persons (

id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,

name CHAR(60) NOT NULL,

PRIMARY KEY (id)

);

CREATE TABLE shirts (

id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,

style ENUM('t-shirt', 'polo', 'dress') NOT NULL,

color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,

owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,

PRIMARY KEY (id)

);

INSERT INTO persons VALUES (NULL, 'Antonio Paz');

INSERT INTO shirts VALUES

(NULL, 'polo', 'blue', LAST_INSERT_ID()),

(NULL, 'dress', 'white', LAST_INSERT_ID()),

(NULL, 't-shirt', 'blue', LAST_INSERT_ID());

INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska');

INSERT INTO shirts VALUES

(NULL, 'dress', 'orange', LAST_INSERT_ID()),

(NULL, 'polo', 'red', LAST_INSERT_ID()),

(NULL, 'dress', 'blue', LAST_INSERT_ID()),

(NULL, 't-shirt', 'white', LAST_INSERT_ID());

SELECT * FROM persons;

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

| id | name |

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

| 1 | Antonio Paz |

| 2 | Lilliana Angelovska |

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

SELECT * FROM shirts;

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

| id | style | color | owner |

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

| 1 | polo | blue | 1 |

| 2 | dress | white | 1 |

| 3 | t-shirt | blue | 1 |

| 4 | dress | orange | 2 |

| 5 | polo | red | 2 |

| 6 | dress | blue | 2 |

| 7 | t-shirt | white | 2 |

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

SELECT s.* FROM persons p, shirts s

WHERE p.name LIKE 'Lilliana%'

AND s.owner = p.id

AND s.color &lt;&gt; 'white';

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

| id | style | color | owner |

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

| 4 | dress | orange | 2 |

| 5 | polo | red | 2 |

| 6 | dress | blue | 2 |

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

3.4 创造并使用一个数据库

既然你知道怎样输入命令，现在是存取一个数据库的时候了。

假定在你的家(你的“动物园”)中有很多宠物，并且你想追踪关于他们各种各样类型的信息。你可以通过创建表来保存你的数据并根据所需要的信息装载他们做到，然后你可以通过从表中检索数据来回答关于你的动物不同种类的问题。本节显示如何做到所有这些事情：

  • 怎样创建一个数据库
  • 怎样创建一个数据库表
  • 怎样装载数据到数据库表
  • 怎样以各种方法从表中检索数据
  • 怎样使用多个表

动物园数据库将会是简单的(故意的)，但是不难把它想象成可能用到相似类型数据库的真实世界情况。例如，这样的一个数据库能被一个农夫用来追踪家畜，或由一个兽医追踪病畜记录。

使用SHOW语句找出在服务器上当前存在什么数据库：

Mysql> SHOW DATABASES;

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

| Database |

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

| Mysql |

| test |

| tmp |

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

数据库列表可能在你的机器上是不同的，但是Mysql和test数据库很可能的在其间。Mysql是必需的，因为它描述用户存取权限，test数据库经常作为一个工作区提供给用户试试身手。

如果test数据库存在，尝试存取它：

Mysql> USE test

Database changed

注意，USE，类似QUIT，不需要一个分号。（如果你喜欢，你可以用一个分号终止这样的语句；这无碍)USE语句在使用上也有另外一个特殊的地方：它必须在一个单行上给出。

你可列在后面的例子中使用test数据库(如果你能访问它)，但是你在该数据库创建的任何东西可以被与访问它的其他人删除，为了这个原因，你可能应该询问你的 Mysql 管理员许可你自己使用的一个数据库。假定你想要调用你的menagerie，管理员需要执行一个这样的命令：

Mysql> GRANT ALL ON menagerie.* TO your_Mysql_name;

这里your_Mysql_name是分配给你的 Mysql 用户名。

3.4.1 创建并选用一个数据库

如果在设置你的权限时，管理员为你创建了数据库，你可以开始使用它。否则，你需要自己创建它：

Mysql> CREATE DATABASE menagerie;

在Unix下，数据库名字是区分大小写的(不像SQL关键词)，因此你必须总是以menagerie引用你的数据库，不是Menagerie、MENAGERIE或一些其他变种。对表名也是这样的。（在Windows下，该限制不适用，尽管你必须在一个给定的查询中使用同样的大小写来引用数据库和表。）

创建了一个数据库并不选定以使用它，你必须明确地做这件事。为了使menagerie称为当前的数据库，使用这个命令：

Mysql> USE menagerie

Database changed

你的数据库只需要创建一次，但是你必须在每次启动一个Mysql会话时为使用而选择它。你可以由发出上面一个USE语句做到。另外，当你调用时Mysql，你可在命令行上选择数据库，就在你可能需要提供的任何连接参数之后指定其名字。例如：

shell> Mysql -h host -u user -p menagerie

Enter password: ********

注意，menagerie不是你在刚才所示命令的口令。如果你想要在命令行上在-p选项后提供你的口令，你必须做到没有多余的空格(例如，如-pmypassword，不是-p mypassword)。然而，不建议把你的口令放在命令行上，因为这样做把它暴露出来，能被在你的机器上登录的其他用户窥探到。

3.4.2 创建一个数据库表

创建数据库是容易的部分，但是在这时它是空的，正如SHOW TABLES将告诉你：

Mysql> SHOW TABLES;

Empty set (0.00 sec)

较难的部分是决定你的数据库结构应该是什么：你将需要什么数据库表，和在他们中有什么样的列。

你将需要一个包含你每个宠物的记录的表。它可称为pet表，并且它应该包含，最少，每个动物的名字。因为名字本身不是很有趣，表应该包含另外的信息。例如，如果在你豢养宠物的家庭有超过一个人，你可能想要列出每个动物的主人。你可能也想要记录例如种类和性别的一些基本的描述信息。

年龄呢？那可能有趣，但是在一个数据库中存储不是一件好事情。年龄随着时间流逝而变化，这意味着你将要不断地更新你的记录。相反, 存储一个固定值例如生日比较好，那么，无论何时你需要年龄，你可以以当前日期和出生日期之间的差别来计算它。Mysql 为日期运算提供了函数，因此这并不困难。存储出生日期而非年龄也有其他优点：

  • 你可以将数据库用于这样的任务例如生成即将到来的宠物生日的提示。（如果你认为这类查询是点蠢，注意，这与在一个商务数据库来标示你不久要给它发出生日祝贺的客户的环境中是同一个问题，因为计算机帮助私人联络。）
  • 你可以相对于日期而不止是当前日期来计算年龄。例如，如果你在数据库存储死亡日期，你能容易计算一只宠物是何时多大死的。

你可能想到pet表中其他有用的其他类型信息，但是到目前为止这些现在是足够了：名字、主人、种类，性别、出生和死亡日期。

使用一个CREATE TABLE语句指定你的数据库表的布局：

Mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),

-> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

VARCHAR对name、owner和species列是个好的选择，因为列值将会是变长的。这些列的长度都不必是相同的，而且不必是20。你可以挑选从1到255的任何长度，无论哪个对你来说好象最合理。（如果你做了较差的选择，以后会变得你需要一个更长的字段，Mysql 提供一个ALTER TABLE语句。）

动物性表可以用许多方法表示，例如，"m"和"f"，或也许"male"和"female"。使用单个字符"m"和"f"是最简单的。

为birth和death列使用DATE数据类型是相当明显的选择。

既然你创建了一个表，SHOW TABLES应该产生一些输出：

Mysql> SHOW TABLES;

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

| Tables in menagerie |

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

| pet |

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

为了验证你的表是按你期望的方式被创建，使用一个DESCRIBE语句：

Mysql> DESCRIBE pet;

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

| Field | Type | Null | Key | Default | Extra |

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

| name | varchar(20) | YES | | NULL | |

| owner | varchar(20) | YES | | NULL | |

| species | varchar(20) | YES | | NULL | |

| sex | char(1) | YES | | NULL | |

| birth | date | YES | | NULL | |

| death | date | YES | | NULL | |

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

你能随时DESCRIBE，例如，如果你忘记在你表中的列的名字或他们是什么类型。

3.4.3 将数据装入一个数据库表

在你创建表后，你需要充实它。LOAD DATA和INSERT语句用于此。

假定你的宠物纪录描述如下。（观察到 Mysql 期望日期时以YYYY-MM-DD格式；这可能与你习惯的不同。）

name | owner | species | sex | birth | death
Fluffy | Harold | cat | f | 1993-02-04 |
Claws | Gwen | cat | m | 1994-03-17 |
Buffy | Harold | dog | f | 1989-05-13 |
Fang | Benny | dog | m | 1990-08-27 |
Bowser | Diane | dog | m | 1998-08-31 | 1995-07-29
Chirpy | Gwen | bird | f | 1998-09-11 |
Whistler | Gwen | bird |  | 1997-12-09 |
Slim | Benny | snake | m | 1996-04-29 |

因为你是从一张空表开始的，充实它的一个容易方法是创建包含为你的动物各一行一个文本文件，然后用一个单个语句装载文件的内容到表中。

你可以创建一个文本文件“pet.txt”，每行包含一个记录，用定位符(tab)把值分开，并且以在CREATE TABLE语句中列出的列次序给出。对于丢失的值(例如未知的性别，或仍然活着的动物的死亡日期)，你可以使用NULL值。为了在你的文本文件表示这些，使用\N。例如，对Whistler鸟的记录看起来像这样的(这里在值之间的空白是一个单个的定位字符)：

Whistler

Gwen

bird

\N

1997-12-09

\N

为了装载文本文件“pet.txt”到pet表中，使用这个命令：

Mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

如果你愿意，你能明确地在LOAD DATA语句中指出列值的分隔符和行尾标记，但是缺省是定位符和换行符。这些对争取读入文件“pet.txt”的语句是足够的。

当你想要一次增加一个新记录时，INSERT语句是有用的。在它最简单的形式，你为每一列提供值，以列在CREATE TABLE语句被列出的顺序。假定Diane把一只新仓鼠命名为Puffball，你可以使用一个这样INSERT语句增加一条新记录：

Mysql> INSERT INTO pet

-> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

注意，这里字符串和日期值被指定为引号扩起来的字符串。另外，用INSERT，你能直接插入NULL代表不存在的值。你不能使用\N，就像你用LOAD DATA做的那样。

从这个例子，你应该能看到涉及很多的键入用多个INSERT语句而非单个LOAD DATA语句装载你的初始记录。

3.4.4 从一个数据库表检索信息

SELECT语句被用来从一张表拉出信息。语句的一般格式是：

SELECT what_to_select

FROM which_table

WHERE conditions_to_satisfy

what_to_select指出你想要看到的，这可以是列的一张表，或*表明“所有的列”。which_table指出你想要从其检索数据的表。WHERE子句是可选的，如果它在，conditions_to_satisfy指定行必须满足的检索条件。

3.4.4.1 选择所有数据

SELECT最简单的形式是从一张表中检索每样东西：

Mysql> SELECT * FROM pet;

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

| name | owner | species | sex | birth | death |

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

| Fluffy | Harold | cat | f | 1993-02-04 | NULL |

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

| Fang | Benny | dog | m | 1990-08-27 | NULL |

| Bowser | Diane | dog | m | 1998-08-31 | 1995-07-29 |

| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |

| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |

| Slim | Benny | snake | m | 1996-04-29 | NULL |

| Puffball | Diane | hamster | f | 1999-03-30 | NULL |

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

如果你想要考察整个表，这种形式的SELECT是很有用的。例如，在你刚刚给它装载了你的初始数据集装以后。当它发生时，刚才显示的输出揭示了在你的数据文件的一个错误：在Bowser死了以后，它好象要出生了！请教你原来的家谱，你发现正确的出生年是1989，而不是1998。

至少有一些修正它的方法：

  • 编辑文件“pet.txt”改正错误，然后使用DELETE和LOAD DATA弄空表并且再次装载它:

· Mysql> DELETE FROM pet;

· Mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

然而, 如果你这样做，你必须重新输入Puffball记录。

  • 用一个UPDATE语句仅修正错误记录：

· Mysql> UPDATE pet SET birth = "1989-08-31" WHERE name = "Bowser";

如上所示，检索整个表是容易的，但是一般你不想那样做，特别地当表变得很大时。相反，你通常对回答一个特别的问题更感兴趣，在这种情况下你在你想要的信息上指定一些限制。让我们看一些他们回答有关你宠物的问题的选择查询。

3.4.4.2 选择特定行

你能从你的表中只选择特定的行。例如，如果你想要验证你对Bowser的出生日期所做的改变，像这样精选Bowser的记录：

Mysql> SELECT * FROM pet WHERE name = "Bowser";

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

| name | owner | species | sex | birth | death |

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

| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |

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

输出证实年份现在正确记录为1989，而不是1998。

字符串比较通常是大小些无关的，因此你可以指定名字为"bowser"、"BOWSER"等等，查询结果将是相同的。

你能在任何列上指定条件，不只是name。例如，如果你想要知道哪个动物在1998以后出生的，测试birth列：

Mysql> SELECT * FROM pet WHERE birth >= "1998-1-1";

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

| name | owner | species | sex | birth | death |

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

| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |

| Puffball | Diane | hamster | f | 1999-03-30 | NULL |

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

你能组合条件，例如，找出雌性的狗：

Mysql> SELECT * FROM pet WHERE species = "dog" AND sex = "f";

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

| name | owner | species | sex | birth | death |

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

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

上面的查询使用AND逻辑操作符，也有一个OR操作符：

Mysql> SELECT * FROM pet WHERE species = "snake" OR species = "bird";

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

| name | owner | species | sex | birth | death |

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

| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |

| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |

| Slim | Benny | snake | m | 1996-04-29 | NULL |

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

AND和OR可以混用。如果你这样做，使用括号指明条件应该如何被分组是一个好主意：

Mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m")

-> OR (species = "dog" AND sex = "f");

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

3.4.4.3 选择特定列

如果你不想要看到你的表的整个行，就命名你感兴趣的列，用逗号分开。例如，如果你想要知道你的动物什么时候出生的，精选name和birth列：

Mysql> SELECT name, birth FROM pet;

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

| name | birth |

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

| Fluffy | 1993-02-04 |

| Claws | 1994-03-17 |

| Buffy | 1989-05-13 |

| Fang | 1990-08-27 |

| Bowser | 1989-08-31 |

| Chirpy | 1998-09-11 |

| Whistler | 1997-12-09 |

| Slim | 1996-04-29 |

| Puffball | 1999-03-30 |

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

找出谁拥有宠物，使用这个查询：

Mysql> SELECT owner FROM pet;

+--------+

| owner |

+--------+

| Harold |

| Gwen |

| Harold |

| Benny |

| Diane |

| Gwen |

| Gwen |

| Benny |

| Diane |

+--------+

然而，注意到查询简单地检索每个记录的owner字段，并且他们中的一些出现多次。为了使输出减到最少，通过增加关键词DISTINCT检索出每个唯一的输出记录：

Mysql> SELECT DISTINCT owner FROM pet;

+--------+

| owner |

+--------+

| Benny |

| Diane |

| Gwen |

| Harold |

+--------+

你能使用一个WHERE子句把行选择与列选择相结合。例如，为了只得到狗和猫的出生日期，使用这个查询：

Mysql> SELECT name, species, birth FROM pet

-> WHERE species = "dog" OR species = "cat";

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

| name | species | birth |

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

| Fluffy | cat | 1993-02-04 |

| Claws | cat | 1994-03-17 |

| Buffy | dog | 1989-05-13 |

| Fang | dog | 1990-08-27 |

| Bowser | dog | 1989-08-31 |

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

3.4.4.4 排序行

你可能已经注意到前面的例子中结果行没有以特定的次序被显示。然而，当行以某个有意义的方式排序，检验查询输出通常是更容易的。为了排序结果，使用一个ORDER BY子句。

这里是动物生日，按日期排序：

Mysql> SELECT name, birth FROM pet ORDER BY birth;

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

| name | birth |

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

| Buffy | 1989-05-13 |

| Bowser | 1989-08-31 |

| Fang | 1990-08-27 |

| Fluffy | 1993-02-04 |

| Claws | 1994-03-17 |

| Slim | 1996-04-29 |

| Whistler | 1997-12-09 |

| Chirpy | 1998-09-11 |

| Puffball | 1999-03-30 |

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

为了以逆序排序，增加DESC（下降 )关键字到你正在排序的列名上：

Mysql> SELECT name, birth FROM pet ORDER BY birth DESC;

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

| name | birth |

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

| Puffball | 1999-03-30 |

| Chirpy | 1998-09-11 |

| Whistler | 1997-12-09 |

| Slim | 1996-04-29 |

| Claws | 1994-03-17 |

| Fluffy | 1993-02-04 |

| Fang | 1990-08-27 |

| Bowser | 1989-08-31 |

| Buffy | 1989-05-13 |

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

你能在多个列上排序。例如，按动物的种类排序，然后按生日，首先是动物种类中最年轻的动物，使用下列查询：

Mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;

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

| name | species | birth |

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

| Chirpy | bird | 1998-09-11 |

| Whistler | bird | 1997-12-09 |

| Claws | cat | 1994-03-17 |

| Fluffy | cat | 1993-02-04 |

| Fang | dog | 1990-08-27 |

| Bowser | dog | 1989-08-31 |

| Buffy | dog | 1989-05-13 |

| Puffball | hamster | 1999-03-30 |

| Slim | snake | 1996-04-29 |

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

注意DESC关键词仅适用于紧跟在它之前的列名字(birth)；species值仍然以升序被排序。

3.4.4.5 日期计算

Mysql 提供几个函数，你能用来执行在日期上的计算，例如，计算年龄或提取日期的部分。

为了决定你的每个宠物有多大，用出生日期和当前日期之间的差别计算年龄。通过变换2个日期到天数，取差值，并且用365除(在一年里的天数)：

Mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 FROM pet;

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

| name | (TO_DAYS(NOW())-TO_DAYS(birth))/365 |

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

| Fluffy | 6.15 |

| Claws | 5.04 |

| Buffy | 9.88 |

| Fang | 8.59 |

| Bowser | 9.58 |

| Chirpy | 0.55 |

| Whistler | 1.30 |

| Slim | 2.92 |

| Puffball | 0.00 |

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

尽管查询可行，关于它还有能被改进的一些事情。首先，如果行以某个次序表示，其结果能更容易被扫描。第二，年龄列的标题不是很有意义的。

第一个问题通过增加一个ORDER BY name子句按名字排序输出来解决。为了处理列标题，为列提供一个名字以便一个不同的标签出现在输出中(这被称为一个列别名)：

Mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age

-> FROM pet ORDER BY name;

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

| name | age |

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

| Bowser | 9.58 |

| Buffy | 9.88 |

| Chirpy | 0.55 |

| Claws | 5.04 |

| Fang | 8.59 |

| Fluffy | 6.15 |

| Puffball | 0.00 |

| Slim | 2.92 |

| Whistler | 1.30 |

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

为了按age而非name排序输出，只要使用一个不同ORDER BY子句：

Mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age

-> FROM pet ORDER BY age;

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

| name | age |

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

| Puffball | 0.00 |

| Chirpy | 0.55 |

| Whistler | 1.30 |

| Slim | 2.92 |

| Claws | 5.04 |

| Fluffy | 6.15 |

| Fang | 8.59 |

| Bowser | 9.58 |

| Buffy | 9.88 |

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

一个类似的查询可以被用来确定已经死亡动物的死亡年龄。你通过检查death值是否是NULL来决定那些是哪些动物，然后，对于那些有非NULL值，计算在death和birth值之间的差别：

Mysql> SELECT name, birth, death, (TO_DAYS(death)-TO_DAYS(birth))/365 AS age

-> FROM pet WHERE death IS NOT NULL ORDER BY age;

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

| name | birth | death | age |

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

| Bowser | 1989-08-31 | 1995-07-29 | 5.91 |

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

差询使用death IS NOT NULL而非death != NULL，因为NULL是特殊的值，这以后会解释。见8.4.4.6 用NULL值工作。

如果你想要知道哪个动物下个月过生日，怎么办？对于这类计算，年和天是无关的，你简单地想要提取birth列的月份部分。Mysql 提供几个日期部分的提取函数，例如YEAR()、MONTH()和DAYOFMONTH()。在这里MONTH()是适合的函数。为了看它怎样工作，运行一个简单的查询，显示birth和MONTH(birth)的值：

Mysql> SELECT name, birth, MONTH(birth) FROM pet;

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

| name | birth | MONTH(birth) |

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

| Fluffy | 1993-02-04 | 2 |

| Claws | 1994-03-17 | 3 |

| Buffy | 1989-05-13 | 5 |

| Fang | 1990-08-27 | 8 |

| Bowser | 1989-08-31 | 8 |

| Chirpy | 1998-09-11 | 9 |

| Whistler | 1997-12-09 | 12 |

| Slim | 1996-04-29 | 4 |

| Puffball | 1999-03-30 | 3 |

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

用下个月的生日找出动物也是容易的。假定当前月是4月，那么月值是4并且你寻找在5月出生的动物 (5月)， 象这样：

Mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;

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

| name | birth |

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

| Buffy | 1989-05-13 |

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

当然如果当前月份是12月，就有点复杂了。你不是只把加1到月份数(12)上并且寻找在13月出生的动物，因为没有这样的月份。相反，你寻找在1月出生的动物(1月) 。

你甚至可以编写查询以便不管当前月份是什么它都能工作。这种方法你不必在查询中使用一个特定的月份数字，DATE_ADD()允许你把时间间隔加到一个给定的日期。如果你把一个月加到NOW()值上，然后用MONTH()提取月份部分，结果产生寻找生日的月份：

Mysql> SELECT name, birth FROM pet

-> WHERE MONTH(birth) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));

完成同样任务的一个不同方法是加1以得出当前月份的下一个月(在使用取模函数(MOD)后，如果它当前是12，则“绕回”月份到值0)：

Mysql> SELECT name, birth FROM pet

-> WHERE MONTH(birth) = MOD(MONTH(NOW()), 12) + 1;

注意，MONTH返回在1和12之间的一个数字，且MOD(something,12)返回在0和11之间的一个数字，因此必须在MOD()以后加1，否则我们将从11月( 11 )跳到1月(1)。

3.4.4.6 NULL值操作

NULL值可能很奇怪直到你习惯于它。概念上，NULL意味着“没有值”或“未知值”，且它被看作有点与众不同的值。为了测试NULL，你不能使用算术比较运算符例如=、<或!=。为了说明它，试试下列查询：

Mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;

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

| 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |

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

| NULL | NULL | NULL | NULL |

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

很清楚你从这些比较中得到毫无意义的结果。相反使用IS NULL和IS NOT NULL操作符：

Mysql> SELECT 1 IS NULL, 1 IS NOT NULL;

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

| 1 IS NULL | 1 IS NOT NULL |

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

| 0 | 1 |

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

在 Mysql 中，0意味着假而1意味着真。

NULL这样特殊的处理是为什么，在前面的章节中，为了决定哪个动物不再是活着的，使用death IS NOT NULL而不是death != NULL是必要的。

3.4.4.7 模式匹配

Mysql 提供标准的SQL模式匹配，以及一种基于象Unix实用程序如vi、grep和sed的扩展正则表达式模式匹配的格式。

SQL的模式匹配允许你使用“_”匹配任何单个字符，而“%”匹配任意数目字符(包括零个字符)。在 Mysql中，SQL的模式缺省是忽略大小写的。下面显示一些例子。注意在你使用SQL模式时，你不能使用=或!=；而使用LIKE或NOT LIKE比较操作符。

为了找出以“b”开头的名字：

Mysql> SELECT * FROM pet WHERE name LIKE "b%";

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

| name | owner | species | sex | birth | death |

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

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |

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

为了找出以“fy”结尾的名字：

Mysql> SELECT * FROM pet WHERE name LIKE "%fy";

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

| name | owner | species | sex | birth | death |

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

| Fluffy | Harold | cat | f | 1993-02-04 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

为了找出包含一个“w”的名字：

Mysql> SELECT * FROM pet WHERE name LIKE "%w%";

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |

| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |

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

为了找出包含正好5个字符的名字，使用“_”模式字符：

Mysql> SELECT * FROM pet WHERE name LIKE "_____";

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

由 Mysql 提供的模式匹配的其他类型是使用扩展正则表达式。当你对这类模式进行匹配测试时，使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE，它们是同义词)。

扩展正则表达式的一些字符是：

  • “.”匹配任何单个的字符。
  • 一个字符类“[...]”匹配在方括号内的任何字符。例如，“[abc]”匹配“a”、“b”或“c”。为了命名字符的一个范围，使用一个“-”。“[a-z]”匹配任何小写字母，而“[0-9]”匹配任何数字。
  • “ * ”匹配零个或多个在它前面的东西。例如，“x*”匹配任何数量的“x”字符，“[0-9]*”匹配的任何数量的数字，而“.*”匹配任何数量的任何东西。
  • 正则表达式是区分大小写的，但是如果你希望，你能使用一个字符类匹配两种写法。例如，“[aA]”匹配小写或大写的“a”而“[a-zA-Z]”匹配两种写法的任何字母。
  • 如果它出现在被测试值的任何地方，模式就匹配(只要他们匹配整个值，SQL模式匹配)。
  • 为了定位一个模式以便它必须匹配被测试值的开始或结尾，在模式开始处使用“^”或在模式的结尾用“$”。

为了说明扩展正则表达式如何工作，上面所示的LIKE查询在下面使用REGEXP重写：

为了找出以“b”开头的名字，使用“^”匹配名字的开始并且“[bB]”匹配小写或大写的“b”：

Mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";

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

| name | owner | species | sex | birth | death |

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

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |

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

为了找出以“fy”结尾的名字，使用“$”匹配名字的结尾：

Mysql> SELECT * FROM pet WHERE name REGEXP "fy$";

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

| name | owner | species | sex | birth | death |

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

| Fluffy | Harold | cat | f | 1993-02-04 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

为了找出包含一个“w”的名字，使用“[wW]”匹配小写或大写的“w”：

Mysql> SELECT * FROM pet WHERE name REGEXP "[wW]";

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |

| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |

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

既然如果一个正规表达式出现在值的任何地方，其模式匹配了，就不必再先前的查询中在模式的两方面放置一个通配符以使得它匹配整个值，就像如果你使用了一个SQL模式那样。

为了找出包含正好5个字符的名字，使用“^”和“$”匹配名字的开始和结尾，和5个“.”实例在两者之间：

Mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

你也可以使用“{n}”“重复n次”操作符重写先前的查询：

Mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";

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

| name | owner | species | sex | birth | death |

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

| Claws | Gwen | cat | m | 1994-03-17 | NULL |

| Buffy | Harold | dog | f | 1989-05-13 | NULL |

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

3.4.4.8 行计数

数据库经常用于回答这个问题，“某个类型的数据在一张表中出现的频度?”例如，你可能想要知道你有多少宠物，或每位主人有多少宠物，或你可能想要在你的动物上施行各种类型的普查。

计算你拥有动物的总数字与“在pet表中有多少行?”是同样的问题，因为每个宠物有一个记录。COUNT()函数计数非NULL结果的数目，所以数你的动物的查询看起来像这样：

Mysql> SELECT COUNT(*) FROM pet;

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

| COUNT(*) |

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

| 9 |

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

在前面，你检索了拥有宠物的人的名字。如果你想要知道每个主人有多少宠物，你可以使用COUNT()函数：

Mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;

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

| owner | COUNT(*) |

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

| Benny | 2 |

| Diane | 2 |

| Gwen | 3 |

| Harold | 2 |

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

注意，使用GROUP BY对每个owner分组所有记录，没有它，你得到的一切是一条错误消息：

Mysql> SELECT owner, COUNT(owner) FROM pet;

ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)

with no GROUP columns is illegal if there is no GROUP BY clause

COUNT()和GROUP BY对以各种方式分类你的数据很有用。下列例子显示出实施动物普查操作的不同方式。

每种动物数量：

Mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;

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

| species | COUNT(*) |

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

| bird | 2 |

| cat | 2 |

| dog | 3 |

| hamster | 1 |

| snake | 1 |

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

每中性别的动物数量：

Mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;

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

| sex | COUNT(*) |

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

| NULL | 1 |

| f | 4 |

| m | 4 |

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

（在这个输出中，NULL表示“未知性别”。）

按种类和性别组合的动物数量：

Mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;

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

| species | sex | COUNT(*) |

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

| bird | NULL | 1 |

| bird | f | 1 |

| cat | f | 1 |

| cat | m | 1 |

| dog | f | 1 |

| dog | m | 2 |

| hamster | f | 1 |

| snake | m | 1 |

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

当你使用COUNT()时，你不必检索整个一张表。例如, 先前的查询，当只在狗和猫上施行时，看起来像这样：

Mysql> SELECT species, sex, COUNT(*) FROM pet

-> WHERE species = "dog" OR species = "cat"

-> GROUP BY species, sex;

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

| species | sex | COUNT(*) |

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

| cat | f | 1 |

| cat | m | 1 |

| dog | f | 1 |

| dog | m | 2 |

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

或，如果你仅需要知道已知性别的按性别的动物数目：

Mysql> SELECT species, sex, COUNT(*) FROM pet

-> WHERE sex IS NOT NULL

-> GROUP BY species, sex;

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

| species | sex | COUNT(*) |

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

| bird | f | 1 |

| cat | f | 1 |

| cat | m | 1 |

| dog | f | 1 |

| dog | m | 2 |

| hamster | f | 1 |

| snake | m | 1 |

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

3.4.5 使用多个数据库表

pet表追踪你有哪个宠物。如果你想要记录他们的其他信息，例如在他们一生中事件看兽医或何时后代出生，你需要另外的表。这张表应该像什么呢？

  • 它需要包含宠物名字因此你知道每个事件属于此动物。
  • 它需要一个日期因此你知道事件什么时候发生的。
  • 需要一个字段描述事件。
  • 如果你想要可分类事件，有一个事件类型字段将是有用的。

给出了这些考虑，为event表的CREATE TABLE语句可能看起来像这样：

Mysql> CREATE TABLE event (name VARCHAR(20), date DATE,

-> type VARCHAR(15), remark VARCHAR(255));

就象pet表，最容易的示通过创建包含信息的一个定位符分隔的文本文件装载初始记录：

Fluffy | 1995-05-15 | litter | 4 kittens, 3 female, 1 male
Buffy | 1993-06-23 | litter | 5 puppies, 2 female, 3 male
Buffy | 1994-06-19 | litter | 3 puppies, 3 female
Chirpy | 1999-03-21 | vet | needed beak straightened
Slim | 1997-08-03 | vet | broken rib
Bowser | 1991-10-12 | kennel |
Fang | 1991-10-12 | kennel |
Fang | 1998-08-28 | birthday | Gave him a new chew toy
Claws | 1998-03-17 | birthday | Gave him a new flea collar
Whistler | 1998-12-09 | birthday | First birthday

象这样装载记录：

Mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;

基于你从已经运行在pet表上的查询中学到的，你应该能执行在event表中记录的检索；原则是一样的。但是什么时候是event表本身不足以回答你可能问的问题呢？

当他们有了一窝小动物时，假定你想要找出每只宠物的年龄。 event表指出何时发生，但是为了计算母亲的年龄，你需要她的出生日期。既然它被存储在pet表中，为了查询你需要两张表：

Mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark

-> FROM pet, event

-> WHERE pet.name = event.name AND type = "litter";

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

| name | age | remark |

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

| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |

| Buffy | 4.12 | 5 puppies, 2 female, 3 male |

| Buffy | 5.10 | 3 puppies, 3 female |

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

关于该查询要注意的几件事情：

  • FROM子句列出两个表，因为查询需要从他们两个拉出信息。
  • 当组合(联结-join)来自多个表的信息时，你需要指定在一个表中的记录怎样能匹配其它表的记录。这很简单，因为它们都有一个name列。查询使用WHERE子句基于name值来匹配2个表中的记录。
  • 因为name列出现在两个表中，当引用列时，你一定要指定哪个表。这通过把表名附在列名前做到。

你不必有2个不同的表来执行一个联结。如果你想要将一个表的记录与同一个表的其他记录进行比较，联结一个表到自身有时是有用的。例如，为了在你的宠物之中繁殖配偶，你可以用pet联结自身来进行相似种类的雄雌配对：

Mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species

-> FROM pet AS p1, pet AS p2

-> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";

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

| name | sex | name | sex | species |

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

| Fluffy | f | Claws | m | cat |

| Buffy | f | Fang | m | dog |

| Buffy | f | Bowser | m | dog |

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

在这个查询中，我们为表名指定别名以便能引用列并且使得每一个列引用关联于哪个表实例更直观。

3.5 获得数据库和表的信息

如果你忘记一个数据库或表的名字，或一个给定的表的结构是什么(例如，它的列叫什么)，怎么办？ Mysql 通过提供数据库及其支持的表的信息的几个语句解决这个问题。

你已经见到了SHOW DATABASES，它列出由服务器管理的数据库。为了找出当前选择了哪个数据库，使用DATABASE()函数：

Mysql> SELECT DATABASE();

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

| DATABASE() |

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

| menagerie |

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

如果你还没选择任何数据库，结果是空的。

为了找出当前的数据库包含什么表(例如，当你不能确定一个表的名字)，使用这个命令：

Mysql> SHOW TABLES;

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

| Tables in menagerie |

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

| event |

| pet |

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

如果你想要知道一个表的结构，DESCRIBE命令是有很用的；它显示有关一个表的每个列的信息：

Mysql> DESCRIBE pet;

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

| Field | Type | Null | Key | Default | Extra |

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

| name | varchar(20) | YES | | NULL | |

| owner | varchar(20) | YES | | NULL | |

| species | varchar(20) | YES | | NULL | |

| sex | char(1) | YES | | NULL | |

| birth | date | YES | | NULL | |

| death | date | YES | | NULL | |

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

Field显示列名字，Type是为列的数据类型，Null表示列是否能包含NULL值，Key显示列是否被索引而Default指定列的缺省值。

如果你在一个表上有索引，SHOW INDEX FROM tbl_name生成有关它们的信息。

3.6 以批处理模式使用Mysql

在前面的章节中，你交互式地使用Mysql输入查询并且查看结果。你也可以以批模式运行Mysql。为了做到这些，把你想要运行的命令放在一个文件中，然后告诉Mysql从文件读取它的输入：

shell> Mysql < batch-file

如果你需要在命令行上指定连接参数，命令可能看起来像这样：

shell> Mysql -h host -u user -p < batch-file

Enter password: ********

当你这样使用Mysql时，你正在创建一个脚本文件，然后执行脚本。

为什么要使用一个脚本？有很多原因：

  • 如果你重复地运行查询(比如说，每天或每周)，把它做成一个脚本使得你在每次执行它时避免重新键入。
  • 你能通过拷贝并编辑脚本文件从类似的现有的查询生成一个新查询。
  • 当你正在开发查询时，批模式也是很有用的，特别对多行命令或多行语句序列。如果你犯了一个错误，你不必重新打入所有一切，只要编辑你的脚本来改正错误，然后告诉Mysql再次执行它。
  • 如果你有一个产生很多输出的查询，你可以通过一个分页器而不是盯着它翻屏到你屏幕的顶端来运行输出：

· shell> Mysql < batch-file | more

  • 你能捕捉输出到一个文件中进行更一步的处理：

· shell> Mysql < batch-file > Mysql.out

  • 你可以散发脚本给另外的人，因此他们也能运行命令。
  • 一些情况不允许交互地使用，例如, 当你从一个cron任务中运行查询时。在这种情况下，你必须使用批模式。

当你以批模式运行Mysql时，比起你交互地使用它时，其缺省输出格式是不同的(更简明些)。例如，当交互式运行SELECT DISTINCT species FROM pet时，输出看起来像这样：

+---------+

| species |

+---------+

| bird |

| cat |

| dog |

| hamster |

| snake |

+---------+

但是当以批模式运行时，像这样：

species

bird

cat

dog

hamster

snake

如果你想要在批模式中得到交互的输出格式，使用Mysql -t。为了回显以输出被执行的命令，使用Mysql -vvv。

3.7 双胞胎项目的查询（实例）

在Analytikerna 和 Lentus，我们为一个大的研究项目工程一直在做系统和现场工作。这个项目是Institute of Environmental Medicine at Karolinska Institutet Stockholm 和 the Section on Clinical Research in Aging and Psychology at the University of Southern California的合作项目。

双胞胎研究的更多信息可在下列链接找到：

http://www.imm.ki.se/TWIN/TWINUKW.HTM

项目的后面部分是用一个用Perl和 Mysql 编写的web接口来管理。

每天晚上所有会谈的数据被移入一个 Mysql 数据库。

3.7.1 找出所有非独处的双胞胎

下列查询用来决定谁进入项目的第二部分：

select

concat(p1.id, p1.tvab) + 0 as tvid,

concat(p1.christian_name, " ", p1.surname) as Name,

p1.postal_code as Code,

p1.city as City,

pg.abrev as Area,

if(td.participation = "Aborted", "A", " ") as A,

p1.dead as dead1,

l.event as event1,

td.suspect as tsuspect1,

id.suspect as isuspect1,

td.severe as tsevere1,

id.severe as isevere1,

p2.dead as dead2,

l2.event as event2,

h2.nurse as nurse2,

h2.doctor as doctor2,

td2.suspect as tsuspect2,

id2.suspect as isuspect2,

td2.severe as tsevere2,

id2.severe as isevere2,

l.finish_date

from

twin_project as tp

/* For Twin 1 */

left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab

left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab

left join harmony as h on tp.id = h.id and tp.tvab = h.tvab

left join lentus as l on tp.id = l.id and tp.tvab = l.tvab

/* For Twin 2 */

left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab

left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab

left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab

left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,

person_data as p1,

person_data as p2,

postal_groups as pg

where

/* p1 gets main twin and p2 gets his/her twin. */

/* ptvab is a field inverted from tvab */

p1.id = tp.id and p1.tvab = tp.tvab and

p2.id = p1.id and p2.ptvab = p1.tvab and

/* Just the sceening survey */

tp.survey_no = 5 and

/* Skip if partner died before 65 but allow emigration (dead=9) */

(p2.dead = 0 or p2.dead = 9 or

(p2.dead = 1 and

(p2.death_date = 0 or

(((to_days(p2.death_date) - to_days(p2.birthday)) / 365)

>= 65))))

and

(

/* Twin is suspect */

(td.future_contact = 'Yes' and td.suspect = 2) or

/* Twin is suspect - Informant is Blessed */

(td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or

/* No twin - Informant is Blessed */

(ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or

/* Twin broken off - Informant is Blessed */

(td.participation = 'Aborted'

and id.suspect = 1 and id.future_contact = 'Yes') or

/* Twin broken off - No inform - Have partner */

(td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))

and

l.event = 'Finished'

/* Get at area code */

and substring(p1.postal_code, 1, 2) = pg.code

/* Not already distributed */

and (h.nurse is NULL or h.nurse=00 or h.doctor=00)

/* Has not refused or been aborted */

and not (h.status = 'Refused' or h.status = 'Aborted'

or h.status = 'Died' or h.status = 'Other')

order by

tvid;

一些解释：

concat(p1.id, p1.tvab) + 0 as tvid

我们想要在id和tvab的连接上以数字序排序。结果加0使得 Mysql 把结果当作一个数字。

列id

这标识一对双胞胎。它是所有表中的一个键。

列tvab

这标识双胞胎中的一个。它有值1或2。

列ptvab

这是tvab一个逆。当tvab是1，它是2，并且反过来也如此。它存在以保存键入并且使它更容易为 Mysql 优化查询。

这个查询表明，怎样用联结(p1和p2)从同一个表中查找表。在例子中，这被用来检查双胞胎的一个是否在65岁前死了。如果因此，行不返回。

上述所有双胞胎信息存在于所有表中。我们在id,tvab两者上的键值（所有表)和在id,ptvab上的键(person_data)以使查询更快。

在我们的生产机器上(一台200MHz UltraSPARC)，这个查询返回大约 150-200 行并且不超过一秒的时间。

上面所用的表的当前记录数是：

表 | 行数
person_data | 71074
lentus | 5291
twin_project | 5286
twin_data | 2012
informant_data | 663
harmony | 381
postal_groups | 100

3.7.2 显示关于双胞胎近况的表

每一次会面以一个称为event的状态码结束。下面显示的查询被用来显示按事件组合的所有双胞胎的表。这表明多少对双胞胎已经完成，多少对的其中之一已完成而另一个拒绝了，等等。

select

t1.event,

t2.event,

count(*)

from

lentus as t1,

lentus as t2,

twin_project as tp

where

/* We are looking at one pair at a time */

t1.id = tp.id

and t1.tvab=tp.tvab

and t1.id = t2.id

/* Just the sceening survey */

and tp.survey_no = 5

/* This makes each pair only appear once */

and t1.tvab='1' and t2.tvab='2'

group by

t1.event, t2.event;

附mysql简明教程：
一、连接MYSQL。
格式： mysql -h主机地址 -u用户名 －p用户密码
1、例1：连接到本机上的MYSQL。
首先在打开DOS窗口，然后进入目录 mysqlbin，再键入命令mysql -uroot -p，回车后提示你输密码，如果刚安装好MYSQL，超级用户root是没有密码的，故直接回车即可进入到MYSQL中了，MYSQL的提示符是：mysql>
2、例2：连接到远程主机上的MYSQL。假设远程主机的IP为：110.110.110.110，用户名为root,密码为abcd123。则键入以下命令：
mysql -h110.110.110.110 -uroot -pabcd123
（注:u与root可以不用加空格，其它也一样）
3、退出MYSQL命令： exit （回车）
二、修改密码。
格式：mysqladmin -u用户名 -p旧密码 password 新密码
1、例1：给root加个密码ab12。首先在DOS下进入目录mysqlbin，然后键入以下命令
mysqladmin -uroot -password ab12
注：因为开始时root没有密码，所以-p旧密码一项就可以省略了。
2、例2：再将root的密码改为djg345。
mysqladmin -uroot -pab12 password djg345
三、增加新用户。（注意：和上面不同，下面的因为是MYSQL环境中的命令，所以后面都带一个分号作为命令结束符）
格式：grant select on 数据库.* to 用户名@登录主机 identified by "密码"
例1、增加一个用户test1密码为abc，让他可以在任何主机上登录，并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL，然后键入以下命令：
grant select,insert,update,delete on *.* to test1@"%" Identified by "abc";
但例1增加的用户是十分危险的，你想如某个人知道test1的密码，那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了，解决办法见例2。
例2、增加一个用户test2密码为abc,让他只可以在localhost上登录，并可以对数据库mydb进行查询、插入、修改、删除的操作（localhost指本地主机，即MYSQL数据库所在的那台主机），这样用户即使用知道test2的密码，他也无法从internet上直接访问数据库，只能通过MYSQL主机上的web页来访问了。
grant select,insert,update,delete on mydb.* to test2@localhost identified by "abc";
如果你不想test2有密码，可以再打一个命令将密码消掉。
grant select,insert,update,delete on mydb.* to test2@localhost identified by "";

在上篇我们讲了登录、增加用户、密码更改等问题。下篇我们来看看MYSQL中有关数据库方面的操作。注意：你必须首先登录到MYSQL中，以下操作都是在MYSQL的提示符下进行的，而且每个命令以分号结束。

一、操作技巧
1、如果你打命令时，回车后发现忘记加分号，你无须重打一遍命令，只要打个分号回车就可以了。也就是说你可以把一个完整的命令分成几行来打，完后用分号作结束标志就OK。
2、你可以使用光标上下键调出以前的命令。但以前我用过的一个MYSQL旧版本不支持。我现在用的是mysql-3.23.27-beta-win。

二、显示命令
1、显示数据库列表。
show databases;
刚开始时才两个数据库：mysql和test。mysql库很重要它里面有MYSQL的系统信息，我们改密码和新增用户，实际上就是用这个库进行操作。
2、显示库中的数据表：
use mysql； ／／打开库，学过FOXBASE的一定不会陌生吧
show tables;
3、显示数据表的结构：
describe 表名;
4、建库：
create database 库名;
5、建表：
use 库名；
create table 表名 (字段设定列表)；
6、删库和删表:
drop database 库名;
drop table 表名；
7、将表中记录清空：
delete from 表名;
8、显示表中的记录：
select * from 表名;

三、一个建库和建表以及插入数据的实例
drop database if exists school; //如果存在SCHOOL则删除
create database school; //建立库SCHOOL
use school; //打开库SCHOOL
create table teacher //建立表TEACHER
(
id int(3) auto_increment not null primary key,
name char(10) not null,
address varchar(50) default '深圳',
year date
); //建表结束
//以下为插入字段
insert into teacher valuess('','glchengang','深圳一中','1976-10-10');
insert into teacher valuess('','jack','深圳一中','1975-12-23');

注：在建表中（1）将ID设为长度为3的数字字段:int(3)并让它每个记录自动加一:auto_increment并不能为空:not null而且让他成为主字段primary key（2）将NAME设为长度为10的字符字段（3）将ADDRESS设为长度50的字符字段，而且缺省值为深圳。varchar和char有什么区别呢，只有等以后的文章再说了。 （4）将YEAR设为日期字段。
如果你在mysql提示符键入上面的命令也可以，但不方便调试。你可以将以上命令原样写入一个文本文件中假设为school.sql，然后复制到c:\下，并在DOS状态进入目录\mysql\bin，然后键入以下命令：
mysql -uroot -p密码 < c:\school.sql
如果成功，空出一行无任何显示；如有错误，会有提示。（以上命令已经调试，你只要将//的注释去掉即可使用）。

四、将文本数据转到数据库中
1、文本数据应符合的格式：字段数据之间用tab键隔开，null值用\n来代替.
例：
3 rose 深圳二中 1976-10-10
4 mike 深圳一中 1975-12-23
2、数据传入命令 load data local infile "文件名" into table 表名;
注意：你最好将文件复制到\mysql\bin目录下，并且要先用use命令打表所在的库 。

五、备份数据库：（命令在DOS的\mysql\bin目录下执行）
mysqldump --opt school>school.bbb
注释:将数据库school备份到school.bbb文件，school.bbb是一个文本文件，文件名任取，打开看看你会有新发现。

后记：其实MYSQL的对数据库的操作与其它的SQL类数据库大同小异，您最好找本将SQL的书看看。我在这里只介绍一些基本的，其实我也就只懂这些了，呵呵。最好的MYSQL教程还是“晏子“译的“MYSQL中文参考手册“不仅免费每个相关网站都有下载，而且它是最权威的。可惜不是象"PHP4中文手册"那样是chm的格式，在查找函数命令的时候不太方便


Mysql 数据库支持库使用及edb to Mysql转换程序使

Mysql 数据库支持库使用及edb to Mysql转换程序使用

步骤要求：

必要工作：首先装好mysql,下载测试例程，用易语言打开

1、运行程序后，连接数据库，显示如图1

图1

2、选择打开数据库，如图2

图2

3、选择edb结构建mysql表，如图3，提示输入表名。

图3

4、创建表成功提示，如图4。

图4

5、选择 edb转换到mysql，成功后显示如图5。

图5

好了剩下的工作自己做啦，哇塞，都21点了偶吃饭去啦 :)