Я шукаю еквівалент 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 та system , тому ви можете посилатися ${env:USER}
на приклад.
Щоб побачити всі доступні змінні, у командному рядку запустіть
% hive -e 'set;'
або із запиту на вулик, біжіть
hive> set;
Оновлення:
я також почав використовувати змінні hivevar , вводячи їх у фрагменти hql, які я можу включити з CLI вулика за допомогою source
команди (або передати як -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, але може мати 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
доступних для зберігання змінних.
Отже, якщо ви зберігаєте змінну як частину запиту (наприклад, дата або номер_файла), ви повинні використовувати 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> 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
Ви можете експортувати змінну в сценарій оболонки експорту CURRENT_DATE = "2012-09-16"
Тоді у hiveql вам подобається SELECT * FOO foo WHERE day> = '$ {env: CURRENT_DATE}'
Ви можете зберігати результат іншого запиту в змінній, а останній ви можете використовувати той самий у своєму коді:
set var=select count(*) from My_table;
${hiveconf:var};