Hive分区INSERT语句中使用hiveconf变量COMPUTE_MONTH报错求助
Hive分区表INSERT INTO使用计算型hiveconf变量报错问题
在Hive中操作分区表时,直接使用字面量定义的hiveconf变量(如PERIOD=202305)可以正常执行DROP PARTITION和INSERT INTO,但通过Hive函数计算得到的COMPUTE_MONTH(上月值)变量却触发报错。
问题复现代码
set PERIOD = 202305; set DAY=concat(substr(${hiveconf:PERIOD},1,4),'-',substr(${hiveconf:PERIOD},5,2),'-01'); -- 预期DAY值为2023-05-01 set COMPUTE_MONTH = date_format(add_months(from_unixtime(unix_timestamp(${hiveconf:DAY}, 'yyyy-MM-dd'), 'yyyy-MM-dd'), -1), 'yyyyMM'); -- 预期COMPUTE_MONTH值为202304 -- Case 1:执行正常 ALTER TABLE db.table DROP PARTITION (snapshot = ${hiveconf:PERIOD}); INSERT INTO TABLE db.table PARTITION (snapshot = ${hiveconf:PERIOD}) SELECT ... -- Case 2:执行报错 ALTER TABLE db.table DROP PARTITION (snapshot = ${hiveconf:COMPUTE_MONTH}); INSERT INTO TABLE db.table PARTITION (snapshot = ${hiveconf:COMPUTE_MONTH}) SELECT ...
现象
- Case 1 使用直接赋值的
PERIOD变量操作分区无异常 - Case 2 使用函数计算得到的
COMPUTE_MONTH变量时触发错误
解决方案
方案1:用hivevar结合临时文件存储计算结果
Hive的set命令无法直接解析执行函数计算,需要通过临时查询把计算结果落地后再读取赋值:
set hivevar:PERIOD=202305; -- 计算上月值并写入临时目录 INSERT OVERWRITE LOCAL DIRECTORY '/tmp/tmp_month' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' SELECT date_format( add_months( to_date(concat(substr('${hivevar:PERIOD}',1,4),'-',substr('${hivevar:PERIOD}',5,2),'-01')), -1 ), 'yyyyMM' ); -- 读取临时文件内容赋值给hivevar变量 set hivevar:COMPUTE_MONTH=`cat /tmp/tmp_month/000000_0`; -- 正常使用变量操作分区 ALTER TABLE db.table DROP PARTITION (snapshot = ${hivevar:COMPUTE_MONTH}); INSERT INTO TABLE db.table PARTITION (snapshot = ${hivevar:COMPUTE_MONTH}) SELECT ...
方案2:在SQL语句中直接嵌入计算逻辑(动态分区)
放弃提前定义变量,直接把上月值的计算逻辑写入SQL语句中,同时使用动态分区语法:
set hivevar:PERIOD=202305; -- 开启动态分区配置 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; -- DROP PARTITION时直接计算分区值 ALTER TABLE db.table DROP PARTITION (snapshot = date_format( add_months( to_date(concat(substr('${hivevar:PERIOD}',1,4),'-',substr('${hivevar:PERIOD}',5,2),'-01')), -1 ), 'yyyyMM' )); -- INSERT时用动态分区,SELECT最后一列返回计算后的分区值 INSERT INTO TABLE db.table PARTITION (snapshot) SELECT col1, col2, ..., date_format( add_months( to_date(concat(substr('${hivevar:PERIOD}',1,4),'-',substr('${hivevar:PERIOD}',5,2),'-01')), -1 ), 'yyyyMM' ) as snapshot FROM your_source_table;
方案3:Shell脚本提前计算变量再传入Hive
如果是通过Shell调用Hive脚本,可以在Shell层完成日期计算,再通过--hiveconf传入变量:
#!/bin/bash PERIOD=202305 # Shell中计算上月值(兼容Linux环境) COMPUTE_MONTH=$(date -d "${PERIOD:0:4}-${PERIOD:4:2}-01 last month" +%Y%m) # 调用Hive时传入两个变量 hive --hiveconf PERIOD=$PERIOD --hiveconf COMPUTE_MONTH=$COMPUTE_MONTH -f your_hive_script.hql
Hive脚本中直接使用${hiveconf:COMPUTE_MONTH}即可,无需再做计算。
内容的提问来源于stack exchange,提问作者Ftu_Sneaky
相关产品推荐
相关产品推荐

