一、软硬件环境
服务器系统版本:windows server 2012R2
SQL SERVER版本:2017
thinkphp版本:5.1
php版本:7.2.34
二、配置用到的相关驱动
具体可参考这篇文章,写得比较详细。
这里我再根据我的理解解释一下这几个名词
1. Microsoft Drivers for PHP for SQL Server:
这个我们下载得到的是两个dll扩展库,php_pdo_sqlsrv_7_ts_x64.dll和php_sqlsrv_7_ts_x64.dll
对应的php版本,ts/nts, x86/x64根据自己的系统环境来选择。
我们需要通过PHP去操作SQL SERVER数据库所要用到的驱动。这个是必不可少的,可以类比思考一下,我们要通过PHP操作mysql需要安装php_mysqli.dll,操作redis需要安装php_redis.dll,操作mongo需要安装php_mongodb.dll也是一样的道理。
关于为什么会有带pdo和不带pdo两个扩展库,这里就不展开了,可以参考这篇文章来理解
2. ODBC Driver
从安装过程我们就知道,这个是从操作系统层面对SQL SERVER的操作。也就是我们不用管安装的是什么SQL SERVER版本,都是用统一的接口程序来操作。
三、实践中碰到的问题
实测中一直报错
[ error ] [10501]SQLSTATE[22018]: Invalid character value for cast specification: 206 [Microsoft][ODBC SQL Server Driver][SQL Server]操作数类型冲突: text 与 int 不兼容 (SQLExecute[206] at ext\pdo_odbc\odbc_stmt.c:260)[E:\project\zzz\thinkphp\library\think\db\Connection.php:687]
我是对一张空表进行的操作,实际查询也就是用到一条简单的查询语句。
按照thinkphp里的写法是这样的
Db::name('tbl_user')->where('status',1)->select();
status是定义为int类型的,但是从报错看为什么一直认为这个参与查询的值1为文本类型呢?
四、解决办法
最后我重新查看了config的database配置文件,发现是这么写的
把dsn里面的配置去掉,查询正常!
五、原因分析
我分析原因是因为写了dsn,优先使用了dsn提供的方式去查询造成的错误。去掉dsn就是用sqlsrv驱动提供的方式去查询。
但是还是没能解释为什么dsn的方式就会出现以文本方式查询的类型兼容错误?是odbc driver的原因还是thinkphp的原因?这个有待进一步研究。