0

我有一个使用 PostgreSQL 数据库用 perl 和 dojo 制作的网页。我必须在数据库中搜索可用的人,因为我来自丹麦,所以字母æ、ø 和 å必须在搜索中可用。我认为这是使用 UTF8 时的标准,当我通常在 php 上通过 mysql 编程时,我认为这不会那么难。

我已经正确地完成了我所知道的每一个技巧,将这个 search_word 转换为正确的编码,这样我就可以在 postgre sql 数据库中搜索带有æ、ø 和 å 的正确名称......但它仍然失败。

我有我的 perl 代码进行提取,但是这个提取返回 0 行,当我在 psql 终端中插入相同的命令时,我得到 46 行返回(从“tail -f log 终端”复制 STDERR 语句并将其插入到另一个连接的终端中通过 psql 命令到数据库)... perl 代码是:

sub dbSearchPersons {
  my $search_word = escapeSql($_[0]);
  $search_word = Encode::decode_utf8($search_word);

  $statement = "SELECT id,name,initials,email FROM person WHERE name ilike '\%".$search_word."\%' OR email ilike '\%".$search_word."\%' OR initials ilike '\%".$search_word."\%' ORDER BY name ASC";
  $sth = $dbh->prepare($statement);
  $num_rows = $sth->execute();

  print STDERR "Statement: " . $statement;
  if($num_rows > 0){
    $persons = $dbh->selectall_hashref($statement,'id');
  }

  dbFinish($sth);
  webdie($DBI::errstr) if($DBI::errstr);
}

如您所见,我将 SQL 语句写入 STDERR 并输出以下内容:

[Fri Apr 27 11:24:26 2012] [error] [client 10.254.0.1] Statement: SELECT id,name,initials,email FROM person WHERE name ilike '%Jørgen%' OR email ilike '%Jørgen%' OR initials ilike '%Jørgen%' ORDER BY name ASC, referer: https://xx.xxx.xxx.xx/cgi-bin/users.cgi

我正确编写的 sql(我可以通过上面的终端输出看到它),如果我从终端复制并粘贴语句并将其直接插入 psql 终端,我会得到 46 行,因为我应该返回......但是perl 仍然不会返回任何行。

我不明白?当格式化字符串以显示“ø”而不是“ø”(因为 perl 将 UTF8 编码转换为,从通过 dojo.xhr.post 发送的“J%C3%B8rgen”),我应该不能使用它在 SQL 语句中?是不是因为 psql 数据库可以有某种编码,我必须以某种方式考虑到这一点?还是可能完全不同?

希望可以有人帮帮我。我已经为这个问题苦苦挣扎了两天了,因为事情看起来应该如此,但不工作我有点难过:/

问候, 托尔·阿斯特鲁普·佩德森

4

1 回答 1

3

你可能忘记了pg_enable_utf8。然后数据库接口将向您返回 Perl 字符数据。

$ createdb -e -E UTF-8 -l en_US.UTF-8 -T template0 so10349280
CREATE DATABASE so10349280 ENCODING 'UTF-8' TEMPLATE template0 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';

$ echo 'create table person (id int, name varchar, initials varchar, email varchar)'|psql so10349280
CREATE TABLE

$ echo "insert into person (id, name) values (1, 'Jørgensen')"|psql so10349280
INSERT 0 1

$ echo 'select * from person'|psql so10349280
 id |   name    | initials | email
----+-----------+----------+-------
  1 | Jørgensen |          |

$ perl -Mutf8 -Mstrictures -MDBI -MDevel::Peek -E'
    my $dbh = DBI->connect(
        "DBI:Pg:dbname=so10349280", $ENV{LOGNAME}, "", { RaiseError => 1, AutoCommit => 1, pg_enable_utf8 => 1}
    );
    my $r = $dbh->selectall_hashref("select * from person where name = ?", "id", undef, "Jørgensen");
    Dump $r->{1}{name};
'
SV = PV(0x836e20) at 0xa58dc8
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0xa5a000 "J\303\270rgensen"\0 [UTF8 "J\x{f8}rgensen"]
  CUR = 10
  LEN = 16

您说的不是很清楚,我认为您最终打算将字符数据作为 JSON 发送以用于 Dojo。您需要将它们编码为 UTF-8 八位字节;各种 JSON 库会自动为您处理,无需Encode手动调用函数。

于 2012-04-27T13:56:10.000 回答