Perl学习笔记(十)--通过DBI访问数据库
Perl访问数据库最常用的包是DBI,可以在www.cpan.org找到。使用ppm命令即可图形化安装。另外还需要安装对应数据库的驱动包,例如DBD::MySQL、DBD::Oracle、DBD::Sybase或者DBD::ODBC等。
一、基本流程
一般来说,数据库操作由以下几个步骤组成一个常见的流程:
1. 建立一个数据库连接
2. 通过建立的数据库连接,执行SQL语句
3. 执行SQL后获取返回的数据集
4. 在数据集中对记录进行处理,一般是一个循环的过程
5. 处理完毕,关闭数据库连接,释放资源
下面是按照上述的流程,在Perl中访问MySQL的一段代码,以这段代码为例,详细说明DBI的使用方法。
#!/usr/bin/perl -w use strict; use DBI;my $dbh = DBI->connect("DBI:mysql:test:192.168.1.2", 'root', 'password'); my $sth = $dbh->prepare("SELECT * FROM test1"); $sth->execute();while ( my @row = $sth->fetchrow_array() ) {print join('\t', @row)."\n"; }$sth->finish(); $dbh->disconnect();
1.1 连接数据库
my $dbh = DBI->connect("DBI:mysql:test:192.168.1.2", 'root', 'password');
调用DBI的方法DBI->connect
来建立一个数据库的连接,如果连接成功则返回一个数据库连接句柄,之后执行SQL等操作都要把这个连接句柄作为一个操作参数。在connect调用中,首先要提供一个数据库连接串。这个连接串用冒号分为了几个部分:
小节 | 说明 |
---|---|
DBI | 接口类型 |
mysql | 数据库类型 |
test | 数据库名称 |
192.168.1.2 | 数据库主机地址 |
在前面例子中的连接串中,DBI表示这是DBI接口的一个连接串;mysql表示要连接的数据库是MySQL数据库(如果要连接Oracle数据 库,这里则是oracle),不同的数据库有不同的连接串定义,可以参考DBI对应的访问驱动的说明;test指明了连接到数据库主机上的数据库名 称;192.168.1.2就是MySQL服务器的IP地址。这里要注意的是,连接串中的数据库类型mysql必须小写。如果省略了主机名,则缺省为 localhost。connect方法的后面两个参数是连接数据库主机的用户名和密码,这个可是不可缺少的 J
如果在连接过程中出现任何错误,则connect的返回值都会是undef(和C语言中的NULL是一回事)。这里为了简化而略去了错误检查,实际做项目的时候应当对这些错误和返回值的进行检查。
1.2 执行SQL语句
my $sth = $dbh->prepare("SELECT * FROM test1"); $sth->execute(); $dbh->do(“UPDATE test1 SET time=now()”);
连接上了数据库,获得了数据库连接句柄,就可以利用这个句柄来对数据库进行操作了。要执行一条SQL语句,为了提高性能,DBI分两个步骤来做。先把 SQL语句通过prepare方法提交到数据库,数据库为该语句分配执行资源,之后调用execute方法通知数据库执行该SQL语句。注意 prepare方法是通过数据库连接句柄调用的,如果成功则返回一个该SQL的句柄,之后通过该SQL语句句柄调用execute执行SQL。 一般来说execute执行的都是返回数据的语句(例如SELECT语句)。反之如果执行INSERT、UPDATE、DELETE、CREATE TABLE等不需要返回数据的语句,则有一个更方便、快速的方法 $dbh->do(SQL语句)
,可以省去prepare的步骤。do方法返回的是受该SQL影响的记录数量。
1.2.1 技巧:对SQL进行排版
常写大段SQL的朋友可能会对于SQL中的引号很头痛,每每都因为引号的问题搞的SQL语句乱成一团分辨不清。还记得上篇文章讲过的qq吗?这里正 是它的好用处。由于qq中的字符串同双引号” ”内的字符串一样会对变量进行解释,同时qq还可以换行。因此使用它来对SQL进行排版是非常好的一个选择,例如像这样的一条SQL语句:
my $res_operator = $dbhandle->prepare( qq{SELECT o_customerid, COUNT(*) AS totalMsgNum FROM mm4fcdrsWHERE (m_date>'$begindate') AND (m_date<'enddate') GROUP BY o_customerid });
1.2.2 通过SQL语句中的参数优化查询执行效率
在执行大量INSERT之类的语句的时候,反复向数据库服务器提交同样结构的一个SQL语句,在这种情况下可以利用prepare和SQL参数来优化执行效率:
1.先使用prepare提交一个SQL模板给数据库服务器,把其中值的部分用参数占位符代替。
2.使用prepare让服务器为该SQL准备了执行资源后,调用execute并在该方法中传入参数实际的值执行SQL。
3.之后可以反复调用execute,不需要服务器重新prepare
假设要执行这样的一个系列的SQL
INSERT INTO test1 VALUES (NULL, ‘a’, ‘2005-04-01’) ... ... INSERT INTO test1 VALUES (NULL, ‘z’, ‘2005-04-01’)
其中第二个字段的值是从a到z的字母。那么可以这样来优化执行效率:
my $sth = $dbh->prepare( qq{INSERT INTO test1 VALUES (NULL, ?, ‘2005-04-01’) } );for my $value('a'..'z') {$sth->execute($value); }
其中的问号就是前面说的参数占位符了,它的意思就是告诉在准备执行资源的服务器:这个SQL的这个位置会有一个值,但是现在还不知道,等下执行的时候再告 诉你。 prepare了之后,用一个循环产生a-z的字符给变量$value,然后将$value在execute方法中作为一个参数传入,服务器那里会自动用 传入的值替换前面的"?"。需要提醒的是,传入的参数个数一定要和SQL中的占位符的数量一样。
1.3 读取记录
熟悉ADO的朋友一定知道里面有一个DataReader对象,DBI中读取数据的方法和它非常的相似。简单来说,就是单向、流式的读取数据,也就是每次只能向后读一条数据直到没有数据可以读取。
文章开头的例子中,用了 $sth->fetchrow_array()
方法来读取数据。其实DBI读取数据还有几种常见的方法,这几个方法是类似的,所不同的是返回记录的形式。
1.3.1 fetchrow_array
返回一个由字段的值组成的数组。该数组的第1个元素就是当前记录第1个字段的值。
while ( my @row = $sth->fetchrow_array() ) {print "$row[0], $row[1], $row[2]\n"; }
或者这样,不过要注意字段对应的顺序
while ( my ($id, $name, $time) = $sth->fetchrow_array() ) {print "$id, $name, $time\n"; }
1.3.2 fetchrow_arrayref
返回由字段的值组成的数组的引用。同fetchrow_array
的区别很明显,fetchrow_arrayref
返回的数组的引用。
while ( my $row_ref = $sth->fetchrow_arrayref() ) {for (my $i = 0; $i < @{$row_ref}; $i++) {print "$row_ref->[$i]\t";}print "\n"; }
这里要注意的是,如果要取字段的个数,需要把这个引用转成数组的形式获得 @{$row_ref}
。获取数组元素的值的时候,因为$row_ref是引用,因此需要使用->
操作符。
1.3.3 fetchrow_hashref
返回一个由”字段名-字段值”这样的”键-值”对组成的HASH表。关键的不同就是,只有这个方法可以通过一个字段名获得它的值,而不必关心这个字段是第几个字段。而前者只能依靠索引来访问值。不过缺点就是,效率要比前面两个差一些。
while ( my $record = $sth->fetchrow_hashref() ) {for my $field( keys %{$record} ) {print "$field: $record->{$field}\t";}print "\n"; }
这里需要复习一下HASH表的操作方法。keys操作符获取HASH的键(key)的数组,$record->{$field}
获得HASH表中$field对应的值。注意这里同样是引用,因此要用->
操作符。
使用上面三个方法可以基本解决问题了。此外,还有两个方法fetchall_arrayref
和selectall_arrayref
可以直接通过SQL一次性获取整个数据集,不过使用上稍微复杂一些,要涉及到 perl的scalar 操作符,这里就不赘述了。有兴趣的读者可以参考DBI的相关资料。
最后是收尾工作。
1.4 结束一个SQL会话
$sth->finish();
1.5 断开数据库连接
$dbh->disconnect();
http://dbi.perl.org/
http://www.perl.com/pub/1999/10/DBI.html
转载于:https://www.cnblogs.com/Hebe/p/4448187.html
Perl学习笔记(十)--通过DBI访问数据库相关推荐
- mysql 临时表 事务_MySQL学习笔记十:游标/动态SQL/临时表/事务
逆天十三少 发表于:2020-11-12 08:12 阅读: 90次 这篇教程主要讲解了MySQL学习笔记十:游标/动态SQL/临时表/事务,并附有相关的代码样列,我觉得非常有帮助,现在分享出来大家一 ...
- Mr.J-- jQuery学习笔记(十六)--展开和收起动画折叠菜单的实现
之前写过动画的隐藏与显示:Mr.J-- jQuery学习笔记(十四)--动画显示隐藏 动画隐藏与显示的一个小demo--对联广告:Mr.J-- jQuery学习笔记(十五)--实现页面的对联广告 与动 ...
- Python语言入门这一篇就够了-学习笔记(十二万字)
Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...
- windows内核开发学习笔记十五:IRP结构
windows内核开发学习笔记十五:IRP结构 IRP(I/O Request Package)在windows内核中,有一种系统组件--IRP,即输入输出请求包.当上层应用程序需要访问底层输入输 ...
- windows内核开发学习笔记十八:IRP 处理的标准模式
windows内核开发学习笔记十八:IRP 处理的标准模式 在 Windows 内核中的请求基本上是通过 I/O Request Packet 完成的. I/O manager ---> Dis ...
- 哈工大操作系统学习笔记十——信号量与死锁
哈工大os学习笔记十(信号量与死锁) 文章目录 哈工大os学习笔记十(信号量与死锁) 一. 信号量临界区保护 1.为什么要保护信号量 2.临界区 3.保护信号量的方法 3.1 轮换法 3.2 标记法 ...
- python爬虫学习笔记2模拟登录与数据库
前言 为了加入学校里面一个技术小组,我接受了写一个爬取学校网站通知公告的任务.这个任务比以前写的爬虫更难的地方在于,需要模拟登录才能获得页面,以及将得到的数据存入数据库. 本文按照日期来记录我完成任务 ...
- Kolin学习笔记十-kotlin与java互操作
Kolin学习笔记十 kotlin与java 可空性 互操作性 @JvmName @JvmFiled @jvmoverloads @jvmstatic 异常捕捉 函数类型操作 kotlin与java ...
- IOS之学习笔记十五(协议和委托的使用)
1.协议和委托的使用 1).协议可以看下我的这篇博客 IOS之学习笔记十四(协议的定义和实现) https://blog.csdn.net/u011068702/article/details/809 ...
- 吴恩达《机器学习》学习笔记十四——应用机器学习的建议实现一个机器学习模型的改进
吴恩达<机器学习>学习笔记十四--应用机器学习的建议实现一个机器学习模型的改进 一.任务介绍 二.代码实现 1.准备数据 2.代价函数 3.梯度计算 4.带有正则化的代价函数和梯度计算 5 ...
最新文章
- c语言怎样在不足n位数的整数前补0,C# String 前面不足位数补零的方法
- 车提示检测轮胎气压_无钥匙启动的车启动后,车主带着钥匙离开车,能不能把车开走?...
- TreeSet()详解
- 你不知道的javascript_你不知道的javascript(上)
- linux 文件描述符
- 标准化设计解决方案 - 标记语言和样式手册 表单
- makeObjectsPerformSelector 方法的用法
- LEFT OUTER JOIN
- redis 哨兵的原理
- linux谷歌浏览器无法登陆,新版CentOS 7.1上的谷歌浏览器无法启动
- vue实时获取当前时间
- 原生js以及jQuery删除节点
- fluent使用DPM模型计算出的颗粒沉积(trap)数据(.dpm格式)后处理python实现
- 上下取整函数的关系以及一些重要性质(附证明)
- 第四届长安杯电子取证大赛个人总结
- scrapy爬取斗鱼图片并且重命名后保存
- 【cocos2d-x4.0学习笔记】dya01
- php interface 抽象类,解析PHP中的抽象类(abstract class)和 接口(interface)
- woff字体文件转xml介绍
- 写给大忙人看的 - Java中图片压缩上传至MinIO服务器(4)
热门文章
- python基础知识整理-python入门基础知识点整理-20171214
- python项目实例初学者-经典Python案例,初学者的小帮手,立马学会Python!
- php和python web开发-Web开发应该学习php还是python
- python整数类型-Python 的数值类型(整数、长整数、浮点数和复数)
- python怎么导入视频-python中的导入如何使用,以及.和..相对导入的使用
- python读取excel-Python中使用第三方库xlrd来读取Excel示例
- linux上添加下载源的时候报错:无法添加 PPA:“‘此 PPA 不支持 bionic‘”,以及关于linuxPPA的介绍,如何查找软件包的PPA源,并添加PPA
- 在Jetson Xavier NX安装中文输入法(googlepinyin中文输入法)
- windows上报错:Could not find a version that satisfies the requirement torch==0.4.1
- ML-2 机器学习算法