歡迎您光臨本站 註冊首頁

DBI/MYSQL FAQ

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  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().


[火星人 ] DBI/MYSQL FAQ已經有552次圍觀

http://coctec.com/docs/linux/show-post-74264.html