Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过Windows CompareStringA进行PostgreSQL排序_Sql_Postgresql_Delphi_Sorting_Collation - Fatal编程技术网

通过Windows CompareStringA进行PostgreSQL排序

通过Windows CompareStringA进行PostgreSQL排序,sql,postgresql,delphi,sorting,collation,Sql,Postgresql,Delphi,Sorting,Collation,我有一个Delphi 6程序(单字节字符),它通过默认的不区分大小写的AnsiCompareText函数对TStringList中的字符串进行排序,该函数反过来调用Windows kernel32.dll中的CompareStringA函数。(区域设置为匈牙利语。) 我想在PostgreSQL数据库中,在Kubuntu(linux-image-3.2.0-65-generic-pae,32位x86,KDE 4.8.5)系统上进行同样的排序。它是由 CREATE DATABASE <..

我有一个Delphi 6程序(单字节字符),它通过默认的不区分大小写的AnsiCompareText函数对TStringList中的字符串进行排序,该函数反过来调用Windows kernel32.dll中的CompareStringA函数。(区域设置为匈牙利语。)

我想在PostgreSQL数据库中,在Kubuntu(linux-image-3.2.0-65-generic-pae,32位x86,KDE 4.8.5)系统上进行同样的排序。它是由

  CREATE DATABASE <...>
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'hu_HU.UTF-8'
       LC_CTYPE = 'hu_HU.UTF-8'
       CONNECTION LIMIT = -1;
创建数据库
拥有者=博士后
编码='UTF8'
表空间=pg_默认值
LC_-COLLATE='hu_-hu.UTF-8'
LC_CTYPE='hu_hu.UTF-8'
连接极限=-1;
如果我按C或POSIX排序,重音字符不会按字母顺序排序。 如果按默认排序规则排序,则忽略空格和一些特殊字符。当这些发生在字符串的开头时,这是一个问题。 (指定排序规则很容易,因为PostgreSQL 9.1:请参阅。)

在本主题中提出了几个问题,例如:。 答案无法概括:它只排除了第一个字符位置的“@”

我的问题也许是重复的 这里的答案指向PostgreSQL的待办事项列表: 从那以后有什么变化吗

我想要的是一个排序规则,它将空格和特殊字符保持在ASCII位置,并按字母顺序对重音字符进行排序,就像在Windows中一样


我是否必须编写自定义区域设置(如何编写)?或者是一个定制的比较函数,可能是用Delphi编写的(如何添加到PostgreSQL)?或者将特殊字符翻译成十六进制,例如,但它们将被排序到文本中。将所有字符转换为十六进制(并将大小写和重音差异映射到同一代码)似乎很糟糕——这意味着我自己编写完整的排序规则。我相信应该有解决方案。

除非您可以更改数据库的编码/排序规则以匹配Windows系统,否则我认为添加一些自定义比较代码可能是您唯一的选择


