Cara mengatur variabel dalam skrip HIVE

102

Saya mencari padanan SQL SET varname = valuedi Hive QL

Saya tahu saya bisa melakukan sesuatu seperti ini:

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

Tapi kemudian saya mendapatkan kesalahan ini:

karakter '@' tidak didukung di sini

pengguna1678312
sumber
Sayangnya, tidak ada cara yang aman untuk menyetel variabel string karena jika seseorang menjalankan kueri tanpa menyetel variabel, maka string tersebut hanya akan menggunakan panggilan variabel sebagai string. :(
kombinatorist

Jawaban:

201

Anda perlu menggunakan hiveconf khusus untuk substitusi variabel. misalnya

hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'

Demikian pula, Anda dapat meneruskan baris perintah:

% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql

Perhatikan bahwa ada env dan variabel sistem juga, jadi Anda bisa mereferensikan ${env:USER}misalnya.

Untuk melihat semua variabel yang tersedia, dari baris perintah, jalankan

% hive -e 'set;'

atau dari prompt sarang, lari

hive> set;

Pembaruan: Saya sudah mulai menggunakan variabel hivevar juga, menempatkannya ke dalam cuplikan hql yang dapat saya sertakan dari sarang CLI menggunakan sourceperintah (atau berikan opsi -i dari baris perintah). Manfaatnya di sini adalah bahwa variabel kemudian dapat digunakan dengan atau tanpa awalan sarang, dan memungkinkan sesuatu yang mirip dengan penggunaan global vs lokal.

Jadi, asumsikan memiliki beberapa setup.hql yang menetapkan variabel tablename:

set hivevar:tablename=mytable;

kemudian, saya bisa membawa ke sarang:

hive> source /path/to/setup.hql;

dan gunakan dalam kueri:

hive> select * from ${tablename}

atau

hive> select * from ${hivevar:tablename}

Saya juga bisa menyetel tablename "lokal", yang akan memengaruhi penggunaan $ {tablename}, tetapi tidak untuk $ {hivevar: tablename}

hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'

vs.

hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'

Mungkin tidak terlalu berarti dari CLI, tetapi dapat memiliki hql dalam file yang menggunakan source , tetapi mengatur beberapa variabel "secara lokal" untuk digunakan dalam skrip lainnya.

libjack
sumber
1
Ini melewati parameter dari baris perintah Saya mengembangkan kueri di Karmasphere dan perlu mengatur beberapa kontan di memohon sehingga saya tidak memasukkan tanggal 10 kali dalam skrip saya. Apakah hal seperti itu mungkin?
pengguna1678312
berfungsi dua arah, jika Anda melakukannya, set CURRENT_DATE='2012-09-16';Anda dapat merujuknya nanti dengan${hiveconf:CURRENT_DATE}
libjack
1
Bagaimana cara kerjanya jika saya memiliki beberapa pekerjaan Hive yang berjalan secara bersamaan? Akankah mereka akhirnya mengambil nilai satu sama lain? Dalam otomasi saya membangun file HQL dengan mempersiapkannya dengan beberapa pernyataan SET. Saya ingin memastikan jika saya mengirimkan dua pekerjaan sekaligus yang menggunakan nama variabel yang sama, satu pekerjaan tidak akan mengambil nilai dari pekerjaan lain. Semantik di sini tidak jelas dari jawaban Anda.
MattD
5
ini bekerja untuk saya di server Hive. Namun, saya telah menyiapkan beberapa pengujian integrasi pada mesin lokal di IntelliJ. Saya terus mendapatkan kesalahan berikut ketika mencoba menggunakan variabel dengan cara ini:FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
chepukha
1
@DatabaseCoder Sepengetahuan saya, hal seperti itu tidak akan berhasil. Kapan pun saya membutuhkan sesuatu seperti itu, saya harus melakukan kueri pertama dan kemudian meneruskan melalui "--hiveconf"
libjack
21

Sebagian besar jawaban di sini menyarankan penggunaan hiveconfatau hivevarnamespace untuk menyimpan variabel. Dan semua jawaban itu benar. Namun, ada satu namespace lagi.

Ada tiga total yang namespacestersedia untuk menyimpan variabel.

  1. hiveconf - hive dimulai dengan ini, semua konfigurasi sarang disimpan sebagai bagian dari conf ini. Awalnya, substitusi variabel bukan bagian dari sarang dan ketika diperkenalkan, semua variabel yang ditentukan pengguna disimpan sebagai bagian dari ini juga. Yang jelas bukan ide yang bagus. Jadi dua ruang nama lagi dibuat.
  2. hivevar : Untuk menyimpan variabel pengguna
  3. sistem : Untuk menyimpan variabel sistem.

Jadi jika Anda menyimpan variabel sebagai bagian dari kueri (yaitu tanggal atau nomor_produk), Anda harus menggunakan hivevarnamespace dan bukan hiveconfnamespace.

Dan begitulah cara kerjanya.

hiveconf masih merupakan namespace default , jadi jika Anda tidak memberikan namespace apa pun, variabel Anda akan disimpan di namespace hiveconf.

Namun, ketika merujuk pada variabel, itu tidak benar. Secara default mengacu pada namespace sarang . Membingungkan, bukan? Ini bisa menjadi lebih jelas dengan contoh berikut.

Jika Anda tidak memberikan namespace seperti yang disebutkan di bawah, variabel varakan disimpan di hiveconfnamespace.

set var="default_namespace";

Jadi, untuk mengakses ini, Anda perlu menentukan hiveconf namespace

select ${hiveconf:var};

Dan jika Anda tidak memberikan namespace itu akan memberi Anda kesalahan seperti yang disebutkan di bawah ini, alasannya adalah bahwa secara default jika Anda mencoba mengakses variabel, ia hanya memeriksa di hivevarnamespace. Dan di hivevardalamnya tidak ada variabel bernamavar

select ${var}; 

Kami telah menyediakan hivevarnamespace secara eksplisit

set hivevar:var="hivevar_namespace";

karena kami menyediakan namespace, ini akan berfungsi.

select ${hivevar:var}; 

Dan sebagai default, ruang kerja yang digunakan selama merujuk variabel adalah hivevar, berikut ini juga akan berfungsi.

select ${var};
Gaurang Shah
sumber
7

Sudahkah Anda mencoba menggunakan tanda dolar dan tanda kurung seperti ini:

SELECT * 
FROM foo 
WHERE day >= '${CURRENT_DATE}';
YABADABADOU
sumber
Ini adalah satu-satunya jawaban yang berhasil untuk saya. Kutipan diperlukan di antarmuka sarang ambari saya.
Laurens Koppenol
ada dua hal hivevar dan hiveconf- keduanya dijelaskan secara rinci di sini
Rahul Sharma
3

Dua cara mudah:

Menggunakan conf hive

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

Menggunakan vars sarang

Pada CLI Anda set vars dan kemudian gunakan di sarang

set hivevar:USER_NAME='FOO';

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

Dokumentasi: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution

Savio D'Souza
sumber
2

Satu hal yang harus diperhatikan adalah mengatur string kemudian merujuk kembali padanya. Anda harus memastikan bahwa kutipan tidak bertabrakan.

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

Saat menetapkan tanggal, rujuklah ke dalam kode karena string dapat bertentangan. Ini tidak akan berfungsi dengan start_date yang disetel di atas.

 '${hiveconf:start_date}'

Kami harus berhati-hati untuk tidak menetapkan dua kali tanda kutip tunggal atau ganda untuk string saat merujuk kembali ke mereka dalam kueri.

berambut pirang
sumber
2

Untuk berjaga-jaga jika seseorang perlu membuat parameter kueri sarang melalui cli.

Misalnya:

hive_query.sql

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

Sekarang jalankan file sql di atas dari cli:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
Abdul Mannan
sumber
0

Coba metode ini:

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

itu bekerja dengan baik di platform saya.

typhoonbxq
sumber
0

Anda dapat mengekspor variabel dalam ekspor skrip shell CURRENT_DATE = "2012-09-16"

Kemudian di hiveql Anda suka SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'

Dileep Dominic
sumber
-7

Anda dapat menyimpan keluaran dari kueri lain dalam variabel dan terakhir Anda dapat menggunakan yang sama dalam kode Anda:

set var=select count(*) from My_table;
${hiveconf:var};
Suman
sumber
Anda salah, pilih count (*) dari My_table; akan disimpan di var .
Ilya Bystrov