PHP sqlsrv驱动程序和PDO驱动程序之间的数据类型差异

问题描述 投票:2回答:1

这里我正在使用sqlsrv

$conn = sqlsrv_connect("192.168.1.102,1433", array("Database"=>"RF_User", "UID"=>"rfo-gcp", "PWD" => ""));

$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = ?";

$stmt = sqlsrv_query($conn, $tsql, array("test"));

$result = sqlsrv_fetch_array($stmt);

var_dump($result);

结果:array(2) { [0]=> object(DateTime)#1 (3) { ["date"]=> string(26) "2020-04-19 20:40:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } ["birthdate"]=> object(DateTime)#1 (3) { ["date"]=> string(26) "2020-04-19 20:40:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } }

这里我正在使用PDO

$conn = new PDO("sqlsrv:Server=192.168.1.102,1433; Database=RF_User;", "rfo-gcp", "");

$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = cast(? as varchar(13))";     

$stmt = $conn->prepare($tsql);

$stmt->execute(array("test"));

$result = $stmt->fetch(PDO::FETCH_ASSOC);

var_dump($result);

结果:array(1) { ["birthdate"]=> string(19) "2020-04-19 20:40:00" }

[如果您注意到,我必须在cast(? as varchar(13))代码上使用PDO。没有它就不会返回任何行。在sqlsrv上,我不必使用CAST()功能。为什么是这样?另外,数据库上的id列是BINARY(13),所以为什么我必须将id强制转换为varchar而不是binary(使用二进制强制转换也不会找到行)?

php sql-server pdo binary sqlsrv
1个回答
3
投票
为什么日期和时间值返回的方式不同?

实际上,这只是一个设置。

当您使用

PDO_SQLSRV

(如文档中的mentioned)时,

日期和时间类型(smalldatetime,datetime,date,date,time,datetime2和datetimeoffset)默认情况下以字符串形式返回。 PDO :: ATTR_STRINGIFY_FETCHES或PDO :: SQLSRV_ATTR_FETCHES_NUMERIC_TYPE属性均无效。为了检索日期和时间类型作为PHP DateTime对象,请将连接或语句属性PDO :: SQLSRV_ATTR_FETCHES_DATETIME_TYPE设置为true(默认情况下为false)。

当您使用SQLSRV驱动程序(再次从documentation开始)时,

smalldatetime,datetime,date,time,datetime2和datetimeoffset类型将作为PHP DateTime对象返回]]。可以通过在连接字符串或语句级别设置'ReturnDatesAsStrings'选项来更改此行为。$conn = sqlsrv_connect( "192.168.1.102,1433", array( "ReturnDatesAsStrings"=>true, "Database"=>"RF_User", "UID"=>"rfo-gcp", "PWD" => "" ) );

请注意,某些功能取决于用于SQL Server的PHP驱动程序的版本。

如何转换参数值?

在语句中使用CAST()CONVERT()函数,并将参数值与字符串值绑定应该起作用。当然,绑定参数时可以指定参数数据类型。

对于

PDO_SQLSRV

,您应该扩展PDOStatement::bindParam()的语法。

对于SQLSRV

,当您调用$params时,可以使用扩展的syntax sqlsrv_query()\sqlsrv_execute()指定SQL Server数据类型。

我能够重现此问题(PHP 7.1.12,SQL Server 4.3.0 + 9904的PHP驱动程序,SQL Server 2012,并且使用以下解决方案:

$params = array($id, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_BINARY); // SQLSRV $stmt->bindParam(1, $id, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); // PDO_SQLSRV

表格:

CREATE TABLE tbl_rfaccount (id binary(13), birthdate datetime)
INSERT INTO tbl_rfaccount (id, birthdate) VALUES (CONVERT(binary(13), 'Test'), GETDATE())

PHP:

<?php
...

// 
$id = "Test";

// SQLSRV
$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = ?";
$params = array($id, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_BINARY);
$stmt = sqlsrv_query($conn, $tsql, $params);
if ($stmt === false) {
    echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
    exit;
}
$result = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
var_dump($result);

// PDO_SQLSRV
$tsql = "SELECT birthdate FROM tbl_rfaccount WHERE id = ?";     
$stmt = $conn->prepare($tsql);
$stmt->bindParam(1, $id, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($result);

...
?> 
© www.soinside.com 2019 - 2024. All rights reserved.