分享
 
 
 

DBI/mysqlFAQ

王朝mysql·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

1. 哪里可以找到关于mysql和DBI的文档资料?

答:mysql可以到其官方主页http://www.mysql.com关于DBI可以到DBD/DBI主页

http://www.symbolstone.org/technology/perl/DBI。

在http://www.savebaseball.com/mysql也可以找到DBI和mysql的一些信息。已经安

装了DBI的系统可以在用perldoc DBI 或 man DBI 或 perldoc mysql 等命令查看信息。

2. 什么是DBI?

答:以下答案引自DBI的作者Tim Bunce:"DBI是用于Perl语言、操作数据库的应用程序

接口(API)。DBI API规范定义了一套函数(functions),变量和协定, 提供了一个稳定的

数据库接口而不必考虑实际使用什么样的数据库" 用更精炼的语言来描述就是,DBI作为

Perl语言的接口,允许使用者不需要更改程序就可以操作不同的数据库。

3. 哪里可以下载DBI?

答: http://www.perl.com/CPAN , http://www.nighthawk.com.cn

4. 什么是mysql?

答: mysql是一个真正多用户、多线程的SQL数据库服务器. SQL 是世界上最普及的数据

库语言. mysql是客户/服务端机制,即包括一个后端的服务器和许多不同的客户程序和库。

mysql数据库是众多的关系型数据库产品中的一个,相比较其它系统而言,mysql数据库

可以称得上是目前运行速度最快的SQL语言数据库。 除了具有许多其它数据库所不具备

的功能和选择之外,mysql数据库是一种完全免费的产品,用户可以直接从网上下载数

据库,用于个人或商业用途,而不必支付任何费用。

mysql数据库具有以下主要特点:

a. 同时访问数据库的用户数量不受限制;

b. 可以保存超过50,000,000条记录;

c. 是目前市场上现有产品中运行速度最快的数据库系统;

d. 用户权限设置简单、有效。

5. 哪里可以下载mysql?

答: http://www.mysql.com

6. 如何知道我现在正用着的mysql的版本?

答: 登录mysql以后,用s命令可以看到许多关于mysql的信息.

7. 如何加入DBI邮件列表?

答: 要获得更多的信息和更新消息,你可以通过访问网址www.isc.org/dbi-lists.html

来加入DBI邮件列表(或者发一封电子邮件到dbi-users-request@isc.org).

8. 如何安装mysql

答:去http://www.mysql.com/download_win.html,下载mysql-Win32发行版, 将zip文

件解压到一个临时目录并且运行安装程序setup.exe,缺省的典型安装, 所有的mysql文

件将会安装到c:mysql目录下。

启动mysql的方法是运行c:mysqlbinmysqld-shareware.exe,你可以看到一个dos窗口,

并在几秒钟后关闭。如果没有显示错误信息,mysql就已经运行了。

9. 如何安装DBI模块?

答:安装dbi之前,请先安装activeperl(http://www.activestate.com 处可下载)

1)在线安装

连接上Internet,开一DOS窗口,在提示符下键入:PPM

PPM> help (可以得到帮助信息)

PPM> query DBI (可以察看是否已经安装了DBI)

PPM> install DBI (自动下载并安装DBI,会列出所有安装的文件及路径

2)离线安装

从www.nighthawk.com.cn处下载DBI.zip,解开到一个临时目录 然后,在dos下,键入命令:

ppm install dbi.ppd

10. DBI要求什么版本的Perl?

答:Perl 5.004_04以上

11. 如何从一个字符串中过滤特别字符?

答: 用$dbh->quote()方法.

quote()方法可从字符串中提取特别字符(如:引号等),然后自动加上右边的引号. 但不

能处理所有的输入(如二进制数据).

#!/usr/local/bin use DBI;

# 连接SQL服务器 ....

# 从网页表单中取得字符信息.

my $string = $cgi_data{'user_input'};

$string = $dbh->quote($string);

# 因为quote已经加上了右边的引号,所以你不必在加上.

my $sql_q = "SELECT * FROM $table WHERE field = $string ";

12. 有没有可能在$sth中查出SQL语句的类型?

答:可试下这个:

