如何在HIVE脚本中设置变量

use*_*312 95 hive hiveql

我正在寻找SET varname = valueHive QL中的SQL等价物

我知道我可以这样做:

SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Run Code Online (Sandbox Code Playgroud)

但后来我得到了这个错误:

这里不支持字符'@'

lib*_*ack 190

您需要使用特殊的hiveconf进行变量替换.例如

hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'
Run Code Online (Sandbox Code Playgroud)

同样,你可以传递命令行:

% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql
Run Code Online (Sandbox Code Playgroud)

请注意,还有env系统变量,因此您可以参考${env:USER}例如.

要查看所有可用变量,请从命令行运行

% hive -e 'set;'
Run Code Online (Sandbox Code Playgroud)

或者从蜂巢提示符运行

hive> set;
Run Code Online (Sandbox Code Playgroud)

更新: 我也开始使用hivevar变量,将它们放入hql片段中,我可以使用source命令从hive CLI中包含(或从命令行传递-i选项).这里的好处是,变量可以在有或没有hivevar前缀的情况下使用,并允许类似于全局和本地使用的东西.

所以,假设有一些setup.hql设置一个tablename变量:

set hivevar:tablename=mytable;
Run Code Online (Sandbox Code Playgroud)

然后,我可以带入蜂巢:

hive> source /path/to/setup.hql;
Run Code Online (Sandbox Code Playgroud)

并在查询中使用:

hive> select * from ${tablename}
Run Code Online (Sandbox Code Playgroud)

要么

hive> select * from ${hivevar:tablename}
Run Code Online (Sandbox Code Playgroud)

我还可以设置一个"本地"表名,这会影响$ {tablename}的使用,但不会影响$ {hivevar:tablename}

hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'
Run Code Online (Sandbox Code Playgroud)

VS

hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'
Run Code Online (Sandbox Code Playgroud)

可能并不意味着从CLI过多,但可以在使用source的文件中使用hql ,但是将一些变量"本地"设置为在脚本的其余部分中使用.

  • 这适用于Hive服务器.但是,我在IntelliJ中的本地机器上设置了一些集成测试.当我尝试以这种方式使用变量时,我不断收到以下错误:```FAILED:ParseException line x:y无法识别表达式规范中`''''''''hiveconf'附近的输入``` (5认同)

Gau*_*hah 16

这里的大多数答案都建议使用hiveconfhivevar名称空间来存储变量。所有这些答案都是正确的。但是,还有一个名称空间。

共有三个namespaces可用于保存变量的变量。

  1. hiveconf -hive 从此开始,所有hive配置都存储为该conf的一部分。最初,变量替换不是蜂巢的一部分,当它引入时,所有用户定义的变量也都作为变量的一部分存储。这绝对不是一个好主意。因此,又创建了两个名称空间。
  2. hivevar:存储用户变量
  3. system:存储系统变量。

因此,如果您将变量存储为查询的一部分(例如,日期或product_number),则应使用hivevar名称空间而不是hiveconf名称空间。

这就是它的工作方式。

hiveconf仍然是默认名称空间,因此,如果您不提供任何名称空间,它将把您的变量存储在hiveconf名称空间中。

但是,当涉及到引用变量时,事实并非如此。默认情况下,它指的是hivevar命名空间。令人困惑,对不对?通过以下示例,它会变得更加清晰。

如果不提供如下所述的名称空间,则变量var将存储在hiveconf名称空间中。

set var="default_namespace";
Run Code Online (Sandbox Code Playgroud)

因此,要访问它,您需要指定 hiveconf名称空间

select ${hiveconf:var};
Run Code Online (Sandbox Code Playgroud)

而且,如果您不提供命名空间,则会出现以下错误,原因是默认情况下,如果您尝试访问变量,则hivevar仅检查命名空间。而且hivevar其中没有名为var

select ${var}; 
Run Code Online (Sandbox Code Playgroud)

我们已经明确提供了hivevar名称空间

set hivevar:var="hivevar_namespace";
Run Code Online (Sandbox Code Playgroud)

当我们提供名称空间时,它将起作用。

select ${hivevar:var}; 
Run Code Online (Sandbox Code Playgroud)

并且默认情况下,在引用变量期间使用的工作空间为hivevar,以下内容也将起作用。

select ${var};
Run Code Online (Sandbox Code Playgroud)


YAB*_*DOU 7

您是否尝试过像这样使用美元符号括号:

SELECT * 
FROM foo 
WHERE day >= '${CURRENT_DATE}';
Run Code Online (Sandbox Code Playgroud)