创建Hive临时表后立即查询该表无法正常执行的技术求助
解决ODBC穿透查询中创建临时表并查询的语法错误问题
看起来你在通过SAS Proc SQL或Python pyodbc连接Hortonworks Hadoop时,尝试在单条穿透语句里创建临时表并查询遇到了语法解析错误——这其实是因为Hive(Hortonworks底层用的是Hive)默认不支持在单条SQL语句中包含多个独立的执行单元(比如先CREATE TABLE再SELECT),ODBC驱动会把整个字符串作为单条语句提交给Hive,而Hive的解析器会把分号识别为语句结束,导致后续内容无法被正确解析。
下面给你两个可行的解决方案,按推荐程度排序:
1. 用CTE(公共表表达式)替代临时表(最推荐)
CTE是Hive支持的语法,它可以在单条语句内定义临时的结果集,完全不需要创建实体临时表,既简洁又避免了多语句提交的问题,完美适配你的需求:
SAS Proc SQL示例
proc sql; CONNECT TO ODBC (USER=XXXXX PASSWORD="XXXXX" DSN="XXXXX"); CREATE TABLE max_partition as SELECT * FROM CONNECTION TO ODBC ( WITH tmp1 AS ( SELECT MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id ) SELECT * FROM tmp1 ); quit;
Python pyodbc示例
import pyodbc # 建立连接 conn = pyodbc.connect('DSN=XXXXX;UID=XXXXX;PWD=XXXXX') cursor = conn.cursor() # 用CTE查询各ID的最新分区 query = """ WITH tmp1 AS ( SELECT MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id ) SELECT * FROM tmp1 """ cursor.execute(query) results = cursor.fetchall() # 后续处理结果,比如转为DataFrame等 conn.close()
2. 分开提交创建临时表和查询的语句
如果你一定要用临时表的方式,需要把创建临时表和查询的操作拆分为两个独立的ODBC请求,确保它们在同一个会话中执行(临时表在会话内有效):
SAS Proc SQL示例
proc sql; CONNECT TO ODBC (USER=XXXXX PASSWORD="XXXXX" DSN="XXXXX"); -- 第一步:单独提交创建临时表的语句 EXECUTE ( CREATE TEMPORARY TABLE tmp1 as SELECT MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id ) BY ODBC; -- 第二步:查询刚才创建的临时表 CREATE TABLE max_partition as SELECT * FROM CONNECTION TO ODBC ( SELECT * FROM tmp1 ); quit;
Python pyodbc示例
import pyodbc conn = pyodbc.connect('DSN=XXXXX;UID=XXXXX;PWD=XXXXX') cursor = conn.cursor() # 1. 创建临时表 create_tmp_stmt = """ CREATE TEMPORARY TABLE tmp1 as SELECT MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id """ cursor.execute(create_tmp_stmt) # Hive通常不需要提交,但部分场景下可能需要,可根据情况添加 # conn.commit() # 2. 查询临时表 query = "SELECT * FROM tmp1" cursor.execute(query) results = cursor.fetchall() conn.close()
为什么之前的写法会报错?
你原来的代码把CREATE TEMPORARY TABLE和SELECT放在同一个CONNECTION TO ODBC()块里,ODBC驱动会把整个内容作为单条语句发送给Hive。而Hive的SQL解析器会把第一个分号(GROUP BY id;后面的分号)识别为当前语句的结束,后面的select * from tmp1)就变成了无效的语法,所以触发了ParseException错误。
内容的提问来源于stack exchange,提问作者Coldchain9
相关产品推荐
相关产品推荐

