gpt4 book ai didi

sql-server - PDO DBLIB 多字节(中文)字符编码 - SQL Server

转载 作者:行者123 更新时间:2023-12-02 06:43:55 25 4
gpt4 key购买 nike

在 Linux 计算机上,我使用 PDO DBLIB 连接到 MSSQL 数据库并将数据插入 SQL_Latin1_General_CP1_CI_AS 表中。问题是,当我尝试插入中文字符(多字节)时,它们被插入为 哈市é⁠™åŠåŒºç æ±Ÿè·́å·

我的(部分)代码如下:

$DBH = new PDO("dblib:host=$myServer;dbname=$myDB;", $myUser, $myPass);

$query = "
INSERT INTO UserSignUpInfo
(FirstName)
VALUES
(:firstname)";

$STH = $DBH->prepare($query);

$STH->bindParam(':firstname', $firstname);

到目前为止我已经尝试过:

  1. $firstname 上将 mb_convert_encoding 转换为 UTF-16LE,并在查询中将 CAST 转换为 VARBINARY,如下所示:

    $firstname = mb_convert_encoding($firstname, 'UTF-16LE', 'UTF-8');

    VALUES
    (CAST(:firstname AS VARBINARY));

    这会导致正确插入字符,直到出现一些非多字节字符,从而中断 PDO 执行。

  2. 将我的连接设置为 utf8:

    $DBH = new PDO("dblib:host=$myServer;dbname=$myDB;charset=UTF-8;", $myUser, $myPass);
    $DBH->exec('SET CHARACTER SET utf8');
    $DBH->query("SET NAMES utf8");
  3. 在我的 freetds.conf 中将客户端字符集设置为 UTF-8

    这没有影响。

有什么方法可以在 SQL 数据库中插入多字节数据吗?还有其他解决方法吗? 我曾想过尝试 PDO ODBC 甚至 mssql,但我认为最好在浪费更多时间之前先在这里询问。

提前致谢。

编辑:

我最终使用了MSSQLN 数据类型前缀。当我有更多时间时,我会换成并尝试PDO_ODBC。谢谢大家的解答!

最佳答案

Is there any way at all, to insert multibyte data in [this particular] SQL database? Is there any other workaround?

  1. 如果您可以切换到 PDO_ODBC,Microsoft 会为 Linux 提供免费的 SQL Server ODBC 驱动程序(仅适用于 64 位 Red Hat Enterprise Linux 和 64 位 SUSE Linux Enterprise),该驱动程序支持 Unicode。

  2. 如果您可以更改为 PDO_ODBC,则用于插入 Unicode 的 N 前缀将起作用。

  3. 如果您可以将受影响的表从 SQL_Latin1_General_CP1_CI_AS 更改为至UTF-8 (这是 MSSQL 的默认设置),那就太理想了。

您的情况受到更多限制。此解决方案适用于输入字符串中混合有多字节和非多字节字符,并且需要将它们保存到拉丁表中的情况,并且 N数据类型前缀不起作用,并且您不想更改 PDO DBLIB(因为 Microsoft 的 Unicode PDO_ODBC 在 Linux 上为 barely supported)。这是一种解决方法。

有条件地将输入字符串编码为 base64。毕竟,这就是我们如何安全地与电子邮件一起传输图片的方法。

工作示例:

$DBH = new PDO("dblib:host=$myServer;dbname=$myDB;", $myUser, $myPass);

$query = "
INSERT INTO [StackOverflow].[dbo].[UserSignUpInfo]
([FirstName])
VALUES
(:firstname)";

$STH = $DBH->prepare($query);

$firstname = "输入中国文字!Okay!";

/* First, check if this string has any Unicode at all */
if (strlen($firstname) != strlen(utf8_decode($firstname))) {
/* If so, change the string to base64. */
$firstname = base64_encode($firstname);
}

$STH->bindParam(':firstname', $firstname);
$STH->execute();

然后,要向后退,您可以测试 Base64 字符串,并解码它们,而不会损坏现有条目,如下所示:

while ($row = $STH->fetch()) {
$entry = $row[0];

if (base64_encode(base64_decode($entry , true)) === $entry) {

/* Decoding and re-encoding a true base64 string results in the original entry */
print_r(base64_decode($entry) . PHP_EOL);

} else {

/* Previous entries not encoded will fall through gracefully */
print_r($entry . PHP_EOL);
}
}

条目将像这样保存:

Guan Tianlang
5pys6Kqe44KS5a2maGVsbG8=

但是您可以轻松地将它们转换回:

Guan Tianlang
输入中国文字!Okay!

关于sql-server - PDO DBLIB 多字节(中文)字符编码 - SQL Server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28740413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com