`
yuexiaowen
  • 浏览: 121751 次
  • 性别: Icon_minigender_2
  • 来自: 咸阳
社区版块
存档分类
最新评论

MySQL 事务预编译查询和Perl DBI简化

    博客分类:
  • perl
 
阅读更多

许多WEB应用程序内部通常重复运行带不同自变量的相同数据库查询,或以全有或全无块的形式执行一组相关查询。要满足这些要求,大多数数据库系统(包括MySQL)支持预编译查询与事务,多数脚本语言(如PHP和Perl)也拥有内置函数访问这些数据库特性。然而,上述两项特性是MySQL的新功能,因此给那些以前没有见过它们的开发者制造了一些麻烦。

本文旨在解决这一问题。文章讨论了支持MySQL事务和预编译查询的Perl DBI函数,并对其工作原理和应用方法进行说明。

 

预编译查询

在数据库中执行批量上传时,我们经常见到这样的SQL查询,这些查询仅在提交给INSERT命令的参数上有所不同。在这些情况下,应用所谓的预编译查询是一种常用的优化方法,它为查询建立一个模板,然后再向模板中导入不同的必要值,从而减少了数据库消耗。如果使用得当,这个特性能够显著提高应用程序的性能。

 

为说明这一点,我们以一个二域表格为例,如下面的列表A所示:

 

 

mysql> SELECT * FROM users;

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

| fname | lname|

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

| Joe| Blow|

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

1 row in set (0.09 sec)

 

列表A

 

现在,假设我需要通过INSERT查询向这个表格中输入一组新记录。很明显,每次运行时,查询的格式保持不变,只有输入的值发生变化。要完成这一操作,最佳方法是为INSERT查询建立一个内置DBI“占位符”的模板,然后在每次运行时用实际值来代替占位符。如列表B所示:

 

#!/usr/bin/perl

use DBI;

# create database connection

my $dbh = DBI->connect("DBI:mysql:database=somedb;
host=localhost", "user", "pass", {''RaiseError'' => 1});

# prepare template query

my $sth = $dbh->prepare
("INSERT INTO users (fname, lname) VALUES (?, ?)");

# execute query with first set of parameters

$sth->execute(''John'', ''Doe'');

# execute query with second set of parameters

$sth->execute(''Jane'', ''Low'');

# close connection

$dbh->disconnect();

 

 

列表B

 

建立并执行一个带Perl DBI预编译SQL查询共分四个简单的步骤:

 

首先调用connect()方法初始化一个数据库句柄。这个方法以一个字符串为连接参数,这个字符串中包括数据库类型(”mysql”)、主机名称(”localhost”)和数据库名称(”somedb”);并向connect()方法提供用户名(”user”)和密码(”pass”)作为第二和第三自变量。

调用prepare()函数建立SQL查询模板。prepare()中用到的问号为代替实际值的占位符。

调用execute()方法向查询预编译模板中输入实际数据值,把它提交给占位符代替的自变量。注意,这里自变量的顺序十分重要,在上一步中必须为每个占位符定义一个自变量。每次通过一组不同的自变量调用execute()方法,就用相应的值执行一次INSERT查询。

调用disconnect()方法结束会话。

从一个外部文件中批量插入数据,是上述查询的典型应用。这时,首先调用prepare()方法,然后应用一个循环从文件中读入数据,每运行一次循环,即调用execute()方法在数据库中插入一组值。

 

事务

 

事务支持是MySQL的另外一项重要的新特性。简单来说,事务就是一个以全有或全无方式执行的SQL语句块(因为这些语句彼此相互依赖)。事务中的所有语句必须全部成功执行,事务才能成功完成;如果有任何一个语句出现错误,系统就会“退回”到原始状态,以避免数据连接/破坏问题。

 

在两个银行账户间转账就是一个典型的例子。在数据库中,转账过程包括二个步骤:首先,从源账户余额中提取转账金额,然后将其存入目标账户的余额中。如果第二步发生错误,那么第一步必须倒退到一个前面的“快照”,以避免余额失衡。大部分数据库(包括MySQL)通过一组命令完成这种转账过程。

 

START TRANSACTION命令标记一个新事务块开始,接着执行一系列SQL命令。

COMMIT命令标记一个事务块结束,表示在事务中发生的所有变化应被“提交”或永久化。

ROLLBACK命令标记一个事务块结束,并表示事务中发生的所有变化必须被撤销。

为说明它的实际应用,我们以一个存储用户账户的表格为例,如列表C所示:

 

mysql> SELECT * FROM accounts;

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

| id | label| balance |

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

|1 | Savings #1 |1000 |

|2 | Current #1 |2000 |

|3 | Current #2 |3000 |

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

3 rows in set (0.34 sec)

 

列表C

现在,假设我要转账400美元。实际的“事务”通过两个UPDATE语句来执行,一个语句将转账金额从源账户中取出,另一语句将其存入目标账户。如果我只是在账户间进行转账,那么整个过程中,所有账户的总余额(00)应一直保持不变。以下是完成转账的DBI代码(列表D):

 

 

#!/usr/bin/perl

use DBI;

# create database connection

my $dbh = DBI->connect
("DBI:mysql:database=somedb;host=localhost", 
"user", "pass", {''RaiseError'' => 1, ''AutoCommit'' => 0});

# trap errors using eval{}

eval {

# debit account #1

$dbh->do("UPDATE accounts SET balance = balance-400 WHERE id=1");

# credit account #2

$dbh->do("UPDATE accounts SET balance = balance+400 WHERE id=2");

# no errors so far

# commit changes

$dbh->commit();

};

# any errors

# rollback

if ($@) {

print "Transaction aborted: $@";

$dbh->rollback();

}

# close connection

$dbh->disconnect();

 

列表D

 

在Perl中执行一个事务共有四个基本步骤:

 

第一步,关闭数据库“自动提交”。(本质上说,自动提交意味着系统保存你所做的变化。)这一步很重要,因为你只应在确定所有的事务“单元”成功完成后,才保存发生的变化。在上面的例子中,我们在调用connect()方法时将AutoCommit选项设为0,完成关闭操作。

下一步,以普通方式执行INSERT、UPDATE和/或DELETE查询,但将这些查询包含在一个eval{}块中。这样做是为了保证:如果发生错误,程序会在块以外中断,事务就不会被提交。如果一切正常,发生的变化将在事务块中的所有查询执行后,通过调用commit()提交给数据库。

如果在执行事务块中任何一个语句时出现错误,程序将在eval{}块外中断,并继续执行后面的代码。这些代码首先打印一段错误信息,然后通过rollback()函数将数据库退回到事务前的状态。注意,一旦调用这个函数,事务即无法逆转。

调用disconnect()方法结束会话。

如你所见,用Perl和MySQL执行事务模型能够使MySQL数据库在遇到查询执行错误时更加稳定。但是,在新开始着手用这些新特性重写代码前,必须注意,它们实际上增加了系统的性能消耗;因此,在执行它们之前,最好进行一下成本效益分析。(T006)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签数据库  分类: Perl Script

要导入一批数据到数据库,使用DBI模块还是比较方便的

  1. #!/usr/bin/perl -w
  2. use DBI;
  3. use strict;
  4. my $dbh;
  5. my $INFILE=$ARGV[0];
  6. open LIST ,"<$INFILE" or die "can't open $INFILE\n";
  7. my $table="table_appinfo";
  8. $dbh=&connect();
  9. my $qurey=qq{insert into $table (ip,name,manage,dev,location) values(?,?,?,?,?) };
  10. my $sth=$dbh->prepare($qurey) || die $dbh->errstr;
  11. my $dev="lab";
  12. my $manage="namexxx";
  13. my $location='location';
  14. while(my $line=<LIST>){
  15.     my ($ip,$name)=split /\s+/,$line;
  16.     $sth->execute($ip,$name,$manage,$dev,$location);
  17.     print "insert $ip $name\n";
  18. }
  19. $dbh->disconnect();
分享到:
评论

相关推荐

    MySQL事务预编译查询和Perl DBI简化

    许多WEB应用程序内部通常重复运行带不同自变量的相同数据库查询,或以全有或全无块的形式 执行一组相关查询。...本文讨论了支持MySQL事务和预编译查询的Perl DBI函数,并对其工作原理和应用方法进行说明。

    MySql 5.1 参考手册.chm

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的过程 ...

    MYSQL

    pthreads 注意事项 4.10 Perl 安装说明 4.10.1 在Unix操作系统上安装 Perl 4.10.2 在 Win32上安装 ActiveState Perl 4.10.3 在 Win32 上安装 MySQL Perl 分发 4.10.4 使用 Perl DBI/DBD接口遇到...

    MySQL中文参考手册

    + 4.10.4 使用 Perl DBI/DBD接口遇到的问题 o 4.11 系统特定的问题 + 4.11.1 Solaris注意事项 + 4.11.2 Solaris 2.7 注意事项 + 4.11.3 Solaris x86 注意事项 + 4.11.4 SunOS 4 注意事项 + 4.11.5 Linux ...

    MySQL 5.1参考手册

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的...

    MySQL 5.1中文手冊

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的过程 ...

    mysql网络数据库指南(中文版) part1

    6.1.2 编译和连接客户机程序 153 6.2 客户机程序1—连接到服务器 154 6.3 客户机程序2—增加错误检查 156 6.4 客户机程序3—产生连接代码模块 158 6.5 客户机程序4—在运行时获取连接参 数 163 6.5.1 访问选项...

    MySQL中文参考手册.chm

    pthreads 注意事项 4.10 Perl 安装说明 4.10.1 在Unix操作系统上安装 Perl 4.10.2 在 Win32上安装 ActiveState Perl 4.10.3 在 Win32 上安装 MySQL Perl 分发 4.10.4 使用 Perl DBI/DBD接口...

    MySQL 5.1官方简体中文参考手册

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的过程 ...

    MySQL 5.1参考手册中文版

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的...

    MySQL 5.1参考手册 (中文版)

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的过程 ...

    MYSQL中文手册

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后...

    MYSQL网络数据库PDF学习资源

    6.1.2 编译和连接客户机程序 153 6.2 客户机程序1—连接到服务器 154 6.3 客户机程序2—增加错误检查 156 6.4 客户机程序3—产生连接代码模块 158 6.5 客户机程序4—在运行时获取连接参 数 163 6.5.1 访问选项文件...

    mysql5.1中文手册

    处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下...

    mysql官方中文参考手册

    2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从源码安装MySQL 2.8.7. 在Windows下编译MySQL客户端 2.9. 安装后的设置和测试 2.9.1. Windows下安装后的过程 2.9.2. Unix下安装后的过程 ...

Global site tag (gtag.js) - Google Analytics