Niestety, nie ma bezpiecznego sposobu na ustawienie zmiennej łańcuchowej, ponieważ jeśli ktoś uruchomi zapytanie bez ustawiania zmiennej, łańcuch po prostu użyje wywołania zmiennej jako łańcucha. :(
combinatorist
Odpowiedzi:
202
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}'
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ą sourcepolecenia (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.
To jest przekazywanie parametru z wiersza poleceń. Tworzę zapytania w Karmasphere i muszę ustawić kilka elementów na początku, aby nie zakodować dat w moim skrypcie 10 razy. Czy coś takiego jest możliwe?
user1678312
działa w obie strony, jeśli to zrobisz set CURRENT_DATE='2012-09-16';, możesz odnieść się do tego później${hiveconf:CURRENT_DATE}
libjack
1
Jak to działa, jeśli mam jednocześnie uruchomionych wiele zadań Hive? Czy ostatecznie przejmą od siebie wartości? W automatyzacji konstruuję plik HQL, poprzedzając go kilkoma instrukcjami SET. Chcę się upewnić, że jeśli prześlę jednocześnie dwa zadania, które używają tych samych nazw zmiennych, jedno zadanie nie pobierze wartości z innego zadania. Ta semantyka nie jest jasna z twojej odpowiedzi.
MattD
5
to działa dla mnie na serwerze Hive. Jednak skonfigurowałem kilka testów integracji na komputerze lokalnym w IntelliJ. Podczas próby użycia zmiennej w ten sposób FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
pojawia
1
@DatabaseCoder O ile wiem, nic takiego nie zadziała. Zawsze, gdy potrzebuję czegoś takiego, muszę wykonać pierwsze zapytanie, a następnie przekazać przez „--hiveconf”
libjack.
21
Większość odpowiedzi sugeruje użycie hiveconflub hivevarprzestrzeni nazw do przechowywania zmiennej. Wszystkie te odpowiedzi są prawidłowe. Jest jednak jeszcze jedna przestrzeń nazw.
Dostępne są łącznie trzy namespaceszmienne do przechowywania.
hiveconf - gałąź zaczęła się od tego, cała konfiguracja gałęzi jest przechowywana jako część tego ustawienia. Początkowo podstawianie zmiennych nie było częścią gałęzi, a kiedy zostało wprowadzone, wszystkie zmienne zdefiniowane przez użytkownika były również przechowywane w ramach tego. Co zdecydowanie nie jest dobrym pomysłem. Utworzono więc dwie kolejne przestrzenie nazw.
hivevar : do przechowywania zmiennych użytkownika
system : do przechowywania zmiennych systemowych.
Jeśli więc przechowujesz zmienną jako część zapytania (np. Datę lub numer_produktu), powinieneś używać hivevarprzestrzeni nazw, a nie hiveconfprzestrzeni 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 varbędzie przechowywana w hiveconfprzestrzeni 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 hivevartylko w przestrzeni nazw. I hivevarnie ma zmiennej o nazwievar
select ${var};
Udostępniliśmy jawnie hivevarprzestrzeń 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ć.
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.
Odpowiedzi:
Do podstawiania zmiennych musisz użyć specjalnego hiveconf . na przykład
podobnie możesz przekazać w wierszu poleceń:
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
lub w wierszu polecenia ula, uruchom
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 :
wtedy mogę wnieść do ula:
i użyj w zapytaniu:
lub
Mógłbym również ustawić „lokalną” nazwę tabeli, co wpłynęłoby na użycie $ {tablename}, ale nie $ {hivevar: tablename}
vs
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.
źródło
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
lubhivevar
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 niehiveconf
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 whiveconf
przestrzeni nazw.Tak więc, aby uzyskać do niego dostęp, musisz określić
hiveconf
przestrzeń nazwA 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. Ihivevar
nie ma zmiennej o nazwievar
Udostępniliśmy jawnie
hivevar
przestrzeń nazwponieważ zapewniamy przestrzeń nazw, to zadziała.
Domyślnie obszar roboczy używany podczas odwoływania się do zmiennej to
hivevar
, poniższe również będą działać.źródło
Czy próbowałeś użyć znaku dolara i nawiasów w ten sposób:
źródło
Dwa proste sposoby:
Korzystanie z konf. Ula
Używanie vars ula
Na swoim CLI ustaw vars, a następnie użyj ich w ulu
Dokumentacja: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution
źródło
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ą.
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ą.
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.
źródło
Na wypadek, gdyby ktoś musiał sparametryzować zapytanie gałęzi przez CLI.
Na przykład:
hive_query.sql
Teraz wykonaj powyższy plik sql z cli:
źródło
Wypróbuj tę metodę:
działa dobrze na mojej platformie.
źródło
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}'
źródło
Możesz przechowywać wyniki innego zapytania w zmiennej, a później możesz użyć tego samego w swoim kodzie:
źródło