Ond*_*ček 5 php odbc pdo snowflake-cloud-data-platform
我正在尝试通过 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 内存,这看起来很多。
我们遇到了类似的问题,CAST 无法通过带有 Snowflake 的 PDO 正常工作。
异常“PDOException”,消息“SQLSTATE[SL009]:<>:0 [unixODBC] [驱动程序管理器]在调用 SQLFetch 或 SQLFetchScroll 之前没有绑定列
长话短说,在与 Snowflake 支持人员交换了几封电子邮件后,我们发现 Snowflake 不支持 PDO。
目前,由于 STRING/VARCHAR 类型的绑定和列大小为 16M 字节,导致出现一些问题,我们不支持 PHP PDO。这是一个不继续推进的决定。您可以继续将 PHP 与 ODBC 结合使用,但是,我们可能无法解决出现的问题/错误。
因此,最好的选择是使用odbc_*PHP 的原生函数系列(这就是我们正在做的)。