在 PHP 中通过 ODBC(使用 PDO)查询雪花返回不正确的数据

Posted

技术标签:

【中文标题】在 PHP 中通过 ODBC(使用 PDO)查询雪花返回不正确的数据【英文标题】:Querying Snowflake via ODBC (using PDO) in PHP returns incorrect data 【发布时间】:2015-12-06 08:29:51 【问题描述】:

我正在尝试通过他们在 php(CentOS 6 和 7)中的 ODBC 驱动程序连接到 Snowflake,并利用 PDO 来更轻松地访问。

ODBC 驱动程序似乎已安装并正常运行,因为 PHP 中的原生 ODBC 函数运行良好:

$dsn = "Driver=SnowflakeDSIIDriver;Server=" . SNOWFLAKE_HOST;
$dsn .= ";Account=" . SNOWFLAKE_ACCOUNT;
$dsn .= ";Port=" . SNOWFLAKE_PORT;
$dsn .= ";Schema=" . SNOWFLAKE_SCHEMA;
$dsn .= ";Warehouse=" . SNOWFLAKE_WAREHOUSE;
$dsn .= ";Database=" . SNOWFLAKE_DATABASAE;

$conn_id = odbc_connect($dsn, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD);
odbc_exec($conn_id, "USE WAREHOUSE " . SNOWFLAKE_WAREHOUSE);

$res = odbc_exec($conn_id, 'SHOW TABLES IN SCHEMA ' . SNOWFLAKE_SCHEMA . ';');
if ($res) 
    print "Tables in schema\n";
    while($row = odbc_fetch_array($res)) 
        print_r($row);
    


$res = odbc_exec($conn_id, 'SELECT * FROM TEST;');
if ($res) 
    print "Test table content\n";
    while($row = odbc_fetch_array($res)) 
        print_r($row);
    

返回

Tables in schema
Array
(
    [created_on] => 2015-09-09 17:34:43.517000
    [name] => TEST
    [database_name] => TESTSUITE
    [schema_name] => TESTSUITE
    [kind] => TRANSIENT
    [comment] =>
    [cluster_by] =>
    [rows] => 3
    [bytes] => 8192
    [owner] => TESTSUITE
    [account_name] => ****
    [retention_time] => 1
)
Test table content
Array
(
    [C1] => c
    [C2] =>
)
Array
(
    [C1] => a
    [C2] =>
)
Array
(
    [C1] => a
    [C2] =>
)

这正是我直接查询数据库时得到的结果。

但是当我想使用 PDO 时,结果变得很奇怪。

$dsn = "Driver=SnowflakeDSIIDriver;Server=" . SNOWFLAKE_HOST;
$dsn .= ";Account=" . SNOWFLAKE_ACCOUNT;
$dsn .= ";Port=" . SNOWFLAKE_PORT;
$dsn .= ";Schema=" . SNOWFLAKE_SCHEMA;
$dsn .= ";Database=" . SNOWFLAKE_DATABASE;
$dsn .= ";Warehouse=" . SNOWFLAKE_WAREHOUSE;

$pdo = new PDO("odbc:" . $dsn, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$pdo->exec("USE WAREHOUSE " . SNOWFLAKE_WAREHOUSE);

$query = 'SHOW TABLES IN SCHEMA ' . SNOWFLAKE_SCHEMA . ';';
$statement = $pdo->query($query);
print "Tables in schema\n";
print "Rows: " . $statement->rowCount() . "\n";
while ($row = $statement->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) 
    print_r($row);


$query = 'SELECT * FROM TEST;';
$statement = $pdo->prepare($query);
$statement->execute();
print "Test table content\n";
print "Rows: " . $statement->rowCount() . "\n";
while ($row = $statement->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) 
    print_r($row);

返回

Tables in schema
Rows: 1
Array
(
    [created_on] => 2015-09-09 17:34:43.517000
    [name] =>
    [database_name] =>
    [schema_name] =>
    [kind] =>
    [comment] =>
    [cluster_by] =>
    [rows] =>
    [bytes] =>
    [owner] =>
    [account_name] =>
    [retention_time] =>
)
Test table content
Rows: 3

注意:Rows: 3之后没有进一步的输出。

所以 PDOStatement 知道正确的行数,但 SHOW TABLES 的内容不完整,SELECT * FROM TEST 不知何故完全丢失($statement->fetch() 立即返回 false)。

知道是否有任何 PDO 选项对此有帮助吗?

我还注意到,在这种情况下,本机 ODBC 函数会消耗大约 200MB 的内存,这似乎很多。

【问题讨论】:

您好,我也遇到了同样的问题,请问您有解决方案吗? @DipuR 很遗憾,我们仍在使用 ODBC。 这里也一样。 @OndřejHlaváček 对此有何更新?您是否设法使其与 PDO 一起使用? @DuruCanCelasun 不,我放弃并最终使用 ODBC 【参考方案1】:

我们遇到了类似的问题,CAST 无法通过 PDO 和 Snowflake 正常工作。

异常 'PDOException' 带有消息 'SQLSTATE[SL009]: : 0 [unixODBC][Driver Manager]之前没有绑定列 调用 SQLFetch 或 SQLFetchScroll

长话短说,在与 Snowflake 支持交换了几封电子邮件后,我们发现 Snowflake 不支持 PDO。

目前,由于某些问题,我们不支持 PHP PDO 由于 STRING/VARCHAR 类型和列大小的绑定而发现 16M 字节。这是一个不支持可支持性的决定。 您可以继续将 PHP 与 ODBC 一起使用,但是,我们可能无法 解决出现的问题/错误。

所以你最好的选择是使用 PHP 的原生 odbc_* 系列函数(这就是我们正在做的)。

【讨论】:

以上是关于在 PHP 中通过 ODBC(使用 PDO)查询雪花返回不正确的数据的主要内容,如果未能解决你的问题,请参考以下文章

PHP PDO ODBC 意外的空结果集

使用 pdo-odbc 连接 php 和 .mdb 的 PHP 问题

使用 ODBC 使用 msaccess 创建 PHP PDO 连接时出现致命错误

Xampp php_pdo_odbc 不工作

PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】

MS SQL SERVER、PHP、PDO、ODBC:用户登录失败