Я ищу SQL-эквивалент SET varname = valueв Hive QL
Я знаю, что могу сделать что-то вроде этого:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Но потом я получаю такую ошибку:
символ '@' здесь не поддерживается
Я ищу SQL-эквивалент SET varname = valueв Hive QL
Я знаю, что могу сделать что-то вроде этого:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Но потом я получаю такую ошибку:
символ '@' здесь не поддерживается
Ответы:
Вам нужно использовать специальный 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 и системные , поэтому вы можете ссылаться, ${env:USER}например.
Чтобы увидеть все доступные переменные, из командной строки запустите
% hive -e 'set;'
или из подсказки улья запустите
hive> set;
Обновление:
я также начал использовать переменные hivevar , помещая их в фрагменты hql, которые я могу включить из интерфейса sourceкомандной строки hive с помощью команды (или передать как параметр -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 в файле, который использует исходный код , но установить некоторые переменные «локально» для использования в остальной части скрипта.
set CURRENT_DATE='2012-09-16';вы можете обратиться к нему позже с помощью${hiveconf:CURRENT_DATE}
FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
В большинстве ответов здесь предлагается использовать hiveconfили hivevarпространство имен для хранения переменной. И все эти ответы верны. Однако есть еще одно пространство имен.
Всего namespacesдоступно три переменных для хранения.
Итак, если вы сохраняете переменную как часть запроса (например, дату или product_number), вы должны использовать 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};
Вы пробовали использовать знак доллара и скобки следующим образом:
SELECT *
FROM foo
WHERE day >= '${CURRENT_DATE}';
Два простых способа:
Использование hive conf
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
Одна вещь, о которой следует помнить, - это устанавливать строки, а затем возвращаться к ним. Вы должны убедиться, что цитаты не противоречат друг другу.
set start_date = '2019-01-21';
select ${hiveconf:start_date};
При установке дат обращайтесь к ним в коде, поскольку строки могут конфликтовать. Это не сработает с установленной выше start_date.
'${hiveconf:start_date}'
Мы должны помнить о том, чтобы не устанавливать двойные одинарные или двойные кавычки для строк при обратном обращении к ним в запросе.
На всякий случай кому-то нужно параметризовать запрос улья через 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
Вы можете экспортировать переменную в сценарии оболочки export CURRENT_DATE = "2012-09-16"
Тогда в hiveql вам нравится SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'
Вы можете сохранить вывод другого запроса в переменной, а затем вы можете использовать то же самое в своем коде:
set var=select count(*) from My_table;
${hiveconf:var};