Запрос Snowflake через ODBC (с использованием PDO) в PHP возвращает неверные данные

Я пытаюсь подключиться к Snowflake через их драйвер ODBC в PHP (CentOS 6 и 7) и использовать PDO для облегчения доступа.

Драйвер ODBC, похоже, установлен и работает правильно, поскольку собственные функции ODBC в PHP работают довольно хорошо:

$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 в этом случае потребляют ~ 200 МБ памяти, что кажется много.


person Ondřej Hlaváček    schedule 10.09.2015    source источник
comment
Привет, у меня такая же проблема, вы получили какое-нибудь решение?   -  person Dipu R    schedule 24.03.2016
comment
@DipuR, к сожалению, мы все еще используем ODBC.   -  person Ondřej Hlaváček    schedule 29.03.2016
comment
То же самое и здесь. @ OndřejHlaváček есть новости по этому поводу? Удалось заставить его работать с PDO?   -  person Duru Can Celasun    schedule 26.05.2016
comment
@DuruCanCelasun нет, я сдался и в конечном итоге использовал ODBC   -  person Ondřej Hlaváček    schedule 30.05.2016


Ответы (1)


У нас была аналогичная проблема, когда CAST некорректно работал через PDO со Snowflake.

исключение 'PDOException' с сообщением 'SQLSTATE [SL009]: ‹>: 0 [unixODBC] [Диспетчер драйверов] Перед вызовом SQLFetch или SQLFetchScroll столбцы не были связаны

Короче говоря, после обмена парой писем со службой поддержки Snowflake мы обнаружили, что PDO не поддерживается Snowflake.

В настоящее время мы не поддерживаем PHP PDO из-за некоторых проблем, обнаруженных из-за привязки типа STRING / VARCHAR и размера столбцов, равного 16 МБ. Было принято решение не продвигаться вперед с поддержкой. Вы можете продолжать использовать PHP с ODBC, однако мы не сможем устранять проблемы / ошибки по мере их возникновения.

Поэтому лучше всего использовать родное odbc_* семейство функций из PHP (это то, что мы делаем).

person Grega Kešpret    schedule 25.08.2016