如果ICU的排序顺序(如链接中所述)是您所追求的,那么请查看(Postgres ICU包装)。安装了此功能后,只需将
orderbyfoo
替换为
orderbycollkey(foo,'hu\u-hu')
(同样地,对于任何显式的
/
,我在这里给出了我的解决方案,尽管它不是问题的答案,因为它不使用任何排序,结果与Delphi的排序不同,它是一个PHP代码,而不是PostgreSQL。然而,这个想法可能有助于其他人将它移植到PostgreSQL或任何其他语言

include 'portable-utf8.php';

$cCharTab = array(
     124 => '00',   // | (field separator)
      32 => '01',   // space
      43 => '11',   // +
      45 => '12',   // -
      47 => '14',   // /
      92 => '15',   // \
      61 => '17',   // =
    9658 => '19',   // ►
      34 => '22',   // "
      39 => '27',   // '
      40 => '28',   // (
      41 => '29',   // )
      42 => '2A',   // *
      46 => '2E',   // .

      48 => '30',   // 0
      49 => '31',   // 1
      50 => '32',   // 2
      51 => '33',   // 3
      52 => '34',   // 4
      53 => '35',   // 5
      54 => '36',   // 6
      55 => '37',   // 7
      56 => '38',   // 8
      57 => '39',   // 9

     164 => '64',   // ¤
      44 => '71',   // ,
      59 => '72',   // ;
     247 => '73',   // ÷
      58 => '73',   // :
      33 => '74',   // !
      36 => '75',   // $
      63 => '75',   // ?
      95 => '95',   // _

      65 => 'a0',   // A
      66 => 'b0',   // B
      67 => 'c0',   // C
      68 => 'd0',   // D
      69 => 'e0',   // E
      70 => 'f0',   // F
      71 => 'g0',   // G
      72 => 'h0',   // H
      73 => 'i0',   // I
      74 => 'j0',   // J
      75 => 'k0',   // K
      76 => 'l0',   // L
      77 => 'm0',   // M
      78 => 'n0',   // N
      79 => 'o0',   // O
      80 => 'p0',   // P
      81 => 'q0',   // Q
      82 => 'r0',   // R
      83 => 's0',   // S
      84 => 't0',   // T
      85 => 'u0',   // U
      86 => 'v0',   // V
      87 => 'w0',   // W
      88 => 'x0',   // X
      89 => 'y0',   // Y
      90 => 'z0',   // Z

      97 => 'a0',   // a
      98 => 'b0',   // b
      99 => 'c0',   // c
     100 => 'd0',   // d
     101 => 'e0',   // e
     102 => 'f0',   // f
     103 => 'g0',   // g
     104 => 'h0',   // h
     105 => 'i0',   // i
     106 => 'j0',   // j
     107 => 'k0',   // k
     108 => 'l0',   // l
     109 => 'm0',   // m
     110 => 'n0',   // n
     111 => 'o0',   // o
     112 => 'p0',   // p
     113 => 'q0',   // q
     114 => 'r0',   // r
     115 => 's0',   // s
     116 => 't0',   // t
     117 => 'u0',   // u
     118 => 'v0',   // v
     119 => 'w0',   // w
     120 => 'x0',   // x
     121 => 'y0',   // y
     122 => 'z0',   // z

     193 => 'a0',   // Á
     196 => 'a0',   // Ä
     201 => 'e0',   // É
     205 => 'i0',   // Í
     211 => 'o0',   // Ó
     214 => 'o1',   // Ö
     218 => 'u0',   // Ú
     220 => 'u1',   // Ü
     225 => 'a0',   // á
     228 => 'a0',   // ä
     231 => 'c0',   // ç
     233 => 'e0',   // é
     235 => 'e0',   // ë
     237 => 'i0',   // í
     243 => 'o0',   // ó
     246 => 'o1',   // ö
     250 => 'u0',   // ú
     252 => 'u1',   // ü
     253 => 'y0',   // ý
     263 => 'c0',   // ć
     268 => 'c0',   // Č
     269 => 'c0',   // č
     281 => 'e0',   // ę
     322 => 'l0',   // ł
     324 => 'n0',   // ń
     336 => 'o1',   // Ő
     337 => 'o1',   // ő
     345 => 'r0',   // ř
     353 => 's0',   // š
     367 => 'u0',   // ů
     368 => 'u1',   // Ű
     369 => 'u1',   // ű
     380 => 'z0'    // ż
);

// Sorter:
function Sorter( $a_str )
/*
    Convert $a_str to a sortable string.
*/
{
    $ct = $GLOBALS['cCharTab'];
    $result = '';
    $arr = preg_split('//u', $a_str, -1, PREG_SPLIT_NO_EMPTY);

    foreach ($arr as $c)
        $result .= $ct[utf8_ord($c)];

    return $result;
}
Sorter函数将要排序的值的每个字符替换为两个字符的字母数字字符串,该字符串不受任何区域设置的影响。我在表中有一个单独的列(f_Sorter),由编写表的PHP脚本中的INSERT语句填充。(我没有更新,我只需要应用程序中的一个ORDER BY。)

是这样的:

pg_query_params( $my_pg_connection, $sql, $params );
在哪里

(插入和更新触发器以及服务器端功能将更加优雅。)

所以

给出了所需的结果

SELECT ...
ORDER BY f1, f2, f3
用我的“整理”

我使用“|”字符作为字段分隔符。它将在任何其他字符之前排序。结果是,较短的字符串将在具有相同前缀的较长字符串之前。(这与Delphi结果相反,但我喜欢它。)

$cCharTab数组包含大约120个字符,这些字符对我很重要。例如,请随意调整列表,更改顺序或将字段分隔符更改为TAB


portable-utf8是一个非常有用的库,用于在PHP5中处理UTF-8字符串。从

下载您的问题到底是什么?仅大小写不重要的排序?不,大小写不重要的排序将很容易使用lower排序(mycl)。问题是PostgreSQL忽略了(几乎?)排序时字符串中的所有标点符号。它在某些情况下可能有用,但无法禁用。其他几个类似问题:,表明它也会激怒许多开发人员。Nick Barnes的解决方案可能是正确的,但我没有花力气开发它。
$params = array( $f1, $f2, $f3, Sorter( $f1 . '|' . $f2. '|' . $f3) );
SELECT ...
ORDER BY f_sorter
SELECT ...
ORDER BY f1, f2, f3