linux环境php调用sqlServer2000存储过程遇到的问题

三世轮回 提交于 2019-11-27 16:18:33

  在linux环境中用php查询sql server并不是很常见的需求.一般来说如果一定要用sql server,编程语言我会先c#;如果一定要用php,数据库我就选mysql.
  这几天的开发中,需要从一个非开源的erp系统中获取数据,它使用的数据库是sql server 2000,并使用了很多存储过程.我们要基于这个系统做一些报表类的功能,并把这些功能集成到一个原有的PHP开发的crm系统中.需求来了~
  在linux环境中用php查询sql server可以用php自带的mssql扩展或pdo_dblib扩展,这两个扩展都需要freetds类库的支持.
  在程序调试过程中我绕了很多弯,把里面几个重点记录一下.

1.tds版本设置

  
参考自:http://cubist.cs.washington.edu/doc/FreeTDS/userguide/x574.htm

我用的是sql server 2000,tds版本应该设置成8.0,修改freetds.conf

[global]
        # TDS protocol version
        # 前面不要带分号
        tds version = 8.0

调试中发现,如果使用pdo_dblib扩展,这个版本设置没有什么影响,设置成几都能运行;如果使用mssql扩展,这个版本一定要设置成8.0,否则会报错.

2.向表中插入NULL

  
在存储过程中用到临时表.

CREATE TABLE [dbo].[#temp2](
	[id] [int] IDENTITY(1,1) NOT NULL,
	title NVARCHAR(50),
	P_money1 MONEY
)

用asp或查询分析器调用存储过程向这个表中插入数据时都可以顺利执行.但用php调用存储过程时,报了一个错:

Warning: mssql_execute() [function.mssql-execute]: message: Cannot insert the value NULL into column 'P_money1', table 'tempdb.dbo.#contract_temp2_____________________________________________________________________________________________________00020000006A'; column does not allow nulls.

字段P_money1中不能插入NULL.把表结构修改成

CREATE TABLE [dbo].[#temp2](
	[id] [int] IDENTITY(1,1) NOT NULL,
	title NVARCHAR(50) NULL,
	P_money1 MONEY NULL 
)

后可以顺利插入数据.
用php和freetds调用sql server 2000时,只有把表字段设置成允许为NULL,才能插入NULL,否则不能插入NULL.

3.存储过程返回多数据集时的处理

  
当一个存储过程返回多个数据集时,如:

create    proc [dbo].[test]
(	@tb1 varchar(20),
	@tb2 varchar(20)
) 
 as
begin
select * from arealist
select top 2 * from arealist
end

使用mssql扩展的处理方法如下,此方法可顺利执行:

$sql = "test";
#初始化存储过程
$procedure = mssql_init($sql,$conn);
$var = array("11",'22');
#给存储过程绑定参数
mssql_bind($procedure, "@tb1", $var[0], SQLVARCHAR,false,false);
mssql_bind($procedure, "@tb2", $var[1], SQLVARCHAR,false,false);
#执行存储过程
$q = mssql_execute($procedure);
#取得第一个数据集
while($t = mssql_fetch_assoc($q))
    var_dump($t);
#取得第二个数据集
mssql_next_result($q);
echo "<br />--------------------------<br />";  
while($t = mssql_fetch_assoc($q))
    var_dump($t);
mssql_close($conn);

使用pdo_dblib扩展的处理方法:

$pdo = new pdo('dblib:host=192.168.3.82;dbname=test', 'sa', '123456');
$sql = "test ?,?";
#初始化存储过程
$st = $pdo->prepare($sql);
#给存储过程绑定参数
$var = array("11",'22');
$st->bindparam(1,$var[0],PDO::PARAM_STR);
$st->bindparam(2,$var[1],PDO::PARAM_STR);
#执行存储过程
$st->execute();
#取得第一个数据集
var_dump($st->fetchall());
echo "<br />--------------------------<br />";  
#取得第二个数据集
$st->nextrowset();
var_dump($st->fetchall());

此方法执行时报了一个错

Warning: PDOStatement::nextRowset() [pdostatement.nextrowset]: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in /var/www/test3.php on line 17

报错说:驱动不支持多数据集.服务器上的freetds版本是一样的,所以是pdo_dblib不能支持获取多数据集的方法nextrowset.

那它为什么还要提供nextrowset方法呢?可能是因为这个方法是由更底层的pdo抽象类提供的,pdo_dblib虽然不能支持它,但也没做其他的处理.

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!