You need to enable JavaScript to run this app. sqlsrv_query查询含em dash的定长VARCHAR字段时输出中断如何解决
优惠活动
大模型
产品
解决方案
定价
更多

sqlsrv_query查询含em dash的定长VARCHAR字段时输出中断如何解决

根因分析

该问题是SQL Server PHP驱动sqlsrv的字符集配置不匹配导致的:
你使用的VARCHAR是非Unicode单字节字段,存储em dash、en dash这类多字节字符时,编码遵循数据库默认排序规则对应的字符集(通常为GBK、Latin1等)。sqlsrv扩展默认未指定返回字符集时,会尝试按系统默认编码转码,遇到无法识别的多字节字符序列时,sqlsrv_fetch_array会直接返回false终止循环,而非输出阶段截断。这也是你没有拿到sqlsrv_errors报错的原因:转码失败属于警告级别的问题,默认不会被错误捕获接口返回,循环在执行到ID=4的记录时已经提前终止,根本没有进入后续的echo、str_replace逻辑。

解决方案

方案1(推荐):连接时指定UTF-8字符集

在数据库连接配置中明确指定返回字符集为UTF-8,驱动会自动将所有查询结果转码为合法的UTF-8字符串,从根源解决转码失败问题。修改你config.php中的连接代码即可:

$connectionInfo = array(
    "Database" => "你的数据库名",
    "UID" => "账号",
    "PWD" => "密码",
    "CharacterSet" => "UTF-8" // 新增该行配置
);
$conn = sqlsrv_connect($serverName, $connectionInfo);

方案2:手动读取二进制内容转码

如果无法修改全局连接配置,可以在查询时指定返回二进制格式,手动处理编码转换:

// 执行查询时指定返回二进制编码
$stmt = sqlsrv_query($conn, $query, array(), array(
    "CharacterSet" => SQLSRV_ENC_BINARY
));
// 循环内手动转码,源编码替换为你数据库实际使用的编码(如GBK、CP1252等)
while($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
    $desc = mb_convert_encoding($row['Description'], 'UTF-8', 'GBK');
    echo "<tr>";
        echo "<td>".$row['ID']."</td>";
        echo "<td>".$desc."</td>";
    echo "</tr>";
}

方案3:修改字段类型为Unicode格式

如果业务允许修改表结构,可以将Description字段从VARCHAR(5)改为NVARCHAR(5),直接存储Unicode字符,避免编码转换问题。

之前方案无效的原因
  • 调整页面字符集、str_replace替换字符:循环在sqlsrv_fetch_array阶段就已经终止,代码未执行到输出、替换逻辑
  • CAST为VARCHAR(MAX)、LEFT截取字段:没有解决单字节存储与多字节字符的编码不匹配问题,转码失败的问题依然存在

内容的提问来源于stack exchange,提问作者Painguin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 22:54:03