关于php中使用odbc或者pdo连接sqlserver时如果查询条件中存在中文会导致查询失败的问题
2014-08-07 12:30
1256 查看
这两天,可以说三天,一直在调试一段程序,或者一个功能,就是查询sqlserver2005/2008数据库,这段程序很简单,就是查询条件中包含了中文:
我使用的是thinkphp框架,代码如下:
返回的结果,$result为null
如果我将查询条件换成int类型时,则结果正常,例如:
这时是可以正确查询出结果的。
所以PHP对数据库的连接应该是没有问题的,那么问题可能是出在了中文的编码上,于是我打算把查询的中文进行编码,因为sqlserver默认编码好像是gb2312,所以我这样:
但是结果仍然是null,我甚至尝试将iconv换过来,变成iconv('gb2312',utf-8',$m_id),或者换成gbk:iconv('gbk',utf-8',$m_id),或者最后都用了mb_convert_encoding($m_id, 'utf8', 'utf8, gbk, gb2312')和mb_convert_encoding($m_id, 'gbk', 'utf8, gbk, gb2312');
都不行,然后我最后甚至怀疑整个sql可能都要进行转码,于是我这样了:
可以看出来为了正确的结果我已经没有原则了,但是,得出的结果还是:null
到底是哪里出了问题呢????
在同事的提醒下,我想到了可能是odbc或者pdo驱动在源头上就有问题,于是我开始查看我的freetds驱动配置:freetds.conf
于是我去查询,结果如下:
Last login: Thu Aug 7 11:11:17 on ttys001
AndyMacBookPro:~ andy$ sudo find / -name freetds.conf
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
/Users/andy/Downloads/freetds-0.91/freetds.conf
/usr/local/Cellar/freetds/0.91/etc/freetds.conf
/usr/local/etc/freetds.conf
/usr/local/freetds/etc/freetds.conf
AndyMacBookPro:~ andy$
于是我修改了这个下面这个文件:
AndyMacBookPro:~ andy$ sudo vim /usr/local/freetds/etc/freetds.conf
我在配置文件中添加了红字的一行:
# $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
client charset = UTF-8
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Microsoft server
[dev]
host = 192.168.100.79
port = 1433
tds version = 7.0
[TEST1dsn]
host = aa.bb.zz
port = 1433
tds version = 7.0
然后保存退出刷新页面,得到的仍然是:null
然后我就认为错误不是出在这里,然后又去找其他原因,还是无果,直到第二天,我想起了我查询时包含了两个位置的freetds.conf配置:
AndyMacBookPro:~ andy$ ll /usr/local/etc/freetds.conf
lrwxr-xr-x 1 andy admin 39 7 1 13:08 /usr/local/etc/freetds.conf@ -> ../Cellar/freetds/0.91/etc/freetds.conf
AndyMacBookPro:~ andy$
其中这两个配置的是同一个,只不过是一个软链接,然后我本地电脑上安装的freetds是用brew安装的,所以正常的freetds应该是上图这个,而不是下图这个:
AndyMacBookPro:~ andy$ ll /usr/local/freetds/etc/freetds.conf
-rw-r--r--@ 1 root admin 1071 8 6 17:06 /usr/local/freetds/etc/freetds.conf
AndyMacBookPro:~ andy$
这个只是我本地自己安装的一个freetds而已,没有起到任何作用,我之前修改的就是它。。。。。。
于是我去修改:
AndyMacBookPro:~ andy$ sudo vim /usr/local/etc/freetds.conf
内容如下(添加了红字部分):
# $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
client charset = UTF-8
# A typical Microsoft server
[TEST1dsn]
host = aa.bb.zz
port = 1433
tds version = 8.0
[TEST2dsn]
host = 192.168.10.81
port = 1433
tds version = 7.0
[prddsn]
host = aa.bb.zz
port = 1433
tds version = 7.0
保存退出,重新刷新页面,天呢,结果出来了~~~
SELECT T1.* FROM (SELECT ROW_NUMBER() OVER ( ORDER BY id desc) AS ROW_NUMBER, thinkphp.* FROM (SELECT id,shopid,shopname FROM shopname WHERE ( shopname = '大商家' )) AS thinkphp) AS T1 WHERE (T1.ROW_NUMBER BETWEEN
1 AND 1)
3天啊~~~
就是因为中文字符编码的问题~~~
加上两个文件这么有迷惑性,自己也没看清和确认~~~
这种错误,以后要切记。
我使用的是thinkphp框架,代码如下:
$m_id = '大商家'; $result = D('SqlServer')->table('shopname')->where(array('shopname'=>$m_id))->field('id,shopid,shopname')->order('id desc')->find();
返回的结果,$result为null
如果我将查询条件换成int类型时,则结果正常,例如:
$shopid='1100'; $result = D('SqlServer')->table('shopname')->where(array('shopid'=>$shopid))->field('id,shopid,shopname')->order('id desc')->find();
这时是可以正确查询出结果的。
所以PHP对数据库的连接应该是没有问题的,那么问题可能是出在了中文的编码上,于是我打算把查询的中文进行编码,因为sqlserver默认编码好像是gb2312,所以我这样:
$m_id = '大商家'; $m_id = iconv('utf-8','gb2312',$m_id); $result = D('SqlServer')->table('shopname')->where(array('shopname'=>$m_id))->field('id,shopid,shopname')->order('id desc')->find();
但是结果仍然是null,我甚至尝试将iconv换过来,变成iconv('gb2312',utf-8',$m_id),或者换成gbk:iconv('gbk',utf-8',$m_id),或者最后都用了mb_convert_encoding($m_id, 'utf8', 'utf8, gbk, gb2312')和mb_convert_encoding($m_id, 'gbk', 'utf8, gbk, gb2312');
都不行,然后我最后甚至怀疑整个sql可能都要进行转码,于是我这样了:
$sql = "select * from shopname where shopname='大商家'"; $sql = mb_convert_encoding($sql, 'utf8', 'utf8, gbk, gb2312'); $result = D('SqlServer')->query($sql);
可以看出来为了正确的结果我已经没有原则了,但是,得出的结果还是:null
到底是哪里出了问题呢????
在同事的提醒下,我想到了可能是odbc或者pdo驱动在源头上就有问题,于是我开始查看我的freetds驱动配置:freetds.conf
于是我去查询,结果如下:
Last login: Thu Aug 7 11:11:17 on ttys001
AndyMacBookPro:~ andy$ sudo find / -name freetds.conf
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
/Users/andy/Downloads/freetds-0.91/freetds.conf
/usr/local/Cellar/freetds/0.91/etc/freetds.conf
/usr/local/etc/freetds.conf
/usr/local/freetds/etc/freetds.conf
AndyMacBookPro:~ andy$
于是我修改了这个下面这个文件:
AndyMacBookPro:~ andy$ sudo vim /usr/local/freetds/etc/freetds.conf
我在配置文件中添加了红字的一行:
# $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
client charset = UTF-8
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Microsoft server
[dev]
host = 192.168.100.79
port = 1433
tds version = 7.0
[TEST1dsn]
host = aa.bb.zz
port = 1433
tds version = 7.0
然后保存退出刷新页面,得到的仍然是:null
然后我就认为错误不是出在这里,然后又去找其他原因,还是无果,直到第二天,我想起了我查询时包含了两个位置的freetds.conf配置:
AndyMacBookPro:~ andy$ ll /usr/local/etc/freetds.conf
lrwxr-xr-x 1 andy admin 39 7 1 13:08 /usr/local/etc/freetds.conf@ -> ../Cellar/freetds/0.91/etc/freetds.conf
AndyMacBookPro:~ andy$
其中这两个配置的是同一个,只不过是一个软链接,然后我本地电脑上安装的freetds是用brew安装的,所以正常的freetds应该是上图这个,而不是下图这个:
AndyMacBookPro:~ andy$ ll /usr/local/freetds/etc/freetds.conf
-rw-r--r--@ 1 root admin 1071 8 6 17:06 /usr/local/freetds/etc/freetds.conf
AndyMacBookPro:~ andy$
这个只是我本地自己安装的一个freetds而已,没有起到任何作用,我之前修改的就是它。。。。。。
于是我去修改:
AndyMacBookPro:~ andy$ sudo vim /usr/local/etc/freetds.conf
内容如下(添加了红字部分):
# $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
client charset = UTF-8
# A typical Microsoft server
[TEST1dsn]
host = aa.bb.zz
port = 1433
tds version = 8.0
[TEST2dsn]
host = 192.168.10.81
port = 1433
tds version = 7.0
[prddsn]
host = aa.bb.zz
port = 1433
tds version = 7.0
保存退出,重新刷新页面,天呢,结果出来了~~~
SELECT T1.* FROM (SELECT ROW_NUMBER() OVER ( ORDER BY id desc) AS ROW_NUMBER, thinkphp.* FROM (SELECT id,shopid,shopname FROM shopname WHERE ( shopname = '大商家' )) AS thinkphp) AS T1 WHERE (T1.ROW_NUMBER BETWEEN
1 AND 1)
array (size=4) 'ROW_NUMBER' => '1' (length=1) 'id' => '2049' (length=4) 'shopid' => '1100' (length=4) 'shopname' => '大商家' (length=9)
3天啊~~~
就是因为中文字符编码的问题~~~
加上两个文件这么有迷惑性,自己也没看清和确认~~~
这种错误,以后要切记。
相关文章推荐
- 使用win8.1 x64 office2010 php 使用 pdo_odbc 连接excel失败的问题
- 关于php pdo连接mysql,查询超时问题
- 关于“打开项目**时发生问题,尝试退出并重新启动应用程序。如果问题仍然存在,则可能是由于正在使用不支持的项目版本,或者项目文件可能损坏”的问题的解决办法。
- php使用ODBC连接sqlserver问题
- 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为
- 关于php连接mssql:pdo odbc sql server
- 关于php中使用IP和localhost连接问题
- sqlserver -- 学习笔记(三)解决php连接sqlserver2005视图时显示“异类查询要求为连接设置 ANSI_NULLS 和 ANSI_WARNINGS 选项”的问题
- INFORMIX数据库PHP ODBC连接无法插入中文、查询中文的解决方案!!搞了三天啊!!
- 使用DBUtils连接Sqlserver插入失败的问题
- 关于php连接sqlserver的问题
- 使用mybatis遇到的关于条件查询">"以及if test传参的使用问题
- 关于:“无法序列化会话状态。在“StateServer”或“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许使用无法序列化的对象或 MarshalByRef 对象。如果自定义会话状态存储在“Custom”模式下执行了类似的序列化,则适用同样的限制。”的问题
- 《关于在MFC中使用ODBC方式连接数据库可能出现的问题》第一篇
- php使用pdo连接sqlserver示例分享
- fstream的使用和打开时存在中文中文路径可能失败的问题,其他中文问题都可以尝试采用如下方法
- 在微软报表服务中,使用odbc连接Sybase数据库,无法使用参数查询的问题我找到办法了
- 关于C++用ODBC连接数据库中文显示乱码的问题
- ThinkPHP3.0使用pdo方式连接sqlserver 2000、mssql 2000的配置,直接上配置文件,php版本是php5.2,服务器环境是ComsenzEXP
- MFC中ODBC连接MySQL数据库查询出的中文显示为乱码的问题