关于在linux下php扩展sqlsrv查询数据不正常,错误01004
前段时间将一个老php项目从windows移至centos7中,安装sqlsrv扩展等都挺顺利,安装过程写在另一篇文章中了。
问题描述:
原先在windows中没哟问题,部署到linux新服务器中出现一个问题,有一个列表页面,发现分页显示数据存在问题,第一页刷新一下原本获取15条数据,但是只出来5条,第二页0条,第三页3条,第三页刷新一下又刷出来8条,类似这种状态,但是执行语句到navicat中执行都是没有问题的。
问题排查:
sql语句,举例:select * from table
首先我在执行语句后面添加了:
var_dump(sqlsrv_errors());
在有一次执行的时候输出发现一个错误:
[Microsoft][ODBC Driver 17 for SQL Server]String data, right truncation 错误码01004
但是这个错误不是每次访问都会出现请注意。
然后我排查了错误代码,详情访问:https://www.cnblogs.com/88999660/articles/1616214.html
错误(警告)提示为:01004 字符串值在指定给具有较短长度的另一字符串数据类型时被截断。
我一开始没有特别理解这个错误提示,认为查询输出来自动帮我截断,也不会出现查询数据丢失啊,然后我测试类一下:select id from table ,我把*改成了id,发现查询都是正常了。没有出现丢失的情况。然后我增加了个字段:select id,content from table 继续执行,问题出现了,时不时分页查询数据丢失,那么问题出现在了content上面。
排查数据表,发现content字段定义为:nvarchar(100),nvarchar表示能存100个字符,不管是什么编码,现在我通过linux的ODBC查询出来的数据应该有一个效验过程,取出来100个字符,如果是utf-8编码的,那么他就认为长度为300了,和数据库定义的100不匹配,然后进行截断,提示警告:01004,导致之后的数据丢失。
问题解决:
然后我将表字段nvarchar长度改成300后一切正常。主要是odbc判断长度和数据库设置长度编码上的问题。导致进行截断了。
还有出现:content数据库类型:nvarchar(max),通过函数转text
select cast(content as text) as content from table
这里的text要改成ntext如:cast(content as ntext),不然也会出现查询错误的问题。