萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> 資料庫綜合

Perl DBI 連接 MySQL 實戰:從安裝驅動到 CRUD 操作的完整範例

環境準備

# Ubuntu/Debian
sudo apt-get install libdbi-perl libdbd-mysql-perl mysql-client

# CentOS/RHEL
sudo yum install perl-DBI perl-DBD-MySQL mysql

# CPAN 手動安裝
cpan DBI DBD::mysql

完整腳本範例 mysql_demo.pl

#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use feature 'say';

# ========== 配置 ==========
my $dsn = "DBI:mysql:database=testdb;host=127.0.0.1;port=3306;mysql_enable_utf8=1";
my $user = "perl_user";
my $pass = "PerlPass123!";
# ============================

# 1. 建立連接(RaiseError 自動拋出異常,AutoCommit 開啟)
my $dbh = DBI->connect($dsn, $user, $pass, {
    RaiseError       => 1,
    PrintError       => 0,
    AutoCommit       => 1,
    mysql_auto_reconnect => 1,
}) or die "連接失敗: $DBI::errstr";

say "MySQL 連接成功,Server 版本: ", $dbh->{mysql_serverversion};

# 2. 創建測試表
$dbh->do(q{
    CREATE TABLE IF NOT EXISTS perl_test (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        email VARCHAR(100),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
});

# 3. 插入數據(預處理語句,防注入、提升性能)
my $sth_ins = $dbh->prepare("INSERT INTO perl_test (name, email) VALUES (?, ?)");
$sth_ins->execute('Alice', 'alice@example.com');
$sth_ins->execute('Bob', 'bob@example.com');
$sth_ins->execute('Charlie', undef);  # NULL 值
say "插入 3 行,最後自增 ID: ", $dbh->{mysql_insertid};

# 4. 批量插入(execute_array)
my $data = [
    ['David', 'david@example.com'],
    ['Eve',   'eve@example.com'],
    ['Frank', 'frank@example.com'],
];
my $tuples = $sth_ins->execute_array({ArrayTupleStatus => \my @status}, $data);
say "批量插入 $tuples 行";

# 5. 查詢數據
my $sth_sel = $dbh->prepare("SELECT id, name, email, created_at FROM perl_test WHERE name LIKE ?");
$sth_sel->execute('%a%');  # 包含 a 的名字
say "\n查詢結果 (name LIKE '%a%'):";
while (my $row = $sth_sel->fetchrow_hashref) {
    printf "ID: %-3d  Name: %-10s  Email: %-25s  Created: %s\n",
        $row->{id}, $row->{name}, $row->{email} // 'NULL', $row->{created_at};
}

# 6. 更新數據
my $sth_upd = $dbh->prepare("UPDATE perl_test SET email = ? WHERE name = ?");
my $rows = $sth_upd->execute('alice.new@example.com', 'Alice');
say "\n更新 $rows 行";

# 7. 刪除數據
my $sth_del = $dbh->prepare("DELETE FROM perl_test WHERE name = ?");
$rows = $sth_del->execute('Charlie');
say "刪除 $rows 行";

# 8. 事務控制示例
eval {
    $dbh->begin_work;
    $dbh->do("INSERT INTO perl_test (name) VALUES ('Txn_Test')");
    $dbh->do("UPDATE perl_test SET name = 'Txn_Test_2' WHERE name = 'Txn_Test'");
    $dbh->commit;
    say "事務提交成功";
};
if ($@) {
    $dbh->rollback;
    warn "事務回滾: $@";
}

# 9. 斷開連接
$dbh->disconnect;
say "\n連接已關閉,腳本結束。";

關鍵最佳實踐

  1. 始終使用預處理語句(prepare/execute):防 SQL 注入、計劃複用、類型安全。
  2. 啟用 RaiseError => 1:異常自動 die,配合 eval 捕獲,避免靜默失敗。
  3. 顯式指定 mysql_enable_utf8=1(DBD::mysql < 4.041)或 mysql_enable_utf8mb4=1(新版),確保 UTF-8 全鏈路正確。
  4. 連接池化:長運行進程(如 Web 應用)使用 DBIx::Connector 或 Mojo::mysql 管理連接池,避免頻繁連接/斷開開銷。
  5. 錯誤處理模式:eval { ... }; if ($@) { rollback; log; } 覆蓋所有寫操作。
  6. 大結果集流式處理:$sth->execute; while (my $row = $sth->fetchrow_hashref) { ... } 避免一次性載入內存。

常見問題排查

現象原因解決
install_driver(mysql) failed缺少 DBD::mysql 或客戶端庫安裝系統包或 cpan DBD::mysql
中文亂碼 / 顯示字符集協商失敗DSN 加 mysql_enable_utf8mb4=1,表/庫 CHARSET=utf8mb4,連接後 $dbh->do("SET NAMES utf8mb4")
MySQL server has gone away連接超時/斷開啟用 mysql_auto_reconnect=1,或用連接池心跳檢測
預處理佔位符 ? 不工作在識別符位置(表名、列名)不能用佔位符表名/列名用 QUOTENAME 或應用層驗證後拼接

Perl + DBI 是系統運維、數據遷移、ETL 腳本的經典利器。掌握預處理、事務、UTF-8、連接池四大核心,即可編寫健壯、高性能的 MySQL 自動化腳本。

copyright © 萬盛學電腦網 all rights reserved