Подтвердить что ты не робот

Как установить переменные в сценариях HIVE

Я ищу SQL-эквивалент SET varname = value в Hive QL

Я знаю, что могу сделать что-то вроде этого:

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

Но тогда я получаю эту ошибку:

символ '@' здесь не поддерживается

4b9b3361

Ответ 1

Для замены переменных вам нужно использовать специальную 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

Обратите внимание, что существуют переменные env и system, поэтому вы можете ссылаться на ${env:USER} например.

Чтобы просмотреть все доступные переменные, из командной строки запустите

% hive -e 'set;'

или из приглашения hive, запустите

hive> set;

Update: Я также начал использовать переменные hivevar, помещая их в hql-фрагменты, которые я могу включить из CLI в hive, используя команду source (или передать как -i из командной строки). Преимущество здесь в том, что переменная может быть затем использована с префиксом hivevar или без него и позволяет что-то сродни глобальному или локальному использованию.

Итак, предположим, что у меня есть setup.hql, который устанавливает переменную tablename:

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, но может иметь hql в файле, который использует источник, но установить некоторые из переменных "локально" для использования в остальной части script.

Ответ 2

В большинстве ответов здесь предлагается использовать пространство имен hiveconf или hivevar для хранения переменной. И все эти ответы верны. Однако есть еще одно пространство имен.

Всего доступно три namespaces для хранения переменных.

  1. hiveconf - куст начался с этого, вся конфигурация улья сохраняется как часть этого конф. Первоначально подстановка переменных не была частью улья, и когда она появилась, все переменные, определенные пользователем, также были сохранены как часть этого. Что, безусловно, не очень хорошая идея. Таким образом, было создано еще два пространства имен.
  2. hivevar: для хранения пользовательских переменных
  3. система: для хранения системных переменных.

И поэтому, если вы храните переменную как часть запроса (например, date или product_number), вы должны использовать пространство имен hivevar а не пространство имен hiveconf.

И вот как это работает.

hiveconf по-прежнему является пространством имен по умолчанию, поэтому, если вы не предоставите никакого пространства имен, он сохранит вашу переменную в пространстве имен hiveconf.

Однако, когда речь идет о ссылке на переменную, это не так. По умолчанию это относится к пространству имен hivevar. Смущает, верно? Это может стать понятнее со следующим примером.

Если вы не предоставите пространство имен, как указано ниже, переменная var будет храниться в пространстве имен hiveconf.

set var="default_namespace";

Итак, для доступа к этому вам нужно указать пространство имен hiveconf

select ${hiveconf:var};

И если вы не предоставите пространство имен, оно выдаст вам ошибку, как указано ниже, причина в том, что по умолчанию, если вы пытаетесь получить доступ к переменной, она проверяет hivevar пространство имен hivevar. А в hivevar нет переменной с именем var

select ${var}; 

Мы явно предоставили пространство имен hivevar

set hivevar:var="hivevar_namespace";

поскольку мы предоставляем пространство имен, это будет работать.

select ${hivevar:var}; 

И по умолчанию рабочая область, используемая при обращении к переменной - это hivevar, также будет работать следующее.

select ${var};

Ответ 3

Пробовали ли вы использовать знак доллара и скобки следующим образом:

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

Ответ 4

Два простых способа:

Использование улья конф

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

Использование улья

На вашем CLI установите Vars, а затем используйте их в улье

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

Ответ 5

Следует помнить, что нужно задавать строки, а затем обращаться к ним. Вы должны убедиться, что цитаты не сталкиваются.

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

При установке дат обращайтесь к ним в коде, так как строки могут конфликтовать. Это не будет работать с указанным выше значением start_date.

 '${hiveconf:start_date}'

Мы должны помнить, что нельзя указывать дважды одинарные или двойные кавычки для строк при обращении к ним в запросе.

Ответ 6

Попробуйте этот метод:

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

это хорошо работает на моей платформе.

Ответ 7

Вы можете экспортировать переменную в экспорте скрипта оболочки CURRENT_DATE = "2012-09-16"

Тогда в hiveql вам нравится SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'

Ответ 8

На всякий случай, если кому-то нужно параметризовать запрос улья через cli.

Например:

hive_query.sql

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

Теперь выполните вышеуказанный файл sql из cli:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql

Ответ 9

Вы можете сохранить вывод другого запроса в переменной, а затем вы можете использовать его в своем коде:

set var=select count(*) from My_table;
${hiveconf:var};