110

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

我知道我可以做这样的事情:

SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE

但后来我得到这个错误:

此处不支持字符“@”

4

10 回答 10

218

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

hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= ${hiveconf:CURRENT_DATE}

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

% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql

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

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

% hive -e 'set;'

或从 hive 提示符下,运行

hive> set;

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

因此,假设有一些setup.hql设置了一个表名变量:

set hivevar:tablename=mytable;

然后,我可以带入蜂巢:

hive> source /path/to/setup.hql;

并在查询中使用:

hive> select * from ${tablename}

或者

hive> select * from ${hivevar:tablename}

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

hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'

对比

hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'

可能对 CLI 的意义不大,但可以在使用source的文件中包含 hql ,但“本地”设置一些变量以在脚本的其余部分中使用。

于 2012-09-18T22:03:29.833 回答
29

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

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

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

因此,如果您将变量存储为查询的一部分(即日期或产品编号),您应该使用hivevar命名空间而不是hiveconf命名空间。

这就是它的工作原理。

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

然而,当涉及到一个变量时,这是不正确的。默认情况下,它指的是hivevar命名空间。令人困惑,对吧?下面的例子可以变得更清楚。

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

set var="default_namespace";

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

select ${hiveconf:var};

如果你不提供命名空间,它会给你一个错误,如下所述,原因是默认情况下,如果你尝试访问它只在hivevar命名空间中检查的变量。并且hivevar没有变量命名var

select ${var}; 

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

set hivevar:var="hivevar_namespace";

当我们提供命名空间时,这将起作用。

select ${hivevar:var}; 

默认情况下,引用变量时使用的工作区是hivevar,以下也可以。

select ${var};
于 2019-01-04T02:26:29.180 回答
7

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

SELECT * 
FROM foo 
WHERE day >= '${CURRENT_DATE}';
于 2012-09-17T18:41:11.473 回答
4

以防万一有人需要通过 cli 参数化配置单元查询。

例如:

hive_query.sql

SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'

现在从cli执行上面的sql文件:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
于 2019-10-10T13:16:01.223 回答
3

两种简单的方法:

使用配置单元配置

hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';

使用配置单元变量

在您的 CLI 设置变量,然后在配置单元中使用它们

set hivevar:USER_NAME='FOO';

hive> select * from foobar where NAME = '${USER_NAME}';
hive> select * from foobar where NAME = '${hivevar:USER_NAME}';

文档: https ://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution

于 2018-10-23T18:35:07.917 回答
2

需要注意的一件事是设置字符串,然后再引用它们。您必须确保引号没有冲突。

 set start_date = '2019-01-21';
 select ${hiveconf:start_date}; 

设置日期时,然后在代码中引用它们,因为字符串可能会发生冲突。这不适用于上面设置的 start_date。

 '${hiveconf:start_date}'

在查询中引用字符串时,我们必须注意不要为字符串设置两次单引号或双引号。

于 2019-01-24T18:22:11.107 回答
1

在 Hive 中有多个设置变量的选项。

如果您希望从 Hive shell 内部设置 Hive 变量,您可以使用hivevar. 您可以设置字符串或整数数据类型。他们没有问题。

SET hivevar:which_date=20200808;
select ${which_date};

如果您打算从 shell 脚本设置变量并希望将这些变量传递到您的 Hive 脚本 (HQL) 文件中,则可以--hivevar在调用 hive 或 beeline 命令时使用选项。

# shell script will invoke script like this
beeline --hivevar tablename=testtable -f select.hql
-- select.hql file
select * from <dbname>.${tablename};
于 2020-12-23T16:05:40.187 回答
0

试试这个方法:

set t=20;
select *
from myTable
where age > '${hiveconf:t}'; 

它在我的平台上运行良好。

于 2018-08-08T06:36:56.343 回答
0

您可以在 shell 脚本 export CURRENT_DATE="2012-09-16" 中导出变量

然后在 hiveql 你喜欢 SELECT * FROM foo WHERE day >= '${env:CURRENT_DATE}'

于 2019-04-10T10:47:41.930 回答
-7

您可以将另一个查询的输出存储在一个变量中,然后您可以在代码中使用它:

set var=select count(*) from My_table;
${hiveconf:var};
于 2016-05-07T00:01:34.320 回答