当前位置: 首页 > 知识库问答 >
问题:

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

家志学
2023-03-14

在Linux机器上,我使用PDO DBLIB连接到MSSQL数据库,并将数据插入SQL\u Latin1\u General\u CP1\u CI\u作为表。问题是,当我尝试插入中文字符(多字节)时,它们被插入为哈å¸阿尔法”™åŠåŒºç

我的(部分)代码如下:

$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);

到目前为止我所尝试的:

>

  • $firstname上执行mb\u转换\u编码UTF-16LE,并在查询中转换为VARBINARY,如下所示:

    $firstname=mb_convert_编码($firstname,'UTF-16LE','UTF-8')

    VALUES
    (CAST(:firstname AS VARBINARY));
    

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

    将我的连接设置为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");
    

    在我的freetds中将客户端字符集设置为UTF-8。形态

    没有任何影响。

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

    提前感谢。

    编辑:

    我最终使用了MSSQL和N数据类型前缀。当我有更多的时间时,我将交换并尝试PDO_ODBC。谢谢大家的回答!


  • 共有3个答案

    后星河
    2023-03-14

    您可以对表列使用Unicode兼容的数据类型来支持外语(编辑2中显示了例外情况)。

    (char,varchar,text)与(nchar,nvarchar,ntext)

    非Unicode:

    最适合美式英语:“使用1字节编码每个字符的数据类型的一个问题是数据类型只能代表256个不同的字符。这迫使不同字母(如相对较小的欧洲字母)具有多个编码规范(或代码页)。它也是不可能处理系统,如日语汉字或韩语字母有数千个字符

    统一码

    最适合需要支持至少一种外语的系统:“Unicode规范为世界各地商业中广泛使用的大多数字符定义了一种单一的编码方案。所有计算机一致地使用单个Unicode规范将Unicode数据中的位模式转换为字符。这确保了在所有计算机上始终将相同的位模式转换为相同的字符。数据可以自由地从一个数据库或计算机传输到另一个数据库或计算机,而不用担心接收系统会将位模式错误地转换为字符。

    例子:

    我也尝试了一个例子,你可以在下面查看它的屏幕,这将有助于与外语插入相关的问题,因为现在的问题是。下面在nvarchar中看到的列,它确实支持中文

    编辑1:

    另一个相关的问题在这里讨论

    编辑2:

    此处显示了不支持Unicode的脚本

    田昊天
    2023-03-14

    排序在这里不重要。

    双字节字符需要存储在nvarcharncharntext字段中。你不需要进行任何铸造。

    n数据类型前缀代表国家,它使SQL Server将文本存储为Unicode(UTF-16)。

    编辑:

    PDO_DBLIB不支持Unicode,现在已被弃用。

    如果您可以切换到PDO_ODBC,Microsoft将为Linux提供支持Unicode的免费SQL Server ODBC驱动程序。

    Microsoft-SQL Server ODBC驱动程序文档

    博客-为Linux安装和使用MicrosoftSQLServer ODBC驱动程序

    石臻
    2023-03-14

    有没有办法在[这个特定的]SQL数据库中插入多字节数据?还有其他解决办法吗?

    >

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

    如果您可以将受影响的表从SQL\u Latin1\u General\u CP1\u CI\u AS更改为UTF-8(这是MSSQL的默认值),那么这将是理想的。

    你的案子更受限制。此解决方案适用于以下情况:输入字符串中混合了多字节和非多字节字符,需要将它们保存到拉丁表中,N数据类型前缀不起作用,并且不想改变PDO DBLIB(因为linux上几乎不支持Microsoft的Unicode PDO_ODBC)。这里有一个解决方法。

    有条件地将输入字符串编码为bas64。毕竟,这就是我们如何安全地在电子邮件中传输图片。

    工作示例:

    $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!
    
     类似资料:
    • 问题内容: 我问过功能。但是在使用外来字符时,它不会将它们转换为大写,因此我必须使用: 但是,如果我想使用功能,该怎么办?我没有找到任何类似的函数,可以在其中设置编码类型。 问题答案: 正如您已经注意到的,没有功能。您可以用两个伪造一个:

    • 问题内容: 我是python3的新手,来自python2,并且我对unicode基本概念有些困惑。我读了一些不错的文章,使事情变得更加清楚,但是我看到python 3上有2种方法可以处理编码和解码,而且我不确定要使用哪种方法。 因此,Python 3中的想法是,每个字符串都是unicode,并且可以按字节进行编码和存储,或者可以再次解码回unicode字符串。 但是有两种方法可以做到: 会生成,但

    • 问题内容: Linux / x86_64上的GCC 4.7是否具有默认字符编码,通过它可以验证和解码C源文件中字符串文字的内容?这是可配置的吗? 此外,将字符串文字从字符串文字链接到输出的数据部分时,它是否具有默认的执行字符编码?这是可配置的吗? 在任何配置中,源字符编码都可能与执行字符编码不同吗?(那gcc会在字符编码之间进行代码转换吗?) 问题答案: 我不知道这些选项的实际效果如何(不使用at

    • 问题内容: 我读取了大约1000个文件名,其中一些文件以UTF8编码,而某些文件为CP1252。 我想将它们全部解码为Unicode,以便在脚本中进行进一步处理。有没有一种方法可以使源编码正确解码为Unicode? 例: 问题答案: 如果您的文件位于和中,则有一种简单的方法。 否则,有一个字符集检测库。 Python-检测字符集并转换为utf-8 https://pypi.python.org/p

    • 我有一个带有一些特殊字符的mysql数据库,一个输入表单,一些PHP页面。 > 这个页面发送(通过GET)一个参数到另一个php页面(ResultsPage)。 最后这个php页面(ResultsPage)向dbms发送一个带有参数的查询并显示结果。 RequestPage编码为utf-8至 meta http equiv=“Content Type”Content=“text/html;char

    • 问题内容: 我想从网址获取html内容,并使用正则表达式解析html内容。但是html内容具有一些多字节字符。所以我遇到了标题中描述的错误。 有人可以告诉我如何解决这个问题吗? 问题答案: 您需要编辑问题以显示(1)您使用的代码(2)完整的错误和回溯(3)涉及的网址(4)您尝试将其 编码 为gbk的 unicode 字符是什么 您似乎已经从html内容中的原始字节中获得了unicode字符-怎么样