原文:ZetCode
协议:CC BY-NC-SA 4.0
MySQL Ruby 教程
原文: http://zetcode.com/db/mysqlrubytutorial/
这是针对 MySQL 数据库的 Ruby 编程教程。 它涵盖了利用 Ruby 进行 MySQL 编程的底子。 它利用mysql模块。 这些示例是在 Ubuntu Linux 上创建和测试的。
在 ZetCode 上有一个类似的 MySQL C API 教程, MySQL Visual Basic 教程或 MySQL Python 教程。
您也可以考虑检察 MySQL 教程。
MySQL & Ruby
MySQL 是领先的开源数据库管理系统。 它是一个多用户,多线程的数据库管理系统。 MySQL 在网络上特别流行。 它是由 Linux,Apache,MySQL 和 PHP 组成的非常流行的LAMP平台的一部分。 目前,MySQL 由 Oracle 拥有。 MySQL 数据库在最重要的 OS 平台上可用。Ruby 是一种动态的,反射性的,通用的面向对象的编程语言。 近来,它在 Web 编程中变得非常流行,这主要归功于 Ruby on Rails 框架的乐成。
mysql 模块
mysql模块是 MySQL 服务器的 Ruby 接口。 它为 Ruby 步伐提供的功能与 MySQL C API 为 C 步伐提供的功能相同。
- $ sudo gem1.9 install mysql
复制代码 在这里,我们为 MySQL 数据库安装 Ruby 模块。
开始之前
我们将创建一个新的数据库用户和一个新的数据库。 为此,我们利用mysql客户端步伐。
- $ mysql -u root -p
- Enter password:
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 30
- Server version: 5.0.67-0ubuntu6 (Ubuntu)
- Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
- mysql> SHOW DATABASES;
- +--------------------+
- | Database |
- +--------------------+
- | information_schema |
- | mysql |
- +--------------------+
- 2 rows in set (0.00 sec)
复制代码 我们利用 root 帐户连接到 MySQL 服务器。 我们用SHOW DATABASES语句显示所有可用的数据库。
- mysql> CREATE DATABASE mydb;
- Query OK, 1 row affected (0.02 sec)
复制代码 我们创建一个新的mydb数据库。 在整个教程中,我们将利用此数据库。
- mysql> CREATE USER user12@localhost IDENTIFIED BY '34klq*';
- Query OK, 0 rows affected (0.00 sec)
- mysql> USE mydb;
- Database changed
- mysql> GRANT ALL ON mydb.* to user12@localhost;
- Query OK, 0 rows affected (0.00 sec)
- mysql> quit;
- Bye
复制代码 我们创建一个新的数据库用户。 我们授予该用户mydb数据库所有表的所有特权。
MySQL 服务器版本
在第一个示例中,我们将获取 MySQL 数据库的版本。
- #!/usr/bin/ruby
- require 'mysql'
- begin
- con = Mysql.new 'localhost', 'user12', '34klq*'
- puts con.get_server_info
- rs = con.query 'SELECT VERSION()'
- puts rs.fetch_row
-
- rescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 在此脚本中,我们获取服务器版本。 我们用两种不同的方式来做。
我们导入mysql模块。 该模块具有效于 MySQL 数据库的类和方法。
- con = Mysql.new 'localhost', 'user12', '34klq*'
复制代码 我们创建连接对象。 参数包括主机名,用户名和密码。 在我们的情况下,主机名是localhost,例如我们的电脑。
我们创建的 Mysql 对象具有get_server_info方法。 它返回安装的 MySQL 服务器的版本。
- rs = con.query 'SELECT VERSION()'
- puts rs.fetch_row
-
复制代码 获取版本的另一种方法是执行SELECT VERSION() SQL 语句。 我们获取数据。 由于只检索一条记录,因此我们称为fetch_row方法。
- rescue Mysql::Error => e
- puts e.errno
- puts e.error
复制代码 我们检查错误。 这很重要,因为利用数据库轻易出错。
- ensure
- con.close if con
- end
复制代码 最后,我们释放资源。
输出可能类似于上面。
列出数据库
MySQL Ruby 模块具有list_dbs方法,该方法返回可用的数据库。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- con.list_dbs.each do |db| puts db endrescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 在此脚本中,我们在 MySQL 服务器上打印所有可用的数据库。
- con.list_dbs.each do |db|
- puts db
- end
复制代码 list_dbs方法返回可用数据库名称的数组。 利用数组的each方法,我们将数组的每个项目打印到控制台。
- $ ./listdb.rb
- information_schema
- mydb
- test
- world
复制代码 在我的系统上,我创建了上述数据库。
创建并填充表
我们创建一个表,并用一些数据填充它。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' con.query("CREATE TABLE IF NOT EXISTS \
- Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
- con.query("INSERT INTO Writers(Name) VALUES('Jack London')") con.query("INSERT INTO Writers(Name) VALUES('Honore de Balzac')") con.query("INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger')") con.query("INSERT INTO Writers(Name) VALUES('Emile Zola')") con.query("INSERT INTO Writers(Name) VALUES('Truman Capote')") rescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 我们创建一个Writers表,并向其中添加五个作者。
- con.query("CREATE TABLE IF NOT EXISTS \
- Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
复制代码 要执行 SQL 语句,我们利用query方法。 该 SQL 语句创建一个称为Writers的新数据库表。 它有两列。 ID 和名称。
- con.query("INSERT INTO Writers(Name) VALUES('Jack London')")
- con.query("INSERT INTO Writers(Name) VALUES('Honore de Balzac')")
- ...
复制代码 我们利用INSERT语句在表中插入作者。 在这里,我们添加两行。
- mysql> SELECT * FROM Writers;
- +----+-------------------+
- | Id | Name |
- +----+-------------------+
- | 1 | Jack London |
- | 2 | Honore de Balzac |
- | 3 | Lion Feuchtwanger |
- | 4 | Emile Zola |
- | 5 | Truman Capote |
- +----+-------------------+
- 5 rows in set (0.00 sec)
复制代码 执行脚本后,我们利用mysql客户端工具从Writers表中选择所有数据。
检索数据
现在我们已经将一些数据插入数据库中,我们可以将其取回。
- #!/usr/bin/rubyrequire "mysql"begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query("SELECT * FROM Writers")
- n_rows = rs.num_rows
- puts "There are #{n_rows} rows in the result set" n_rows.times do puts rs.fetch_row.join("\s")
- endrescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 在此示例中,我们从 Writers 表中检索所有数据。
- con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb'
复制代码 构造器的最后一个参数是我们要连接的数据库名称。
- rs = con.query("SELECT * FROM Writers")
复制代码 该 SQL 语句从Writers表中选择所有数据。
我们利用结果集对象的num_rows方法得到结果集中的行数。
- n_rows.times do
- puts rs.fetch_row.join("\s")
- end
复制代码 在这里,我们利用fetch_row方法获取每一行。 它返回一行作为字段数组。 默认情况下,打印时这些字段用换行分隔。 利用join方法,我们将每一行打印在一行上。 字段由一个空格分隔。
- $ ./retrieve1.rb
- There are 5 rows in the result set
- 1 Jack London
- 2 Honore de Balzac
- 3 Lion Feuchtwanger
- 4 Emile Zola
- 5 Truman Capote
复制代码 接下来,我们介绍另一种从表中检索数据的方法。
- #!/usr/bin/rubyrequire "mysql"begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query("SELECT * FROM Writers")
- rs.each do |row| puts row.join("\s") endrescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 我们从Writers表中打印所有数据。 这次我们利用结果集的每种方法遍历数据。
- rs.each do |row|
- puts row.join("\s")
- end
复制代码 我们利用每种方法遍历结果集。
- $ ./retrieve2.rb
- 1 Jack London
- 2 Honore de Balzac
- 3 Lion Feuchtwanger
- 4 Emile Zola
- 5 Truman Capote
复制代码 这是示例的输出。
我们可以以 Ruby 哈希的情势遍历数据。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)"
- puts "We have #{rs.num_rows} row(s)" rs.each_hash do |row| puts row['Id'] + " " + row['Name'] end rescue Mysql::Error => e puts e ensure
- con.close if con
- end
复制代码 在示例中,我们利用each_hash迭代器。 可以通过列名称检索结果集中的记录。
- rs.each_hash do |row|
- puts row['Id'] + " " + row['Name']
- end
复制代码 我们利用each_hash方法检察结果集。 返回的每一行都是一个 Ruby 哈希; 键值对的集合。 键是列名。
- $ ./retrieve3.rb
- We have 3 row(s)
- 1 Jack London
- 2 Honore de Balzac
- 3 Lion Feuchtwanger
复制代码 示例的输出。
多个语句
MySQL 支持多条语句执行。 必须通过特殊选项启用它。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' con.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
- rs = con.query "SELECT Name FROM Writers WHERE Id=1; SELECT Name FROM Writers WHERE Id=2; SELECT Name FROM Writers WHERE Id=3" puts rs.fetch_row
- while con.next_result rs = con.store_result puts rs.fetch_row
- end rescue Mysql::Error => e
- puts e.errno
- puts e.error
- ensure
- con.close if con
- end
复制代码 在此示例中,我们在一个查询中具有三个SELECT语句。
- con.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
复制代码 起首,我们须要利用Mysql::OPTION_MULTI_STATEMENTS_ON启用多条语句处置惩罚。
- rs = con.query "SELECT Name FROM Writers WHERE Id=1;
- SELECT Name FROM Writers WHERE Id=2;
- SELECT Name FROM Writers WHERE Id=3"
复制代码 在这里,我们界说了三个SELECT语句。 它们之间用分号分隔。
查询方法返回第一个结果集。 我们从该结果集中获取一行。
- while con.next_result
- rs = con.store_result
- puts rs.fetch_row
- end
复制代码 我们将得到其他结果集,直到没有更多要处置惩罚的语句为止。
- $ ./multiplest.rb
- Jack London
- Honore de Balzac
- Lion Feuchtwanger
复制代码 运行示例。
元数据
元数据是有关数据库中数据的信息。 MySQL 系统中的元数据包罗有关存储数据的表和列的信息。 受 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也属于元数据。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)"
- puts "We have #{con.field_count} fields" puts "We have #{rs.num_rows} row(s)" puts rs.fetch_row.join("\s")
- rescue Mysql::Error => e puts e ensure
- con.close if con
- end
复制代码 在此脚本中,我们从 SQL 查询中找出行数和列数。
- rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)"
复制代码 该 SQL 语句返回三行。 每行有两列。
- puts "We have #{con.field_count} fields"
- puts "We have #{rs.num_rows} row(s)"
复制代码 这两行返回结果集中的列数和行数。 请留意,此处的字段是列的同义词。 返回的数据是元数据。
- puts rs.fetch_row.join("\s")
复制代码 在这里,我们从结果集中返回一行。 这是存储在我们数据库表中的原始数据。
对于INSERT,DELETE和UPDATE语句,有一种称为rows_affected的方法。 此方法返回受这三个语句影响的行数。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' con.query "DELETE FROM Writers WHERE Id IN (1, 2, 3)"
- puts "The query has affected #{con.affected_rows} rows"
- rescue Mysql::Error => e puts e ensure
- con.close if con
- end
复制代码 在我们的示例中,我们从Writers表中删除了前三行。
- con.query "DELETE FROM Writers WHERE Id IN (1, 2, 3)"
复制代码 一个 SQL 语句,该语句删除Writers表的前三行。
- puts "The query has affected #{con.affected_rows} rows"
复制代码 在这里,我们得到受上述 SQL 语句影响的行数。 该数字属于元数据。
- $ ./affected.rb
- The query has affected 3 rows
- mysql> SELECT * FROM Writers;
- +----+---------------+
- | Id | Name |
- +----+---------------+
- | 4 | Emile Zola |
- | 5 | Truman Capote |
- +----+---------------+
- 2 rows in set (0.00 sec)
复制代码 我们执行受影响的.rb脚本,并检查Writers表中的更改。 三行已被删除。
在下一个示例中,我们将检查有关字段的元数据。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id=1"
- field = rs.fetch_field_direct 1
- puts "Table name: #{field.table}" puts "Field name: #{field.name}" puts "Field length: #{field.length}" puts "Field type: #{field.type}"rescue Mysql::Error => e puts eensure
- con.close if con
- end
复制代码 我们从数据库中得到一条记录。 我们得到字段的表名,列名,长度和类型。
- rs = con.query "SELECT * FROM Writers WHERE Id=1"
复制代码 该查询返回一行。 它有两列。
- field = rs.fetch_field_direct 1
复制代码 利用fetch_field_direct方法,我们得到了一条特定的记录。 更准确地说,记录来自第一行第二列的交集。
- puts "Table name: #{field.table}"
- puts "Field name: #{field.name}"
- puts "Field length: #{field.length}"
- puts "Field type: #{field.type}"
复制代码 我们利用字段对象的属性读取器获取元数据。
- $ ./metadata.rb
- Table name: Writers
- Field name: Name
- Field length: 25
- Field type: 253
复制代码 这是示例的输出。
在与元数据有关的最后一个示例中,我们将打印表中的所有行及其列名。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query "SELECT * FROM Writers" fields = rs.fetch_fields puts "%3s %s" % [fields[0].name, fields[1].name] rs.each_hash do |row| puts "%3s %s" % [row['Id'], row['Name']] endrescue Mysql::Error => e puts eensure
- con.close if con
- end
复制代码 我们将Writers表的内容打印到控制台。 现在,我们也包括列的名称。
- fields = rs.fetch_fields
- puts "%3s %s" % [fields[0].name, fields[1].name]
复制代码 第一步,我们获取列名。 它们利用尺度的 Ruby 字符串格式化函数进行打印。
- rs.each_hash do |row|
- puts "%3s %s" % [row['Id'], row['Name']]
- end
复制代码 现在,将获取数据并将其打印到控制台。 我们也进行一些格式化。
- $ ./columnheaders.rb
- Id Name
- 1 Jack London
- 2 Honore de Balzac
- 3 Lion Feuchtwanger
- 4 Emile Zola
- 5 Truman Capote
复制代码 脚本的输出。
准备语句
现在,我们将以准备语句来关注自己。 在编写准备语句时,我们利用占位符,而不是直接将值写入语句中。 预准备的语句可进步安全性和性能。
- #!/usr/bin/rubyrequire 'mysql'
- name = "Stefan Zweig"begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' pst = con.prepare "INSERT INTO Writers(Name) VALUES(?)"
- pst.execute name
- rescue Mysql::Error => e puts e ensure con.close if con pst.close if pst
- end
复制代码 在上面的示例中,我们将新行插入Writers表。 我们利用准备语句。
- pst = con.prepare "INSERT INTO Writers(Name) VALUES(?)"
复制代码 prepare方法用于创建准备语句。 ?字符是一个占位符。 稍后,我们将一个值绑定到该占位符。
我们将名称变量中的值绑定到占位符,并执行准备语句。
准备语句已关闭。
- mysql> SELECT * FROM Writers;
- +----+-------------------+
- | Id | Name |
- +----+-------------------+
- | 1 | Jack London |
- | 2 | Honore de Balzac |
- | 3 | Lion Feuchtwanger |
- | 4 | Emile Zola |
- | 5 | Truman Capote |
- | 6 | Stefan Zweig |
- +----+-------------------+
- 6 rows in set (0.00 sec)
复制代码 脚本乐成运行后,我们在Writers表中看到一个新作者。
写图像
有些人喜欢将其图像放入数据库中,有些人则希望将其保留在文件系统中以供其应用利用。 当我们处置惩罚大量图像时,会出现技能难题。 图像是二进制数据。 MySQL 数据库具有一种特殊的数据类型来存储称为BLOB(二进制大对象)的二进制数据。
- mysql> CREATE TABLE Images(Id INT PRIMARY KEY AUTO_INCREMENT, Data MEDIUMBLOB);
- Query OK, 0 rows affected (0.06 sec)
复制代码 对于此示例,我们创建一个名为Images的新表。
- #!/usr/bin/rubyrequire 'mysql'
- begin fin = File.open("woman.jpg" , "rb") img = fin.readrescue SystemCallError => e puts eensure fin.close if fin endbegin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' pst = con.prepare("INSERT INTO Images SET Data='%s'" % img.unpack('H*'))
- pst.execute rescue Mysql::Error => e puts eensure con.close if con pst.close if pst
- end
复制代码 在上面的脚本中,我们读取 JPG 图像并将其插入到Images表中。
- fin = File.open("woman.jpg" , "rb")
- img = fin.read
复制代码 我们打开并阅读图像。 read方法以字符串情势返回数据。
- pst = con.prepare("INSERT INTO Images SET Data='%s'" % img.unpack('H*'))
复制代码 将该字符串数据放入准备语句中。 在这样做之前,利用 Ruby 字符串对象的unpack方法对其进行解码。 解码是必须的,因为图像对象具有许多无法正常处置惩罚的特殊字符。
读取图像
在前面的示例中,我们已将图像插入数据库表中。 现在,我们将从表中读取图像。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' rs = con.query "SELECT Data FROM Images LIMIT 1"
- f = File.new "woman2.jpg", "wb"
- f.write rs.fetch_row.pack 'H*'
- rescue Mysql::Error, SystemCallError => e puts eensure con.close if con f.close if fend
复制代码 我们从图片表中读取了一张图片。
- rs = con.query "SELECT Data FROM Images LIMIT 1"
复制代码 我们从表中选择一条记录。
- f = File.new "woman2.jpg", "wb"
复制代码 我们创建一个可写的二进制文件。
- f.write rs.fetch_row.pack 'H*'
复制代码 我们从先前的 SQL 语句中获取数据并将其写入文件。 fetch_row方法返回一个数组对象。 在将数据写入文件之前,利用数组的pack方法将其放回原始格式。 对于解码和反转这两种操作,我们利用相同的指令'H*'。 它代表十六进制字符串。
现在我们在当前目录中应该有一个名为woman2.jpg的映像。 我们可以检查它是否与我们插入表中的图像相同。
事务支持
transaction是针对一个或多个数据库中数据的数据库操作的基本单元。 事务中所有 SQL 语句的影响可以全部提交给数据库,也可以全部回滚。
默认情况下,MySQL 在主动提交模式下运行。 在这种模式下,对表的所有更改将立即生效。 为了防止这种情况,我们必须关闭主动提交模式。 禁用主动提交后,对事务感知表的更改不会立即永世更改。 要存储更改,我们必须调用COMMIT语句或ROLLBACK还原它们。 Ruby MySQL 为这些 SQL 语句commit和rollback提供了便捷的方法。
MySQL 数据库具有不同类型的存储引擎。 最常见的是 MyISAM 和 InnoDB 引擎。 在数据安全性和数据库速率之间须要权衡。 MyISAM 表的处置惩罚速率更快,并且不支持事务。 commit和rollback方法未实现。 他们什么都不做。 另一方面,InnoDB 表可以更安全地防止数据丢失。 他们支持事务。 它们处置惩罚较慢。
- mysql> SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES
- -> where TABLE_SCHEMA = 'mydb' AND TABLE_NAME='Writers';
- +------------+--------+
- | TABLE_NAME | ENGINE |
- +------------+--------+
- | Writers | InnoDB |
- +------------+--------+
- 1 row in set (0.00 sec)
复制代码 Writers表的引擎是 InnoDB,它支持事务。
- #!/usr/bin/rubyrequire 'mysql'
- begin con = Mysql.new 'localhost', 'user12', '34klq*'
- , 'mydb' con.autocommit false
- pst = con.prepare "UPDATE Writers SET Name = ? WHERE Id = ?" pst.execute "Leo Tolstoy", "1" pst.execute "Boris Pasternak", "2" pst.execute "Leonid Leonov" con.commitrescue Mysql::Error => e
- puts e
- con.rollback
- ensure pst.close if pst
- con.close if conend
复制代码 在此脚本中,我们尝试更新三行。
主动提交模式被禁用。
- pst = con.prepare "UPDATE Writers SET Name = ? WHERE Id = ?"
- pst.execute "Leo Tolstoy", "1"
- pst.execute "Boris Pasternak", "2"
- pst.execute "Leonid Leonov"
复制代码 我们执行三个UPDATE语句。 最后一个不正确。 第二个参数丢失。
如果一切正常,则更改将提交到表中。
- rescue Mysql::Error => e
- puts e
- con.rollback
复制代码 如果发生错误,则会回滚更改。
- $ ./update.rbexecute: param_count(2) != number of argument(1)mysql> SELECT * FROM Writers;
- +----+-------------------+
- | Id | Name |
- +----+-------------------+
- | 1 | Jack London |
- | 2 | Honore de Balzac |
- | 3 | Lion Feuchtwanger |
- | 4 | Emile Zola |
- | 5 | Truman Capote |
- | 6 | Stefan Zweig |
- +----+-------------------+
- 6 rows in set (0.00 sec)
复制代码 运行脚本会出现错误。 但是,该事务已回滚,并且前两行未更改。
Tweet
这是 MySQL Ruby 教程。 您可能也对 PostgreSQL Ruby 教程, SQLite Ruby 教程或 MongoDB Ruby 教程感爱好。
MySQL C# 教程
原文: http://zetcode.com/db/mysqlcsharptutorial/
关于本教程
这是 MySQL 数据库的 C# 教程。 它涵盖了利用 C# 进行 MySQL 编程的底子。 在本教程中,我们利用 Connector/Net 驱动步伐。 该驱动步伐基于 ADO.NET 规范。 这些示例是在 Ubuntu Linux 上创建和测试的。 在 ZetCode 上有一个类似的 MySQL Visual Basic 教程。
如果您须要重新学习 C# 语言的知识,请在 ZetCode 上找到完整的 C# 教程。
关于 MySQL 数据库
MySQL 是领先的开源数据库管理系统。 它是一个多用户,多线程的数据库管理系统。 MySQL 在网络上特别流行。 它是由 Linux,Apache,MySQL 和 PHP 组成的非常流行的 LAMP 平台的一部分。 目前,MySQL 由 Oracle 拥有。 MySQL 数据库在最重要的 OS 平台上可用。 它可以在 BSD Unix,Linux,Windows 或 Mac OS 上运行。 维基百科和 YouTube 利用 MySQL。 这些站点每天管理数百万个查询。 MySQL 有两个版本:MySQL 服务器系统和 MySQL 嵌入式系统。
开始之前
在 Linux 上,我们须要安装几个包来执行本教程中的示例:libmysql6.1-cil,mysql-server和mysql-client。 我们还须要从 Mono 项目(从包或从源代码)安装 C# 编译器。
libmysql6.1-cil是 CLI 的 MySQL 数据库连接器。 它用 C# 编写,并且可用于所有 CLI 语言:C# ,Visual Basic,Boo 等。
- $ ls /usr/lib/cli/MySql.Data-6.1/MySql.Data.dll
- /usr/lib/cli/MySql.Data-6.1/MySql.Data.dll
复制代码 从技能角度来看,我们须要一个 DLL。 在 Ubuntu Linux 上,它位于上述路径下。 我们须要知道 DLL 库的路径。 汇编我们的例子。
如果您尚未安装 MySQL,则必须安装它。
- $ sudo apt-get install mysql-server
复制代码 此下令将安装 MySQL 服务器和其他各种包。 在安装包时,提示我们输入 MySQL 根帐户的密码。 要从源代码安装 MySQL,请检察 MySQL 安装页面。
- $ service mysql status
- mysql start/running, process 1238
复制代码 我们检查 MySQL 服务器是否正在运行。 如果没有,我们须要启动服务器。
- $ sudo -b /usr/local/mysql/bin/mysqld_safe
复制代码 上面的下令利用 MySQL 服务器启动脚本启动 MySQL 服务器。 我们启动 MySQL 服务器的方式可能有所不同。 这取决于我们是否从源代码或包安装了 MySQL,也取决于 Linux 发行版。 有关更多信息,请查阅 MySQL 的第一步或您的 Linux 发行版信息。
接下来,我们将创建一个新的数据库用户和一个新的数据库。 我们利用mysql客户端。
- $ mysql -u root -p
- Enter password:
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 30
- Server version: 5.0.67-0ubuntu6 (Ubuntu)
- Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
- mysql> SHOW DATABASES;
- +--------------------+
- | Database |
- +--------------------+
- | information_schema |
- | mysql |
- +--------------------+
- 2 rows in set (0.00 sec)
复制代码 我们利用 mysql 监督器客户端应用连接到服务器。 我们利用根帐户连接到数据库。 我们用SHOW DATABASES语句显示所有可用的数据库。
- mysql> CREATE DATABASE mydb;
- Query OK, 1 row affected (0.02 sec)
复制代码 我们创建一个新的mydb数据库。 在整个教程中,我们将利用此数据库。
- mysql> CREATE USER user12@localhost IDENTIFIED BY '34klq*';
- Query OK, 0 rows affected (0.00 sec)
- mysql> USE mydb;
- Database changed
- mysql> GRANT ALL ON mydb.* to user12@localhost;
- Query OK, 0 rows affected (0.00 sec)
- mysql> quit;
- Bye
复制代码 我们创建一个新的数据库用户。 我们授予该用户mydb数据库所有表的所有特权。
界说
ADO.NET 是 .NET 框架的重要组成部分。 该规范同一了对关系数据库,XML 文件和其他应用数据的访问。MySQL Connector/Net 是 MySQL 数据库 ADO.NET 规范的实现。 它是用 C# 语言编写的驱动步伐,可用于所有.NET 语言。
Connection,Command,DataReader,DataSet和DataProvider是 .NET 数据供应器模型的焦点元素。 Connection创建到特定数据源的连接。 Command对象针对数据源执行一条 SQL 语句。 DataReader从数据源读取数据流。 DataSet对象用于脱机处置惩罚大量数据。 它是一种断开连接的数据表示情势,可以保存来自各种不同来源的数据。 DataReader和DataSet都用于处置惩罚数据。 它们在不同的情况下利用。 如果只须要读取查询结果,则DataReader是更好的选择。 如果须要更广泛的数据处置惩罚,或者要将 Winforms 控件绑定到数据库表,则首选DataSet。
MySQL 版本
如果以下步伐运行正常,则我们已安装一切正常。 我们检查 MySQL 服务器的版本。
- using System;
- using MySql.Data.MySqlClient;
- public class Example
- {
- static void Main()
- {
- string cs = @"server=localhost;userid=user12;
- password=34klq*;database=mydb";
- MySqlConnection conn = null;
- try
- {
- conn = new MySqlConnection(cs);
- conn.Open();
- Console.WriteLine("MySQL version : {0}", conn.ServerVersion);
- } catch (MySqlException ex)
- {
- Console.WriteLine("Error: {0}", ex.ToString());
- } finally
- {
- if (conn != null)
- {
- conn.Close();
- }
- }
- }
- }
复制代码 我们连接到数据库并获取有关 MySQL 服务器的一些信息。
- using MySql.Data.MySqlClient;
复制代码 我们导入 MySQL 数据供应器的元素。
- string cs = @"server=localhost;userid=user12;
- password=34klq*;database=mydb";
复制代码 这是连接字符串。 数据提供者利用它来建立与数据库的连接。 我们指定主机名,用户名,密码和数据库名。
- conn = new MySqlConnection(cs);
复制代码 创建一个MySQLConnection对象。 该对象用于打开与数据库的连接。
这行打开数据库连接。
- Console.WriteLine("MySQL version : {0}", conn.ServerVersion);
复制代码 在这里,我们利用连接对象的ServerVersion属性打印 MySQL 的版本。
- } catch (MySqlException ex)
- {
- Console.WriteLine("Error: {0}", ex.ToString());
复制代码 如果发生非常,我们将错误消息打印到控制台。
- } finally
- {
- if (conn != null)
- {
- conn.Close();
- }
- }
复制代码 在最后一步,我们关闭连接对象。
- $ dmcs -r:/usr/lib/cli/MySql.Data-6.1/MySql.Data.dll version.cs
复制代码 我们汇编示例。 提供了 MySQL 连接器 DLL 的路径。
- $ ./version.exe
- MySQL version : 5.5.9
复制代码 这是我系统上步伐的输出。
接下来是一个更复杂的步伐。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- string stm = "SELECT VERSION()";
- MySqlCommand cmd = new MySqlCommand(stm, conn);
- string version = Convert.ToString(cmd.ExecuteScalar());
- Console.WriteLine("MySQL version : {0}", version); } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}
复制代码 我们检查 MySQL 数据库的版本。 这次利用 SQL 查询。
- string stm = "SELECT VERSION()";
复制代码 这是 SQL SELECT语句。 它返回数据库的版本。 VERSION()是内置的 MySQL 函数。
- MySqlCommand cmd = new MySqlCommand(stm, conn);
复制代码 MySqlCommand是一个对象,用于在数据库上执行查询。 参数是 SQL 语句和连接对象。
- string version = Convert.ToString(cmd.ExecuteScalar());
复制代码 有些查询仅返回标量值。 在我们的例子中,我们须要一个简朴的字符串来指定数据库的版本。 在这种情况下利用ExecuteScalar()。 我们避免了利用更复杂的对象的开销。
- $ ./version2.exe
- MySQL version : 5.5.9
复制代码 结果与前面的示例相同。
创建和填充表
接下来,我们将创建数据库表并用数据填充它们。 这些表将在本教程中利用。
- DROP TABLE IF EXISTS Books, Authors;
- CREATE TABLE IF NOT EXISTS Authors(Id INT PRIMARY KEY AUTO_INCREMENT,
- Name VARCHAR(25)) ENGINE=INNODB;
- INSERT INTO Authors(Id, Name) VALUES(1, 'Jack London');
- INSERT INTO Authors(Id, Name) VALUES(2, 'Honore de Balzac');
- INSERT INTO Authors(Id, Name) VALUES(3, 'Lion Feuchtwanger');
- INSERT INTO Authors(Id, Name) VALUES(4, 'Emile Zola');
- INSERT INTO Authors(Id, Name) VALUES(5, 'Truman Capote');
- CREATE TABLE IF NOT EXISTS Books(Id INT PRIMARY KEY AUTO_INCREMENT,
- AuthorId INT, Title VARCHAR(100),
- FOREIGN KEY(AuthorId) REFERENCES Authors(Id) ON DELETE CASCADE)
- ENGINE=INNODB;
- INSERT INTO Books(Id, AuthorId, Title) VALUES(1, 1, 'Call of the Wild');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(2, 1, 'Martin Eden');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(3, 2, 'Old Goriot');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(4, 2, 'Cousin Bette');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(5, 3, 'Jew Suess');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(6, 4, 'Nana');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(7, 4, 'The Belly of Paris');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(8, 5, 'In Cold blood');
- INSERT INTO Books(Id, AuthorId, Title) VALUES(9, 5, 'Breakfast at Tiffany');
复制代码 我们有一个books.sql文件。 它创建两个数据库表:Authors和Books。 这些表是 InnoDB 类型的。 InnoDB 数据库支持外键束缚和事务。 我们将外键束缚放在Books表的AuthorId列上。 我们用初始数据填充表。
- mysql> source books.sql
- Query OK, 0 rows affected (0.07 sec)
- Query OK, 0 rows affected (0.12 sec)
- Query OK, 1 row affected (0.04 sec)
- ...
复制代码 我们利用source下令执行books.sql脚本。
准备语句
现在,我们将以准备语句来关注自己。 在编写准备语句时,我们利用占位符,而不是直接将值写入语句中。 预准备的语句可进步安全性和性能。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; cmd.CommandText = "INSERT INTO Authors(Name) VALUES(@Name)"; cmd.Prepare(); cmd.Parameters.AddWithValue("@Name", "Trygve Gulbranssen");
- cmd.ExecuteNonQuery();
- } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}
复制代码 我们将新作者添加到Authors表中。 我们利用参数化下令。
- cmd.CommandText = "INSERT INTO Authors(Name) VALUES(@Name)";
- cmd.Prepare();
复制代码 在这里,我们创建一个准备语句。 在编写准备语句时,我们利用占位符,而不是直接将值写入语句中。 准备语句更快,并且可以防止 SQL 注入攻击。 @Name是一个占位符,稍后将填充。
- cmd.Parameters.AddWithValue("@Name", "Trygve Gulbranssen");
复制代码 值绑定到占位符。
执行准备语句。 当我们不希望返回任何数据时,我们利用MySQLCommand对象的ExecuteNonQuery()方法。 这是当我们创建数据库或执行INSERT,UPDATE和DELETE语句时。
- $ ./prepared.exe
- mysql> SELECT * FROM Authors;
- +----+--------------------+
- | Id | Name |
- +----+--------------------+
- | 1 | Jack London |
- | 2 | Honore de Balzac |
- | 3 | Lion Feuchtwanger |
- | 4 | Emile Zola |
- | 5 | Truman Capote |
- | 6 | Trygve Gulbranssen |
- +----+--------------------+
- 6 rows in set (0.00 sec)
复制代码 我们在表中插入了一位新作者。
利用MySqlDataReader检索数据
MySqlDataReader是用于从数据库检索数据的对象。 它提供对查询结果的快速,仅转发和只读访问。 这是从表中检索数据的最有效方法。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; MySqlDataReader rdr = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- string stm = "SELECT * FROM Authors";
- MySqlCommand cmd = new MySqlCommand(stm, conn);
- rdr = cmd.ExecuteReader(); while (rdr.Read()) { Console.WriteLine(rdr.GetInt32(0) + ": " + rdr.GetString(1)); } } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (rdr != null) { rdr.Close(); } if (conn != null) { conn.Close(); } } }}
复制代码 我们从Authors表中获取所有作者并将其打印到控制台。
- reader = cmd.ExecuteReader();
复制代码 要创建MySQLDataReader,我们必须调用MySqlCommand对象的ExecuteReader()方法。
- while (reader.Read())
- {
- Console.WriteLine(reader.GetInt32(0) + ": "
- + reader.GetString(1));
- }
复制代码 Read()方法将数据读取器移至下一条记录。 如果有更多行,则返回true;否则,返回true。 否则为假。 我们可以利用数组索引符号来检索值,或者利用特定的方法来访问其本机数据类型中的列值。 后者服从更高。
- if (rdr != null)
- {
- rdr.Close();
- }
复制代码 阅读完毕后,请务必调用阅读器的Close()方法。
- $ ./retrieve.exe
- 1: Jack London
- 2: Honore de Balzac
- 3: Lion Feuchtwanger
- 4: Emile Zola
- 5: Truman Capote
- 6: Trygve Gulbranssen
复制代码 这是示例的输出。
列标题
接下来,我们将展示如何利用数据库表中的数据打印列标题。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; MySqlDataReader rdr = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- string stm = @"SELECT Name, Title From Authors, Books WHERE Authors.Id=Books.AuthorId"; MySqlCommand cmd = new MySqlCommand(stm, conn);
- rdr = cmd.ExecuteReader(); Console.WriteLine("{0} {1}", rdr.GetName(0), rdr.GetName(1).PadLeft(18)); while (rdr.Read()) { Console.WriteLine(rdr.GetString(0).PadRight(18) + rdr.GetString(1)); } } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (rdr != null) { rdr.Close(); } if (conn != null) { conn.Close(); } } }}
复制代码 在此步伐中,我们从Authors表中选择作者,并从Books表中选择他们的书。
- string stm = @"SELECT Name, Title From Authors,
- Books WHERE Authors.Id=Books.AuthorId";
复制代码 这是将作者与他们的书接洽在一起的 SQL 语句。
- reader = cmd.ExecuteReader();
复制代码 我们创建一个MySqlDataReader对象。
- Console.WriteLine("{0} {1}", reader.GetName(0),
- reader.GetName(1).PadLeft(18));
复制代码 我们利用阅读器的GetName()方法得到列的名称。 PadLeft()方法返回指定长度的新字符串,其中当前字符串的开头用空格填充。 我们利用此方法正确对齐字符串。
- while (reader.Read())
- {
- Console.WriteLine(reader.GetString(0).PadRight(18) +
- reader.GetString(1));
- }
复制代码 我们将 SQL 语句返回的数据打印到终端。
- $ ./headers.exe
- Name Title
- Jack London Call of the Wild
- Jack London Martin Eden
- Honore de Balzac Old Goriot
- Honore de Balzac Cousin Bette
- Lion Feuchtwanger Jew Suess
- Emile Zola Nana
- Emile Zola The Belly of Paris
- Truman Capote In Cold blood
- Truman Capote Breakfast at Tiffany
复制代码 该步伐的输出。
数据集& MySqlDataAdapter
DataSet是数据库表中数据的副本以及数据之间的关系。 它在内存中创建,并在须要对数据进行大量处置惩罚或将数据表绑定到 Winforms 控件时利用。 处置惩罚完成后,更改将被写入数据源。 MySqlDataAdapter是数据集和数据源之间的中介。 它填充DataSet并解析数据源的更新。
- using System;using System.Data;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- string stm = "SELECT * FROM Authors";
- MySqlDataAdapter da = new MySqlDataAdapter(stm, conn);
- DataSet ds = new DataSet(); da.Fill(ds, "Authors"); DataTable dt = ds.Tables["Authors"];
- dt.WriteXml("authors.xml");
- foreach (DataRow row in dt.Rows) { foreach (DataColumn col in dt.Columns) { Console.WriteLine(row[col]); } Console.WriteLine("".PadLeft(20, '=')); } } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}
复制代码 我们从Authors表中打印作者。 我们还将它们保存在 XML 文件中。 这次,我们利用MySqlDataAdapter和DataSet对象。
- MySqlDataAdapter da = new MySqlDataAdapter(stm, conn);
复制代码 创建一个MySqlDataAdapter对象。 它以 SQL 语句和连接为参数。
- DataSet ds = new DataSet();
- da.Fill(ds, "Authors");
复制代码 我们创建并填充DataSet。
- DataTable dt = ds.Tables["Authors"];
复制代码 我们得到名为Authors的表。 我们只给了DataSet一个表,但是它可以包罗多个表。
- dt.WriteXml("authors.xml");
复制代码 我们将数据写入 XML 文件。
- foreach (DataRow row in dt.Rows)
- {
- foreach (DataColumn col in dt.Columns)
- {
- Console.WriteLine(row[col]);
- }
- Console.WriteLine("".PadLeft(20, '='));
- }
复制代码 我们向终端显示Authors表的内容。 为了遍历数据,我们利用了DataTable对象的行和列。
在下一个示例中,我们将表绑定到 Winforms DataGrid控件。
- using System;using System.Windows.Forms;
- using System.Drawing;
- using System.Data;using MySql.Data.MySqlClient;
- class MForm : Form{ private DataGrid dg = null; private MySqlConnection conn = null; private MySqlDataAdapter da = null; private DataSet ds = null; public MForm() { this.Text = "DataGrid"; this.Size = new Size(350, 300); this.InitUI(); this.InitData(); this.CenterToScreen(); } void InitUI() { dg = new DataGrid();
- dg.CaptionBackColor = System.Drawing.Color.White; dg.CaptionForeColor = System.Drawing.Color.Black; dg.CaptionText = "Authors"; dg.Location = new Point(8, 0); dg.Size = new Size(350, 300); dg.TabIndex = 0; dg.Parent = this; } void InitData() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; string stm = "SELECT * FROM Authors";
- try { conn = new MySqlConnection(cs);
- conn.Open();
- ds = new DataSet(); da = new MySqlDataAdapter(stm, conn); da.Fill(ds, "Authors"); dg.DataSource = ds.Tables["Authors"];
- } catch (MySqlException ex) { Console.WriteLine("Error: " + ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}class MApplication { public static void Main() { Application.Run(new MForm()); }}
复制代码 在此示例中,我们将Authors表绑定到 Winforms DataGrid控件。
- using System.Windows.Forms;
- using System.Drawing;
复制代码 这两个名称空间用于 GUI。
- this.InitUI();
- this.InitData();
复制代码 在InitUI()方法内部,我们构建了用户界面。 在InitData()方法中,我们连接到数据库,将数据检索到DataSet中并将其绑定到DataGrid控件。
DataGrid控件已创建。
- string stm = "SELECT * FROM Authors";
复制代码 我们将在DataGrid控件中显示Authors表中的数据。
- dg.DataSource = ds.Tables["Authors"];
复制代码 我们将DataGrid控件的DataSource属性绑定到所选表。
- $ dmcs -r:/usr/lib/cli/MySql.Data-6.1/MySql.Data.dll -r:System.Windows.Forms.dll
- -r:System.Drawing.dll -r:System.Data.dll dataadapter2.cs
复制代码 要编译该示例,我们必须包括其他 DLL:用于 MySQL 连接器,Winforms,Drawing和Data的 DLL。
图:DataGrid
事务支持
事务是针对一个或多个数据库中数据的数据库操作的基本单元。 事务中所有 SQL 语句的影响可以全部提交给数据库,也可以全部回滚。
MySQL 数据库具有不同类型的存储引擎。 最常见的是 MyISAM 和 InnoDB 引擎。 在数据安全性和数据库速率之间须要权衡。 MyISAM 表的处置惩罚速率更快,并且不支持事务。 另一方面,InnoDB 表可以更安全地防止数据丢失。 他们支持事务。 它们处置惩罚较慢。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; MySqlTransaction tr = null;
- try { conn = new MySqlConnection(cs);
- conn.Open();
- tr = conn.BeginTransaction();
- MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; cmd.Transaction = tr; cmd.CommandText = "UPDATE Authors SET Name='Leo Tolstoy' WHERE Id=1"; cmd.ExecuteNonQuery();
- cmd.CommandText = "UPDATE Books SET Title='War and Peace' WHERE Id=1"; cmd.ExecuteNonQuery();
- cmd.CommandText = "UPDATE Books SET Titl='Anna Karenina' WHERE Id=2"; cmd.ExecuteNonQuery();
- tr.Commit();
- } catch (MySqlException ex) { try { tr.Rollback(); } catch (MySqlException ex1) { Console.WriteLine("Error: {0}", ex1.ToString()); } Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}
复制代码 在此步伐中,我们想在Authors表的第一行上更改作者的姓名。 我们还必须更改与该作者相干的册本。 一个须要进行事务的很好的例子。 如果我们更改作者但不更改作者的书,则数据已粉碎。
- MySqlTransaction tr = null;
复制代码 MySqlTransaction是用于处置惩罚事务的对象。
- tr = conn.BeginTransaction();
复制代码 我们开始事务。
- cmd.CommandText = "UPDATE Books SET Titl='Anna Karenina' WHERE Id=2";
- cmd.ExecuteNonQuery();
复制代码 第三个 SQL 语句有一个错误。 表中没有"Titl"列。
如果没有非常,则提交事务。
- try
- {
- tr.Rollback();
- } catch (MySqlException ex1)
- {
- Console.WriteLine("Error: {0}", ex1.ToString());
- }
复制代码 发生非常时,事务将回滚。 没有更改提交到数据库。 在回滚期间,可能会出现Exception。 我们在单独的try/catch语句中对此进行处置惩罚。
- $ ./transaction.exe
- Error: MySql.Data.MySqlClient.MySqlException: Unknown column 'Titl' in 'field list'
- at MySql.Data.MySqlClient.MySqlStream.ReadPacket () [0x00000]
- at MySql.Data.MySqlClient.NativeDriver.ReadResult () [0x00000]
- mysql> SELECT Name, Title From Authors, Books WHERE Authors.Id=Books.AuthorId;
- +-------------------+----------------------+
- | Name | Title |
- +-------------------+----------------------+
- | Jack London | Call of the Wild |
- | Jack London | Martin Eden |
- | Honore de Balzac | Old Goriot |
- | Honore de Balzac | Cousin Bette |
- | Lion Feuchtwanger | Jew Suess |
- | Emile Zola | Nana |
- | Emile Zola | The Belly of Paris |
- | Truman Capote | In Cold blood |
- | Truman Capote | Breakfast at Tiffany |
- +-------------------+----------------------+
- 9 rows in set (0.00 sec)
复制代码 引发非常。 事务已回滚,并且未进行任何更改。
但是,如果没有事务,数据是不安全的。
- using System;using MySql.Data.MySqlClient;
- public class Example{ static void Main() { string cs = @"server=localhost;userid=user12; password=34klq*;database=mydb"; MySqlConnection conn = null; try { conn = new MySqlConnection(cs);
- conn.Open();
- MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; cmd.CommandText = "UPDATE Authors SET Name='Leo Tolstoy' WHERE Id=1"; cmd.ExecuteNonQuery();
- cmd.CommandText = "UPDATE Books SET Title='War and Peace' WHERE Id=1"; cmd.ExecuteNonQuery();
- cmd.CommandText = "UPDATE Books SET Titl='Anna Karenina' WHERE Id=2"; cmd.ExecuteNonQuery();
- } catch (MySqlException ex) { Console.WriteLine("Error: {0}", ex.ToString()); } finally { if (conn != null) { conn.Close(); } } }}
复制代码 我们有同样的例子。 这次,没有事务支持。
- $ ./notransaction.exe
- Error: MySql.Data.MySqlClient.MySqlException: Unknown column 'Titl' in 'field list'
- at MySql.Data.MySqlClient.MySqlStream.ReadPacket () [0x00000]
- at MySql.Data.MySqlClient.NativeDriver.ReadResult () [0x00000]
- mysql> SELECT Name, Title From Authors, Books WHERE Authors.Id=Books.AuthorId;
- +-------------------+----------------------+
- | Name | Title |
- +-------------------+----------------------+
- | Leo Tolstoy | War and Peace |
- | Leo Tolstoy | Martin Eden |
- | Honore de Balzac | Old Goriot |
- | Honore de Balzac | Cousin Bette |
- | Lion Feuchtwanger | Jew Suess |
- | Emile Zola | Nana |
- | Emile Zola | The Belly of Paris |
- | Truman Capote | In Cold blood |
- | Truman Capote | Breakfast at Tiffany |
- +-------------------+----------------------+
- 9 rows in set (0.00 sec)
复制代码 再次引发非常。 列夫·托尔斯泰没有写马丁·伊甸园。 数据已粉碎。
Tweet
这是带有 MySQL 连接器的 MySQL C# 教程。 您可能也对 MySQL C API 教程, MySQL Python 教程或 MySQL PHP 教程感爱好。
SQLite 教程
原文: http://zetcode.com/db/sqlite/
这是 SQLite 教程。 它涵盖了 SQLite 数据库引擎,sqlite3 下令行工具以及数据库引擎涵盖的 SQL 语言。
目录
- 简介
- sqlite3 下令行工具
- 创建,更改和删除表
- SQLite 表达式
- 插入,更新和删除数据
- SELECT语句
- 束缚
- 连接表
- SQLite 函数
- 检察,触发,事务
SQLite
SQLite 是嵌入式关系数据库引擎。 它的开发者称其为自包罗,无服务器,零设置和事务型 SQL 数据库引擎。
Tweet
相干教程和电子书
SQLite Python 电子书是利用 Python 语言进行 SQLite 编程的深入质料。 MySQL 教程涵盖了 MySQL 数据库系统。 SQLAlchemy 教程涵盖了 SQLAlchemy SQL 工具包和对象关系映射器。 以下教程展示了如何从各种编程语言连接到 SQLite: SQLite C 教程, SQLite Python 教程, PHP SQLite3 教程, SQLite Perl 教程 , SQLite Ruby 教程, SQLite C# 教程和 SQLite Visual Basic 教程。
SQLite 简介
原文: http://zetcode.com/db/sqlite/introduction/
这是 SQLite 教程。 它涵盖了 SQLite 数据库引擎,sqlite3下令行工具和数据库引擎涵盖的 SQL 语言。 它是初学者的入门教程。 它涵盖了 SQLite 3.16.2 版本。
SQLite 数据库
SQLite 是嵌入式关系数据库引擎。 它的开发者称其为自包罗,无服务器,零设置和事务型 SQL 数据库引擎。 它非常受欢迎,当今全球有数亿本利用。 SQLite 用于 Solaris 10 和 Mac OS 操作系统以及 iPhone 和 Skype。 Qt4 库具有对 SQLite 以及 Python 和 PHP 语言的内置支持。 许多流行的应用内部都利用 SQLite,例如 Firefox,Google Chrome 或 Amarok。
SQLite 实现了 SQL 的大多数 SQL-92 尺度。 SQLite 引擎不是独立的进程。 而是将其静态或动态链接到应用。 SQLite 库很小。 它可能须要少于 300 KiB。 SQLite 数据库是单个平凡磁盘文件,可以位于目录层次布局中的任何位置。 这是一个跨平台文件。 它可以在 32 位和 64 位架构的各种操作系统上利用。 SQLite 是用 C 编程语言编写的。 它具有许多语言的绑定,包括 C++ ,Java,C# ,Python,Perl,Ruby,Visual Basic 和 Tcl。 SQLite 的源代码在公共范畴。
界说
关系数据库是表中构造的数据的集合。 表之间存在关系。 这些表是正式描述的。 它们由行和列组成。 _SQL(布局化查询语言)是一种数据库计算机语言,旨在管理关系数据库管理系统中的数据。 表是利用垂直列和水平行的模型构造的一组值。 列由其名称标识。 数据库系统的模式是用正式语言描述的布局。 它界说了表,字段,关系,视图,索引,过程,函数,队列,触发器和其他元素。 数据库行代表表中的单个隐式布局化数据项。 它也称为元组或记录。
列是一组特定简朴类型的数据值,该数据值对应于表的每一行。 列提供了构成行所依据的布局。 字段是单个项目,存在于一行和一列之间的交点处。 主键唯一标识表中的每个记录。 外键是两个表之间的引用束缚。 外键标识一个(引用)表中的一列或一组列,该列或表引用另一(引用)表中的一列或一组列。 触发器是响应于数据库中特定表上的某些变乱而主动执行的过程代码。 视图是对来自一个或多个表的数据的特定外观。 它可以按特定顺序分列数据,突出显示或隐藏某些数据。 视图由存储的查询组成,该查询可作为由查询结果集组成的虚拟表访问。 与平凡表不同,视图不构成物理模式的一部分。 它是根据数据库中的数据计算或整理的动态虚拟表。
事务是针对一个或多个数据库中数据的数据库操作的基本单元。 事务中所有 SQL 语句的影响可以全部提交给数据库,也可以全部回滚。 SQL 结果集是SELECT语句返回的数据库中的一组行。 它还包罗有关查询的元信息,例如列名以及每列的类型和大小。 索引是一种数据布局,可进步对数据库表的数据检索操作的速率。
从源代码安装 SQLite
为了得到最新版本的 SQLite,我们可以从源代码安装 SQLite。 安装很轻易,并且只须要一段时间。 以下说明在 Linux 上构建和安装 SQLite。
- $ sudo apt-get install libreadline-dev
复制代码 要在 sqlite 下令行工具中启用下令历史记录,我们须要安装readline开发库。
- $ wget https://www.sqlite.org/2017/sqlite-autoconf-3160200.tar.gz
复制代码 从 SQLite 下载页面,我们可以得到最新资源。 这些是 SQLite 版本 3.16.2 的来源。
- $ tar -xzvf sqlite-autoconf-3160200.tar.gz
复制代码 我们解压缩压缩文件。
- $ cd sqlite-autoconf-3160200/
复制代码 我们转到sqlite-autoconf-3160200目录。
我们运行configure脚本。 它告诉我们是否已经准备好构建 SQLite 的所有内容。
利用make,我们构建 SQLite。
利用sudo make install,我们在系统上安装了 SQLite。
- $ which sqlite3
- /usr/local/bin/sqlite3
复制代码 默认情况下,SQLite 下令行工具安装在/usr/local/bin目录中。
- $ sqlite3
- SQLite version 3.16.2 2017-01-06 16:32:41
- Enter ".help" for usage hints.
- Connected to a transient in-memory database.
- Use ".open FILENAME" to reopen on a persistent database.
- sqlite>
复制代码 /usr/local/bin目录位于PATH变量中,因此我们可以在没有完整路径的情况下运行sqlite3。
利用的表
在这里,我们将列出整个教程中利用的最重要的表。 sqlite3工具的.read下令用于从文件执行 SQL 语句。
在这里,我们执行cars.sql文件中的 SQL 语句。
cars.sql
- -- SQL for the Cars table
- BEGIN TRANSACTION;
- DROP TABLE IF EXISTS Cars;
- CREATE TABLE Cars(Id INTEGER PRIMARY KEY, Name TEXT, Price INTEGER);
- INSERT INTO Cars VALUES(1, 'Audi', 52642);
- INSERT INTO Cars VALUES(2, 'Mercedes', 57127);
- INSERT INTO Cars VALUES(3, 'Skoda', 9000);
- INSERT INTO Cars VALUES(4, 'Volvo', 29000);
- INSERT INTO Cars VALUES(5, 'Bentley', 350000);
- INSERT INTO Cars VALUES(6, 'Citroen', 21000);
- INSERT INTO Cars VALUES(7, 'Hummer', 41400);
- INSERT INTO Cars VALUES(8, 'Volkswagen', 21600);
- COMMIT;
复制代码 这是Cars表。
orders.sql
- -- SQL for the Orders table
- BEGIN TRANSACTION;
- DROP TABLE IF EXISTS Orders;
- CREATE TABLE Orders(Id INTEGER PRIMARY KEY,
- OrderPrice INTEGER CHECK(OrderPrice>0), Customer TEXT);
- INSERT INTO Orders(OrderPrice, Customer) VALUES(1200, "Williamson");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(200, "Robertson");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(40, "Robertson");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(1640, "Smith");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(100, "Robertson");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(50, "Williamson");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(150, "Smith");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(250, "Smith");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(840, "Brown");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(440, "Black");
- INSERT INTO Orders(OrderPrice, Customer) VALUES(20, "Brown");
- COMMIT;
复制代码 这是Orders表。
friends.sql
- -- SQL for the Friends table
- BEGIN TRANSACTION;
- DROP TABLE IF EXISTS Friends;
- CREATE TABLE Friends(Id INTEGER PRIMARY KEY, Name TEXT UNIQUE NOT NULL,
- Sex TEXT CHECK(Sex IN ('M', 'F')));
- INSERT INTO Friends VALUES(1, 'Jane', 'F');
- INSERT INTO Friends VALUES(2, 'Thomas', 'M');
- INSERT INTO Friends VALUES(3, 'Franklin', 'M');
- INSERT INTO Friends VALUES(4, 'Elisabeth', 'F');
- INSERT INTO Friends VALUES(5, 'Mary', 'F');
- INSERT INTO Friends VALUES(6, 'Lucy', 'F');
- INSERT INTO Friends VALUES(7, 'Jack', 'M');
- COMMIT;
复制代码 这是Friends表。
customers_reservations.sql
- BEGIN TRANSACTION;
- DROP TABLE IF EXISTS Reservations;
- DROP TABLE IF EXISTS Customers;
- CREATE TABLE IF NOT EXISTS Customers(CustomerId INTEGER PRIMARY KEY, Name TEXT);
- INSERT INTO Customers(Name) VALUES('Paul Novak');
- INSERT INTO Customers(Name) VALUES('Terry Neils');
- INSERT INTO Customers(Name) VALUES('Jack Fonda');
- INSERT INTO Customers(Name) VALUES('Tom Willis');
- CREATE TABLE IF NOT EXISTS Reservations(Id INTEGER PRIMARY KEY,
- CustomerId INTEGER, Day TEXT);
- INSERT INTO Reservations(CustomerId, Day) VALUES(1, '2009-22-11');
- INSERT INTO Reservations(CustomerId, Day) VALUES(2, '2009-28-11');
- INSERT INTO Reservations(CustomerId, Day) VALUES(2, '2009-29-11');
- INSERT INTO Reservations(CustomerId, Day) VALUES(1, '2009-29-11');
- INSERT INTO Reservations(CustomerId, Day) VALUES(3, '2009-02-12');
- COMMIT;
复制代码 这些是Customers和Reservations表。
authors_books.sql
- -- SQL for the Authors & Books tables
- BEGIN TRANSACTION;
- DROP TABLE IF EXISTS Books;
- DROP TABLE IF EXISTS Authors;
- CREATE TABLE Authors(AuthorId INTEGER PRIMARY KEY, Name TEXT);
- INSERT INTO Authors VALUES(1, 'Jane Austen');
- INSERT INTO Authors VALUES(2, 'Leo Tolstoy');
- INSERT INTO Authors VALUES(3, 'Joseph Heller');
- INSERT INTO Authors VALUES(4, 'Charles Dickens');
- CREATE TABLE Books(BookId INTEGER PRIMARY KEY, Title TEXT, AuthorId INTEGER,
- FOREIGN KEY(AuthorId) REFERENCES Authors(AuthorId));
- INSERT INTO Books VALUES(1,'Emma',1);
- INSERT INTO Books VALUES(2,'War and Peace',2);
- INSERT INTO Books VALUES(3,'Catch XII',3);
- INSERT INTO Books VALUES(4,'David Copperfield',4);
- INSERT INTO Books VALUES(5,'Good as Gold',3);
- INSERT INTO Books VALUES(6,'Anna Karenia',2);
- COMMIT;
复制代码 这些是Authors和Books表。
数据来源
SQLite 的文档用于创建本教程。
本章是对 SQLite 数据库的介绍。
sqlite3 下令行工具
原文: http://zetcode.com/db/sqlite/tool/
在 SQLite 教程的这一部分中,我们介绍了sqlite3下令行工具。
sqlite3 工具
sqlite3工具是 SQLite 库的基于终端的前端,可以交互地求值查询并以多种格式显示结果。 它也可以在脚本中利用。
在终端屏幕上,我们看到sqlite3工具的以下提示:
- $ sqlite3
- SQLite version 3.16.2 2017-01-06 16:32:41
- Enter ".help" for usage hints.
- Connected to a transient in-memory database.
- Use ".open FILENAME" to reopen on a persistent database.
复制代码 .help下令是sqlite3工具的元下令之一; 它列出了所有元下令。 .exit和.quit下令退出sqlite3会话。 我们还可以利用Ctrl + D组合键退出sqlite3。 .databases下令显示附加的数据库。 .tables下令列出了可用的表。
Ctrl + L扫除屏幕,Ctrl + U扫除当前行。 (利用readline库构建时。)
利用 sqlite3 创建数据库
完整的 SQLite 数据库存储在单个跨平台磁盘文件中。 我们利用sqlite3下令行工具创建一个新的数据库文件。
在这里,我们创建一个新的test.db数据库。 如果该文件存在,则将其打开。
基本的 sqlite3 元下令
接下来,我们描述sqlite3工具的一些元下令。
- sqlite> .tables
- Authors Cars Friends Reservations
- Books Customers Orders
复制代码 .tables下令显示可用表。
- sqlite> SELECT * FROM Friends;
- 1|Jane|F
- 2|Thomas|M
- 3|Franklin|M
- 4|Elisabeth|F
- 5|Mary|F
- 6|Lucy|F
- 7|Jack|M
复制代码 在这里,我们得到SELECT语句的输出。 默认情况下,输出模式为line,分隔符为|。
- sqlite> .separator :
- sqlite> SELECT * FROM Friends;
- 1:Jane:F
- 2:Thomas:M
- 3:Franklin:M
- 4:Elisabeth:F
- 5:Mary:F
- 6:Lucy:F
- 7:Jack:M
复制代码 在这里,我们利用了一个新的冒号分隔符。
还有其他几种输出模式可用。 以下示例显示column输出模式。
- sqlite> .mode column
- sqlite> .headers on
- sqlite> SELECT * FROM Friends;
- Id Name Sex
- ---------- ---------- ----------
- 1 Jane F
- 2 Thomas M
- 3 Franklin M
- 4 Elisabeth F
- 5 Mary F
- 6 Lucy F
- 7 Jack M
复制代码 本示例说明如何在 sqlite 的列模式下格式化数据。 .headers下令也已用于显示列标题。 默认情况下,标题是隐藏的。
.width下令调整列的大小。 (此元下令仅与列模式下的表有关。)
- sqlite> SELECT Name, Title FROM Authors NATURAL JOIN Books;
- Name Title
- ----------- ----------
- Jane Austen Emma
- Leo Tolstoy War and Pe
- Joseph Hell Catch XII
- Charles Dic David Copp
- Joseph Hell Good as Go
- Leo Tolstoy Anna Karen
复制代码 列宽不足以正确显示所有数据。
- sqlite> .width 15 18
- sqlite> SELECT Name, Title FROM Authors NATURAL JOIN Books;
- Name Title
- --------------- ------------------
- Jane Austen Emma
- Leo Tolstoy War and Peace
- Joseph Heller Catch XII
- Charles Dickens David Copperfield
- Joseph Heller Good as Gold
- Leo Tolstoy Anna Karenia
复制代码 在这里,我们更改列宽。 第一列为 15 个字符,第二列为 18 个字符。
.shell下令执行系统步伐。 在本例中,我们利用clear下令扫除屏幕。 (Windows 上的等效值为cls。)
- sqlite> .show
- echo: off
- eqp: off
- explain: auto
- headers: on
- mode: column
- nullvalue: ""
- output: stdout
- colseparator: "|"
- rowseparator: "\n"
- stats: off
- width: 15 18
- filename: testdb
复制代码 .show下令列出了各种设置。 其中包括输出模式,列表模式中利用的分隔符以及标题是否打开。
- sqlite> .schema Cars
- CREATE TABLE Cars(Id INTEGER PRIMARY KEY, Name TEXT, Price INTEGER);
复制代码 .schema下令显示表的布局。 它提供了 DDL SQL 来创建表。
可以利用.prompt下令更改sqlite3的提示。
- sqlite> .prompt "> " ". "
- > SELECT * FROM Cars
- . LIMIT 2;
- Id Name Price
- ---------- ---------- ----------
- 1 Audi 52642
- 2 Mercedes 57127
- >
复制代码 有两个提示。 一个是主提示,另一个是继续提示。 默认的主提示是sqlite>,默认的继续提示是...>。
从 Shell 执行 SQL
我们可以从 Shell 执行 SQL 下令。
- $ sqlite3 test.db
- "SELECT * FROM Cars;"1|Audi|526422|Mercedes|571273|Skoda|90004|Volvo|290005|Bentley|3500006|Citroen|210007|Hummer|414008|Volkswagen|21600
复制代码 在这里,我们非交互地执行了SELECT语句; 从Cars表中选择了所有汽车。
转储表
可以将 SQL 格式的表转储到磁盘上。 这样,我们可以轻松地保存数据库表的布局和数据。
我们有汽车表。
- sqlite> SELECT * FROM Cars;
- Id Name Price
- ---------- ---------- ----------
- 1 Audi 52642
- 2 Mercedes 57127
- 3 Skoda 9000
- 4 Volvo 29000
- 5 Bentley 350000
- 6 Citroen 21000
- 7 Hummer 41400
- 8 Volkswagen 21600
复制代码 我们将利用.dump下令转储该表。
- sqlite> .dump Cars
- PRAGMA foreign_keys=OFF;
- BEGIN TRANSACTION;
- CREATE TABLE Cars(Id INTEGER PRIMARY KEY, Name TEXT, Price INTEGER);
- INSERT INTO "Cars" VALUES(1,'Audi',52642);
- INSERT INTO "Cars" VALUES(2,'Mercedes',57127);
- INSERT INTO "Cars" VALUES(3,'Skoda',9000);
- INSERT INTO "Cars" VALUES(4,'Volvo',29000);
- INSERT INTO "Cars" VALUES(5,'Bentley',350000);
- INSERT INTO "Cars" VALUES(6,'Citroen',21000);
- INSERT INTO "Cars" VALUES(7,'Hummer',41400);
- INSERT INTO "Cars" VALUES(8,'Volkswagen',21600);
- COMMIT;
复制代码 .dump下令向我们显示了创建Cars表所需的 SQL。
- sqlite> .output cars2.sql
- sqlite> .dump Cars
复制代码 我们还可以将输出重定向到文件。 .output下令会将输出重定向到cars2.sql文件。
- $ cat cars2.sql
- PRAGMA foreign_keys=OFF;
- BEGIN TRANSACTION;
- CREATE TABLE Cars(Id INTEGER PRIMARY KEY, Name TEXT, Price INTEGER);
- INSERT INTO "Cars" VALUES(1,'Audi',52642);
- ...
复制代码 我们利用cat下令显示cars2.sql文件的内容。
读取 SQL
我们可以利用.read下令从文件名读取 SQL 语句。
- sqlite> .tables
- Authors Cars Friends Reservations
- Books Customers Orders
- sqlite> DROP TABLE Cars;sqlite> .tablesAuthors Customers Orders Books Friends Reservationssqlite> .read cars.sql
- sqlite> .tables
- Authors Cars Friends Reservations
- Books Customers Orders
- sqlite> SELECT * FROM Cars WHERE Id=1;Id Name Price ---------- ---------- ----------1 Audi 52642
复制代码 在这里,我们执行了一系列下令。 我们放下表并从cars.sql中读取它。
.sqlite_history文件
下令和语句存储在.sqlite_history文件中。 该文件位于主目录中。
- $ tail -5 ~/.sqlite_history
- .tables
- SELECT * FROM Cars;
- .mode column
- .headers on
- .show
复制代码 利用tail下令,显示最后五个条目。
资源文件
sqlite3工具具有一个名为.sqliterc的资源文件。 它位于主目录中。 如果没有这样的文件,我们可以简朴地创建它。 资源文件可以包罗元下令或通例 SQL 语句。 但是,我们应该避免在文件中利用 SQL。
- $ cat .sqliterc
- .mode column
- .headers on
- .nullvalue NULL
复制代码 这是资源文件的简朴示例。 它具有三个元下令。 利用资源文件,当我们启动sqlite3工具时,我们不必重新执行元下令。 它们将在工具启动时主动执行。
- $ sqlite3 test.db
- -- Loading resources from /home/janbodnar/.sqlitercSQLite version 3.16.2 2017-01-06 16:32:41Enter ".help" for usage hints.
复制代码 我们有一条消息说该工具从一开始就加载资源。
下令行选项
该工具有几个命令行选项。 他们大多复制元下令。 请留意,下令行选项将覆盖资源文件元下令。
- $ sqlite3 --help
- -- Loading resources from /home/janbodnar/.sqliterc
- Usage: sqlite3 [OPTIONS] FILENAME [SQL]
- FILENAME is the name of an SQLite database. A new database is created
- if the file does not previously exist.
- OPTIONS include:
- -ascii set output mode to 'ascii'
- -bail stop after hitting an error
- -batch force batch I/O
- -column set output mode to 'column'
- -cmd COMMAND run "COMMAND" before reading stdin
- -csv set output mode to 'csv'
- -echo print commands before execution
- -init FILENAME read/process named file
- -[no]header turn headers on or off
- -help show this message
- -html set output mode to HTML
- -interactive force interactive I/O
- -line set output mode to 'line'
- -list set output mode to 'list'
- -lookaside SIZE N use N entries of SZ bytes for lookaside memory
- -mmap N default mmap size set to N
- -newline SEP set output row separator. Default: '\n'
- -nullvalue TEXT set text string for NULL values. Default ''
- -pagecache SIZE N use N slots of SZ bytes each for page cache memory
- -scratch SIZE N use N slots of SZ bytes each for scratch memory
- -separator SEP set output column separator. Default: '|'
- -stats print memory stats before each finalize
- -version show SQLite version
- -vfs NAME use NAME as the default VFS
复制代码 --help选项为我们提供了所有可用选项的列表,并带有简要说明。
- $ sqlite3 -echo -line -noheader test.db
- -- Loading resources from /home/janbodnar/.sqliterc
- SQLite version 3.16.2 2017-01-06 16:32:41
- Enter ".help" for usage hints.
- sqlite> SELECT * FROM Cars LIMIT 2;
- SELECT * FROM Cars LIMIT 2;
- Id = 1
- Name = Audi
- Price = 52642
- Id = 2
- Name = Mercedes
- Price = 57127
复制代码 我们利用-echo,-line和-noheader选项启动sqlite3工具。 SELECT语句在启动后会重复/回显。 输出处于行模式,并且没有标题显示。
- $ sqlite3 -version
- -- Loading resources from /home/janbodnar/.sqliterc
- 3.16.2 2017-01-06 16:32:41 a65a62893ca8319e89e48b8a38cf8a59c69a8209
复制代码 利用-version选项,我们得到 sqlite3 的版本。
- $ sqlite3 -html test.db
- -- Loading resources from /home/janbodnar/.sqliterc
- SQLite version 3.16.2 2017-01-06 16:32:41
- Enter ".help" for usage hints.
- sqlite> SELECT * FROM Cars LIMIT 2;
- <TR><TH>Id</TH>
- <TH>Name</TH>
- <TH>Price</TH>
- </TR>
- <TR><TD>1</TD>
- <TD>Audi</TD>
- <TD>52642</TD>
- </TR>
- <TR><TD>2</TD>
- <TD>Mercedes</TD>
- <TD>57127</TD>
- </TR>
复制代码 利用-html选项,我们可以将结果输出为简朴的 HTML 表。
在 SQLite 教程的这一部分中,我们利用了sqlite3下令行工具。 我们已经描述了各种元下令,展示了如何转储表以及从文件中读取 SQL。 我们提到了 sqlite 的历史和资源文件。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |