您的位置:首页 > 编程语言 > PHP开发

关于php中使用odbc或者pdo连接sqlserver时如果查询条件中存在中文会导致查询失败的问题

2014-08-07 12:30 1256 查看
这两天,可以说三天,一直在调试一段程序,或者一个功能,就是查询sqlserver2005/2008数据库,这段程序很简单,就是查询条件中包含了中文:

我使用的是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天啊~~~

就是因为中文字符编码的问题~~~

加上两个文件这么有迷惑性,自己也没看清和确认~~~

这种错误,以后要切记。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