PostgreSQL,perl和dojo特殊字符问题(æ,ø和å)

时间:2012-04-27 10:50:45

标签: perl postgresql character-encoding dojo special-characters

我使用PostgreSQL数据库在perl和dojo中创建了一个网页。我必须在数据库中搜索可用的人,因为我来自丹麦,必须在搜索中提供æ,ø和å字母。我认为这是使用UTF8时的标准,当我通常使用php编写mysql时,我认为它不会那么难。

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

我有我的perl代码进行提取,但是这个提取返回0行,当我在psql终端中插入相同的命令时,我得到46行返回(从“tail -f log terminal”复制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编码转换为“J%C3%B8rgen”,通过dojo.xhr.post发送),我是否应该无法使用它在SQL语句中?是因为psql数据库可以有某种编码我必须以某种方式考虑到这一点吗?或者它可能有些完全不同?

希望有人可以帮助我。我已经在这个问题上苦苦挣扎了两天了,既然事情看起来应该如此,但是不行,我有点难过:/

此致 Thor Astrup Pedersen

1 个答案:

答案 0 :(得分: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函数。