Szukam odpowiednika SQL SET varname = value
w Hive QL
Wiem, że mogę zrobić coś takiego:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Ale potem pojawia się ten błąd:
znak „@” nie jest tutaj obsługiwany
Szukam odpowiednika SQL SET varname = value
w Hive QL
Wiem, że mogę zrobić coś takiego:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Ale potem pojawia się ten błąd:
znak „@” nie jest tutaj obsługiwany
Odpowiedzi:
Do podstawiania zmiennych musisz użyć specjalnego hiveconf . na przykład
hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'
podobnie możesz przekazać w wierszu poleceń:
% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql
Zauważ, że istnieją również zmienne env i systemowe , więc możesz ${env:USER}
na przykład odwołać się .
Aby zobaczyć wszystkie dostępne zmienne, z wiersza poleceń uruchom
% hive -e 'set;'
lub w wierszu polecenia ula, uruchom
hive> set;
Aktualizacja:
Zacząłem również używać zmiennych hivevar , umieszczając je we fragmentach hql, które mogę dołączyć z hive CLI za pomocą source
polecenia (lub przekazać jako opcję -i z wiersza poleceń). Zaletą jest to, że zmienna może być następnie używana z prefiksem hivevar lub bez niego i umożliwia użycie czegoś zbliżonego do użycia globalnego lub lokalnego.
Załóżmy więc, że mamy plik setup.hql, który ustawia zmienną nazwy tabeli :
set hivevar:tablename=mytable;
wtedy mogę wnieść do ula:
hive> source /path/to/setup.hql;
i użyj w zapytaniu:
hive> select * from ${tablename}
lub
hive> select * from ${hivevar:tablename}
Mógłbym również ustawić „lokalną” nazwę tabeli, co wpłynęłoby na użycie $ {tablename}, ale nie $ {hivevar: tablename}
hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'
vs
hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'
Prawdopodobnie nie znaczy to zbyt wiele z CLI, ale może mieć hql w pliku, który używa źródła , ale ustawia niektóre zmienne „lokalnie” do użycia w pozostałej części skryptu.
set CURRENT_DATE='2012-09-16';
, możesz odnieść się do tego później${hiveconf:CURRENT_DATE}
FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
Większość odpowiedzi sugeruje użycie hiveconf
lub hivevar
przestrzeni nazw do przechowywania zmiennej. Wszystkie te odpowiedzi są prawidłowe. Jest jednak jeszcze jedna przestrzeń nazw.
Dostępne są łącznie trzy namespaces
zmienne do przechowywania.
Jeśli więc przechowujesz zmienną jako część zapytania (np. Datę lub numer_produktu), powinieneś używać hivevar
przestrzeni nazw, a nie hiveconf
przestrzeni nazw.
I tak to działa.
hiveconf jest nadal domyślną przestrzenią nazw , więc jeśli nie podasz żadnej przestrzeni nazw, będzie przechowywać zmienną w przestrzeni nazw hiveconf.
Jednak jeśli chodzi o odwoływanie się do zmiennej, to nieprawda. Domyślnie odnosi się do przestrzeni nazw hivevar . Mylące, prawda? Może to stać się jaśniejsze na następującym przykładzie.
Jeśli nie podasz przestrzeni nazw, jak wspomniano poniżej, zmienna var
będzie przechowywana w hiveconf
przestrzeni nazw.
set var="default_namespace";
Tak więc, aby uzyskać do niego dostęp, musisz określić hiveconf
przestrzeń nazw
select ${hiveconf:var};
A jeśli nie podasz przestrzeni nazw , spowoduje to błąd, jak wspomniano poniżej, ponieważ domyślnie, jeśli spróbujesz uzyskać dostęp do zmiennej, sprawdza ona hivevar
tylko w przestrzeni nazw. I hivevar
nie ma zmiennej o nazwievar
select ${var};
Udostępniliśmy jawnie hivevar
przestrzeń nazw
set hivevar:var="hivevar_namespace";
ponieważ zapewniamy przestrzeń nazw, to zadziała.
select ${hivevar:var};
Domyślnie obszar roboczy używany podczas odwoływania się do zmiennej to hivevar
, poniższe również będą działać.
select ${var};
Czy próbowałeś użyć znaku dolara i nawiasów w ten sposób:
SELECT *
FROM foo
WHERE day >= '${CURRENT_DATE}';
Dwa proste sposoby:
Korzystanie z konf. Ula
hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';
Używanie vars ula
Na swoim CLI ustaw vars, a następnie użyj ich w ulu
set hivevar:USER_NAME='FOO';
hive> select * from foobar where NAME = '${USER_NAME}';
hive> select * from foobar where NAME = '${hivevar:USER_NAME}';
Dokumentacja: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution
Jedną rzeczą, o której należy pamiętać, jest ustawienie łańcuchów, a następnie odwołanie się do nich. Musisz się upewnić, że cytaty się nie kolidują.
set start_date = '2019-01-21';
select ${hiveconf:start_date};
Podczas ustawiania dat odwołujemy się do nich w kodzie, ponieważ ciągi znaków mogą powodować konflikty. To nie zadziała z ustawioną powyżej datą_początkową.
'${hiveconf:start_date}'
Musimy pamiętać, aby nie ustawiać podwójnych apostrofów lub podwójnych cudzysłowów dla ciągów podczas odwoływania się do nich w zapytaniu.
Na wypadek, gdyby ktoś musiał sparametryzować zapytanie gałęzi przez CLI.
Na przykład:
hive_query.sql
SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'
Teraz wykonaj powyższy plik sql z cli:
hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
Wypróbuj tę metodę:
set t=20;
select *
from myTable
where age > '${hiveconf:t}';
działa dobrze na mojej platformie.
Możesz wyeksportować zmienną za pomocą eksportu skryptu powłoki CURRENT_DATE = "2012-09-16"
Następnie w hiveql lubisz SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'
Możesz przechowywać wyniki innego zapytania w zmiennej, a później możesz użyć tego samego w swoim kodzie:
set var=select count(*) from My_table;
${hiveconf:var};