perl - DBD::Firebird 编码/解码

标签 perl character-encoding firebird dbi

在此示例中,Firebird 返回未解码的字符串。是我没有正确设置数据库还是 Firebird 就是这样工作的?

#!/usr/bin/env perl
use warnings;
use 5.10.0;
use utf8;
use open qw( :std :utf8 );
use Devel::Peek;
use DBI;

my ( $db, $dbh, $sth, @array );
my $table = 'test_encoding';
my $create = "CREATE TABLE $table ( name varchar(32) )";
my $insert = "INSERT INTO $table ( name ) VALUES ( ? )";
my $select = "SELECT * FROM $table";
my $value = 'ä';

$db = '/home/me/my_firebird_db';
$dbh = DBI->connect(
    "dbi:Firebird:db=$db", 'user', 'password',
    { PrintError => 0, RaiseError => 1, ib_charset => 'UTF-8' }
);
$sth = $dbh->do( "DROP TABLE $table" );
$sth = $dbh->do( $create );;
$sth = $dbh->prepare( $insert );
$sth->execute( $value );
@array = $dbh->selectrow_array( $select );
Dump $array[0];
say $array[0];
say "";

$db = '/home/me/my_sqlite_db';
$dbh = DBI->connect(
    "dbi:SQLite:db=$db", '', '',
    { PrintError => 0, RaiseError => 1, sqlite_string_mode => 5 }
);
$sth = $dbh->do( "DROP TABLE IF EXISTS $table" );
$sth = $dbh->do( $create );
$sth = $dbh->prepare( $insert );
$sth->execute( $value );
@array = $dbh->selectrow_array( $select );
Dump $array[0];
say $array[0];

输出:

SV = PV(0x2105360) at 0x22628a0
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x22a37e0 "\303\244"\0
  CUR = 2
  LEN = 10
ä

SV = PV(0x2111470) at 0x2121220
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x1f2fed0 "\303\244"\0 [UTF8 "\x{e4}"]
  CUR = 2
  LEN = 10
ä

最佳答案

documentation of DBD::Firebird 的链接所示由 clamp 提供在评论中,您需要使用以下方式连接:

$dbh = DBI->connect(
    "dbi:Firebird:db=$db;ib_charset=UTF8", 'user', 'password',
    { PrintError => 0, RaiseError => 1, ib_enable_utf8 => 1 }

也就是说,ib_charset 属性必须位于连接字符串中,而不是散列中,并且其值必须为 UTF8(而不是 UTF-8!),并且您需要添加 ib_enable_utf8 并设置 1 到哈希值。

具体来说,this part :

ib_enable_utf8 (driver-specific, boolean)

Setting this attribute to TRUE will cause any Perl Unicode strings supplied as statement parameters to be downgraded to octet sequences before passing them to Firebird.

Also, any character data retrieved from the database (CHAR, VARCHAR, BLOB sub_type TEXT) will be upgraded to Perl Unicode strings.

Caveat: Currently this is supported only if the ib_charset DSN parameter is UTF8. In the future, encoding and decoding to/from arbitrary character set may be implemented.

Example:

$dbh = DBI->connect( 'dbi:Firebird:db=database.fdb;ib_charset=UTF8',
    { ib_enable_utf8 => 1 } );

关于perl - DBD::Firebird 编码/解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72618139/

相关文章:

perl - 如何使用 Perl 的三元条件运算符构造单词的复数形式?

perl - Mojo::UserAgent 证书验证失败

执行 SELECT 时的 MySQL 特殊字符显示其他没有特殊字符的结果

sql - 使用 firebird 数据库在 SQL 中包含空格的别名

delphi - Chau Chee Yang 的 dbExpress 和 XE2 Enterprise dbExpress for Firebird 的兼容性如何?

regex - perl:在全局范围内匹配,保存和替换正则表达式的最佳方法

multithreading - 在 Perl 线程中调用 system() 时产生僵尸进程

python - python 的 print 函数现在处理 unicode 的方式是否与编写 Dive Into Python 时不同?

php - 奇怪的字符^M php无法识别

sql - 如何使用 group by 和 select distinct