Laravel+ODBC连接Snowflake取数报错:SQLSTATE[SL009]
解决Laravel连接Snowflake查询VARIANT字段时的SQLSTATE[SL009]错误
问题场景
查询Snowflake中存储为VARIANT类型的JSON字段时,触发以下错误:
SQLSTATE[SL009]: <<Unknown error>>: [unixODBC][Driver Manager]No columns were bound prior to calling SQLFetch or SQLFetchScroll (SQLFetchScroll[0] at /build/php8.2-upKkUu/php8.2-8.2.6/ext/pdo_odbc/odbc_stmt.c:556)
执行的SQL语句:
$select = "select parse_json(ACCOUNT_DETAILS) from POC.TEST.TESTING_TABLE2 where ACCOUNT_DETAILS:gender='Male'"; $res= DB::connection('snowflake')->select($select);
问题原因
Snowflake ODBC驱动无法自动识别parse_json返回的半结构化数据类型,导致列绑定失败,无法执行SQLFetch操作。
解决方案
1. 显式转换数据类型并指定列别名
将parse_json的结果转换为字符串类型,同时给列指定明确别名,让ODBC驱动能识别列类型并完成绑定:
$select = "select parse_json(ACCOUNT_DETAILS)::string as account_details from POC.TEST.TESTING_TABLE2 where ACCOUNT_DETAILS:gender='Male'"; $res= DB::connection('snowflake')->select($select); // 后续可将字符串转回JSON对象 foreach($res as $item) { $accountDetails = json_decode($item->account_details, true); }
2. 按需提取JSON内的字段
如果不需要完整JSON内容,直接提取所需字段并转换为基础数据类型,避免处理复杂半结构化数据:
$select = "select ACCOUNT_DETAILS:name::string as name, ACCOUNT_DETAILS:age::int as age from POC.TEST.TESTING_TABLE2 where ACCOUNT_DETAILS:gender='Male'"; $res= DB::connection('snowflake')->select($select);
3. 更新Snowflake ODBC驱动
旧版本ODBC驱动对VARIANT类型的半结构化数据处理存在兼容性问题,安装最新稳定版驱动后重新配置连接重试。
4. 调整Laravel数据库连接配置
在config/database.php的Snowflake连接配置中,添加PDO选项强制将所有查询结果转为字符串,帮助驱动完成列绑定:
'snowflake' => [ 'driver' => 'snowflake', 'host' => env('SNOWFLAKE_HOST'), 'database' => env('SNOWFLAKE_DATABASE'), 'username' => env('SNOWFLAKE_USERNAME'), 'password' => env('SNOWFLAKE_PASSWORD'), 'warehouse' => env('SNOWFLAKE_WAREHOUSE'), 'schema' => env('SNOWFLAKE_SCHEMA'), 'options' => [ PDO::ATTR_STRINGIFY_FETCHES => true, ], ],
内容的提问来源于stack exchange,提问作者Sandeep Nambiar
相关产品推荐
相关产品推荐