if ($sql_statement =~ /^s*(insert|update|delete)/i) { # do something }

elsif ($sql_statement =~ /^s*select/i) { # do something }

else { # do something }

13. 如何加密一个密码,并将来和输入密码向相比较?

答: 保存一个密码(即从网页上输入的),首先要对密码加密然后再把它保存在数据库中。

mysql已经有一个加密函数来对一个字符串加密.

# 连接sql server

# 从表单中取得user id 和 password

# 你可能要通过$dbh->quote()函数来确定输入中没有会破坏SQL语句的字符

my $insert_user = "INSERT INTO $user_table (user_id,password)

VALUES('$user_id',PASSWORD('$password')";

my $insert_sth = $dbh->prepare($insert_user);

$insert_sth->execute() or die "Error : $dbh->errstr";

# 检查用户是否输入了正确的字符

# 注意 : 又必须先运行dbh->quote()

my $check_sql = "SELECT * FROM $user_table WHERE

user_id = $user_id AND passwordfield = PASSWORD('$password_entered')";

如果你不想用mysql的PASSWORD函数, 你可以在保存前用perl的crypt 函数来加密。 进

行比较时,先对输入密码crypt,然后与保存在数据库中的已加密密码进行比较。

14. 如何在mysql中创建表 ?

答:试下这个 ..

CREATE TABLE pictures( picture_id INT UNSIGNED NOT NULL AUTO_INCREMENT,

category_id SMALLINT UNSIGNED NOT NULL,

location VARCHAR(40),

thumb VARCHAR(40),

title VARCHAR(80) NOT NULL,

description TINYTEXT,

last_modified DATE,

last_viwed DATE,

view_count INT UNSIGNED,

user_id VARCHAR(20) NOT NULL,

colour ENUM('true','false') NOT NULL DEFAULT 'true',

PRIMARY KEY (picture_id),

INDEX (title),

INDEX (user_id),

INDEX (category_id),

INDEX (colour) );

15. 如何在M个纪录中只列出N个,并用翻页的方法列出其它?

答:可以采用mysql的LIMIT函数.

注意:下面的代码用了cgi-lib.pl的函数来获取网页输入数据.

sub List_Result{

my ($user_action) = @_;

my %cgi_data;

&ReadParse(%cgi_data);

my $limit = 10 ;

my $offset = $cgi_data{'offset'};

my $printed = $cgi_data{'printed'};

my $prev_offset = $cgi_data{'prev_offset'};

my $next_action = $cgi_data{'next_action'};

my $print_cnt = 0;

$new_prev_offset = $offset;

#下面的代码取得用户的操作

if ($next_action eq "Next"){

$offset += $limit;

}

elsif($next_action eq "Previous"){

if ($printed < $limit){

$offset = $prev_offset;

}else{

$offset -= $printed;

}

}

else { $offset = 0 ; }

}

my $SELECT ;

my $LIMIT = " LIMIT $offset,$limit";

# 如果$KEEP_SQL 为空,则表示重新开始,用旧的sql语句

if ($KEEP_SQL eq ""){

if($user_action eq "list_all"){

$SELECT = "SELECT * FROM mytable ";

}

else{

$SELECT = "SELECT * FROM mytable WHERE rec_id = $rec_id ";

}

}else{

$SELECT = $KEEP_SQL;

}

my $SQL = $SELECT.$LIMIT;

# KEEP_SQL将被保存在一个隐含的表段输入中,这个变量保证每次都用一个sql语句.

my $KEEP_SQL = $SELECT;

my $sth = $dbh->prepare($SQL);

$sth->execute() or die "Can't execute:";

# 做你想做的事情.

print " [form method=post action=$this_cgi] ...

... 列出结果 ..

[input type=hidden name=offset value=$offset]

[input type=hidden name=printed value=$printed]

[input type=hidden name=prev_offset value=$new_prev_offset]

[input type=hidden name=user_action value=viewing_result]

[input type=hidden name=KEEP_SQL value=$KEEP_SQL] ";

if ($offset > 0 ) {print "[input type=submit name=next_action width=100 value="Previous"]n"; }

if ($printed == $limit){ print "[input type=submit name=next_action width=100 value="Previous"n"]; }

print "[/form]";

16. 如何获得表的字段信息?

答:

#!/usr/bin/perl

# connect to db

my $dbh = DBI->connect(bla..bla..bla);

my $sql_q = "SHOW COLUMNS FROM $table";

my $sth = $dbh->prepare($sql_q);

$sth->execute;

while (@row = $sth->fetchrow_array){

print"Field Type Null Key Default Extran";

print"---------------------------------------------------------------n";

print"$row[0] $row[1] $row[2] $row[3] $row[4] $row[5]n";

}

17. 如何添加一个超级用户 ?

答: 你可以用GRANT语句:

shell> mysql --user=root mysql

mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost

IDENTIFIED BY 'something' WITH GRANT OPTION;

mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%"

IDENTIFIED BY 'something' WITH GRANT OPTION;

超级用户可以从任何地方连接服务器,但必须使用一个密码('something').

请注意我们同时对monty@localhost和monty@"%"用了GRANT语句。如果不加上

localhost,当我们(超级用户)从本机上连接时,localhost上mysql_install_db创

建的匿名用户会取得更高的优先权,因为它有更特别的Host字段值,使得在用户列

表中占据靠前的位置.

18. 如何知道mysql服务器中所有可供使用的数据库?

答: 用data_sources($driver_name)方法,这个方法返回SQL服务器中数据库名字列表

例: $db_names = DBI->data_sources("mysql");

19. 如何连接SQL服务器?

答:

#!/usr/bin/perl

use DBI;

my $database_name = "db_name";

my $location = "localhost";

my $port_num = "3306"; # 这是mysql的缺省值

# 定义SQL服务器的位置.

my $database = "DBI:mysql:$database_name:$location:$port_num";

my $db_user = "user_name";

my $db_password = "user_password";

# 连接.

my $dbh = DBI->connect($database,$db_user,$db_password);

# 做你要做的事情.. ... ...

$dbh->disconnect;

$exit;

20. 如何从SQL服务器上获取记录数据?

答: 从SQL服务器上获取记录数据,必须先连接服务器,然后提交SQL查询语句,服务器则返回结果

#!/usr/bin/perl

# 连接服务器 (见22)

my $sql_statement = "SELECT first_name,last_name FROM $table ORDER BY first_name";

my $sth = $dbh->prepare($sql_statement);

my ($first, $last);

# 结果保存在$sth中 $sth->execute() or die "无法执行SQL语句:

$dbh->errstr"; $sth->bind_columns(undef, $first, $last);

my $row; while ($row = $sth->fetchrow_arrayref) {

print "$first $lastn";

# 或者

print "$row->[0] $row[1]n";

}

以上的程序将列出结果中的每一行,打印出first name和last name。 这是最快的

提取数据的方法之一。

21. 如何从服务器随机地提取记录?

答: 用mysql的LIMIT函数.

$Query = "SELECT * FROM Table";

$sth = $dbh->prepare($Query);

$numrows = $sth->execute;

$randomrow = int(rand($numrows));

$sth = $dbh->prepare("$Query LIMIT $randomrow,1");

$sth->execute;

@arr = $sth->fetchrow;

22. 插入记录后,如何获得自动增加的主键值?

答: insertid方法是mysql特有的,也许不能在其它SQL server上工作

#!/usr/bin/perl

# 连接数据库 ....

my $sql_statement = "INSERT INTO $table (field1,field2) VALUES($value1,$value2)";

my $sth = $dbh->prepare($sql_statement);

$sth->execute or die "无法添加数据 :

$dbh->errstr";

# 现在我们可以取回刚刚插入后生成的主键.

my $table_key = $sth->{insertid};

# 也可以用这种方法(标准的DBI方法)

my $table_key = $dbh->{'mysql_insertid'};

$sth->finish;

23. 执行SELECT查询以后,如何获得记录行数?

答: 有好几种方法可以做到。这是其中的一种:

# 文档中说这种方法不行,但对我来说却可以,你或许也行.

my $mysql_q = "SELECT field1,field2 FROM $table WHERE field1=$value1";

my $sth = $dbh->prepare($mysql_q);

my $found = $sth->execute or die "无法执行 :

$dbh->errstr";

$sth->finish;

# 这是一种较慢的方法,而且做SELECT查询时还不太可靠.

my $sql = q(select * from $table where field = ? );

my $sth = $dbh->prepare($sql);

$sth->execute('$value');

my $rows = $sth->rows;

$sth->finish;

# 这是一种较快的方法.

my $sql = q(select count(*) from $table where field = ? );

my $sth = $dbh->prepare($sql); $sth->execute('$value');

my $rows = $sth->fetchrow_arrayref->[0];

$sth->finish;

24. 为什么SELECT LAST_INSERT_ID(USER_ID) FROM User返回的是所有的user id而不是最后一个?

答: 摘自手册:"在服务器上最后创建的ID是根据每个连接来单独管理的。也就是说,

它不能被另外一个客户端改变. 甚至你用一个非空和非零的值来更新另外一个

AUTO_INCREMENT字段,它也不会改变. 如果算式做为一个参量赋给UPDATE语句中的

LAST_INSERT_ID(),则参量会返回LAST_INSERT_ID()的值."

你真正需要的是: SELECT USER_ID FROM User ORDER BY USER_ID DESC LIMIT 1

25. WHERE语句中可否使用两个条件?

答: 可以

my $sql_statment = "SELECT * FROM $table WHERE $field1='$value1' AND $field2='$value2'";

26. 如何在多个字段中查找一个关键字?

答: 试下这个:

SELECT concat(last,' ',first,' ',suffix,' ',year,' ',phone,' ',email) AS COMPLEAT, last, first, suffix, year, dorm, phone, box, email

FROM Student HAVING COMPLEAT

LIKE '%value1%' AND COMPLEAT LIKE '%value2%' AND COMPLEAT LIKE '%value3%'

27.如何找到一个星期前创建的记录?

答: 我们需要用DATE函数来做sql查询:

DATE_ADD(date,INTERVAL expr type)

DATE_SUB(date,INTERVAL expr type)

ADDDATE(date,INTERVAL expr type)

SUBDATE(date,INTERVAL expr type)

例如 : # 这个查询语句返回所有"年龄"小于或等于7天的记录

my $sql_q = "SELECT * FROM $database WHERE DATE_ADD(create_date,INTERVAL 7 DAY) >= NOW() ORDER BY create_date DESC";

28.如何取回所有字段的数据并用"column_name" => value来放入一个相关的数组中?

答:用$sth->fetchrow_hashref 方法.

$SQL = "SELECT * FROM members";

my $sth = $dbh->prepare($SQL);

$sth->execute or die "sql语句错误 ".

$dbh->errstr;

my $record_hash;

while ($record_hash = $sth->fetchrow_hashref){

print "$record_hash->{first_name} $record_hash->{last_name}n";

}

$sth->finish;

29.如何保存一个图像文件(JPG和GIF)到数据库中?

答:

file: test_insert_jpg.pl

-------------------------

#! /usr/bin/perl

use DBI;

open(IN,"/imgdir/bird.jpg");

$gfx_file=join('',);

close(IN);

$database="speedy";

$table="archive";

$user="stephen";

$password="none";

$dsn="DBI:mysql:$database";

$dbh=DBI->connect($dsn, $user, $password);

$sql_statement=<<"__EOS__";

insert into $table (id, date, category, caption, content, picture1, picture2,

picture3, picture4, picture5, source, _show) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

__EOS__

# uncomment to debug sql statement

# --------------------------------

#open(SQLLOG,">>sql_log_file");

#print SQLLOG scalar(localtime)."t$sql_statementn";

#close(SQLLOG);

$sth=$dbh->prepare($sql_statement);

$sth->execute(NULL,NULL,"car|sports","Porsche Boxster S","German excellence",$gfx_file,NULL,NULL,NULL,NULL,"European Car","Y");

$sth->finish(); $sth=$dbh->prepare("SELECT * FROM $table");

$sth->execute();

while($ref=$sth->fetchrow_hashref()){

print "id = $ref->{'id'}tcategory = $ref->{'category'}tcaption = $ref->{'caption'}n";

}

$numRows=$sth->rows;

$sth->finish();

$dbh->disconnect();

file: serve_gfx.cgi

-----------------------------------------------------

#!/usr/bin/perl

$|=1;

use DBI;

$database="speedy";

$table="archive";

$user="stephen";

$password="none";

$dsn="DBI:mysql:$database";

$dbh=DBI->connect($dsn, $user,$password);

$sth=$dbh->prepare("select * from $table where id=1");

$sth->execute();

$ref=$sth->fetchrow_hashref();

print "content-type: image/jpgnn";

print $ref->{'picture1'};

$numRows=$sth->rows;

$sth->finish();

$dbh->disconnect();

30. 如何插入N个记录?

答:

# 让我们插入10000个记录

my $rec_num = 10000;

my $PRODUCT_TB = "products";

my $dbh = DBI->connect($database,$db_user,$db_password) or die "无法连接数据库n";

my $sth = $dbh->prepare("INSERT INTO $PRODUCT_TB (name,price,description,pic_location) VALUES (?,?,?,?)");

for ($i = 1; $i <= $rec_num; $i++){

my $name = "Product $i";

my $price = rand 350;

my $desc = "Desccription of product $i";

my $pic = "images/product/product".$i.".jpg";

$sth->execute($name,$price,$desc,$pic);

}

$sth->finish();

print "完成插入$rec_num个记录到表$PRODUCT_TBn";

$dbh->disconnect;

exit;

31. 如何创建一个date字段,使其缺省值是新记录创建时的日期?

答:有很多种方法可以做到:

(1) 用TIMESTAMP

Create Table mytable( table_id INT NOT NULL AUTO_INCREMENT,

value VARCHAR(25),

date TIMESTAMP(14),

PRIMARY KEY (table_id) );

当插入或更新记录时,TIMESTAMP字段将自动地设置成当前日期。 如果你不想更新

时改变日期,可在用UPDATE语句时,把日期字段设置成原来的(插入日期)。

(2) 用NOW()函数.

Create Table mytable( table_id INT NOT NULL AUTO_INCREMENT,

value VARCHAR(25),

date DATE,

PRIMARY KEY (table_id) );

在insert语句中设置date=NOW().

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有