首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Perl DBI 操作 MySQL 避坑指南:UTF8、特殊字符、自動重連與超時優化

     編輯:MySQL 綜合教學

核心 Tips 速查

場景問題解決方案
MySQL 字符集 UTF8讀取中文亂碼啟用 use utf8; + 三標準流 binmode
用戶輸入含單引號/反斜槓SQL 拼接報錯/注入佔位符 ? + execute(@params) + qq// 包裹字符串
長連接閒置超時MySQL server has gone awaymysql_auto_reconnect=1 或會話級調大 wait_timeout

1. UTF8 環境初始化模板

use utf8;
binmode(STDOUT, ':encoding(utf8)');
binmode(STDIN,  ':encoding(utf8)');
binmode(STDERR, ':encoding(utf8)');

my $dbh = DBI->connect("dbi:mysql:dbname=test;host=localhost;mysql_enable_utf8=1",
                       'user', 'pass', { RaiseError => 1, PrintError => 0 });
  • mysql_enable_utf8=1(DBD::mysql 4.004+)自動設置連接字符集為 utf8mb4。
  • binmode 確保標準流編碼一致,避免終端顯示亂碼。

2. 安全執行含特殊字符的 SQL

# ❌ 危險:字符串拼接
$dbh->do("INSERT INTO t(c) VALUES('$user_input')");

# ✅ 安全:佔位符 + execute 參數綁定
my $sth = $dbh->prepare("INSERT INTO t(c) VALUES(?)");
$sth->execute($user_input);

# 批量插入示例
my $sth = $dbh->prepare("INSERT INTO week_event VALUES(?,?,?,?,?,?,?)");
$sth->execute($OId, $CId, $Time, $EventType, $CDesc, $PId, $RFlag);
# 若字符串變量可能含特殊字符,用 qq// 確保作為標量傳遞
$sth->execute($OId, $CId, qq/$Time/, $EventType, qq/$CDesc/, $PId, $RFlag);

3. 連接自動重連與超時優化

方案 A:DBD::mysql 4.012+ 內建自動重連

$dbh->{mysql_auto_reconnect} = 1;
# 連接斷開時,下次方法調用自動重連並重試

方案 B:舊版驅動 / 通用會話級超時調大

$dbh->do("SET SESSION wait_timeout=72000");
$dbh->do("SET SESSION interactive_timeout=72000");
# 20 小時無操作不斷開,適用於長跑批處理腳本

原理:MySQL 默認 wait_timeout=28800(8 小時),長連接閒置超過此值被 Server 主動斷開,客戶端再發包即報 gone away。

完整範例:健壯的長連接批量導入腳本骨架

#!/usr/bin/perl
use strict; use warnings;
use DBI; use utf8;
binmode(STDOUT, ':encoding(utf8)');
binmode(STDERR, ':encoding(utf8)');

my $dbh = DBI->connect("dbi:mysql:dbname=prod;host=10.0.0.1;mysql_enable_utf8=1",
                       'app', 'secret', { RaiseError => 1, AutoCommit => 0 });
$dbh->{mysql_auto_reconnect} = 1;

my $sth = $dbh->prepare("INSERT INTO events(uid,type,msg,ts) VALUES(?,?,?,?)");
open my $fh, '<:encoding(utf8)', 'events.csv' or die $!;
while (<$fh>) {
    chomp; my @f = split /,/;
    $sth->execute(@f);
    $dbh->commit if $. % 1000 == 0;
}
$dbh->commit;
$dbh->disconnect;

避坑總結:佔位符防注入、utf8mb4 防亂碼、auto_reconnect 防斷連——三板斧打通 Perl 操作 MySQL 的任督二脈。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved