HIVE betiklerinde değişkenler nasıl ayarlanır


102

SET varname = valueHive QL'deki SQL eşdeğerini arıyorum

Bunun gibi bir şey yapabileceğimi biliyorum:

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

Ama sonra şu hatayı alıyorum:

Burada '@' karakteri desteklenmez


Ne yazık ki, bir dize değişkeni belirlemenin güvenli bir yolu yoktur, çünkü birisi sorguyu değişkeni ayarlamadan çalıştırırsa, dize değişken çağrısını bir dize olarak kullanır. :(
birleştirici

Yanıtlar:


202

Değişken ikamesi için özel hiveconf'u kullanmanız gerekir . Örneğin

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

benzer şekilde, komut satırını da iletebilirsiniz:

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

Orada Not olduğunu env ve sistem başvurabileceğiniz böylece değişkenler yanı ${env:USER}örneğin.

Kullanılabilir tüm değişkenleri görmek için komut satırından şunu çalıştırın:

% hive -e 'set;'

veya kovan isteminden çalıştırın

hive> set;

Güncelleme: Hivevar değişkenlerini de kullanmaya başladım , onları hql parçacıkları içine koydum , sourcekomutu kullanarak kovan CLI'den ekleyebilirim (veya komut satırından -i seçeneği olarak geçirebilirim). Buradaki avantaj, değişkenin daha sonra hivevar öneki ile ya da olmadan kullanılabilmesi ve küresel ve yerel kullanıma benzer bir şeye izin vermesidir.

Öyleyse, bir tablename değişkeni ayarlayan bazı setup.hql'ye sahip olduğunuzu varsayın :

set hivevar:tablename=mytable;

sonra, kovana getirebilirim:

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

ve sorguda kullan:

hive> select * from ${tablename}

veya

hive> select * from ${hivevar:tablename}

Ayrıca, $ {tablename} kullanımını etkileyecek, ancak $ {hivevar: tablename} kullanılmayan bir "yerel" tablo adı da ayarlayabilirdim

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

vs

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

Muhtemelen CLI'den çok fazla bir şey ifade etmiyor, ancak kaynağı kullanan bir dosyada hql olabilir , ancak komut dosyasının geri kalanında kullanmak için bazı değişkenleri "yerel olarak" ayarlayın.


1
Bu, komut satırından bir parametre geçiriyorum Karmasphere'de sorgular geliştiriyorum ve dilenirken birkaç içerik ayarlamam gerekiyor, böylece betiğimde tarihleri ​​10 kez sabit kodlamam. Böyle bir şey mümkün mü?
user1678312

her iki şekilde de çalışır, eğer yaparsanız set CURRENT_DATE='2012-09-16';daha sonra${hiveconf:CURRENT_DATE}
libjack

1
Aynı anda çalışan birden çok Hive işim varsa bu nasıl çalışır? Birbirlerinden değer alacaklar mı? Otomasyonda, başına bazı SET ifadeleri ekleyerek bir HQL dosyası oluşturuyorum. Aynı değişken adlarını kullanan iki işi aynı anda gönderirsem, bir işin diğer işten değer almayacağından emin olmak istiyorum. Buradaki anlambilim cevabınızdan net değil.
MattD

5
bu benim için Hive sunucusunda çalışıyor. Ancak, IntelliJ'de yerel makinede bazı entegrasyon testleri kurdum. Değişkeni bu şekilde kullanmaya çalışırken şu hatayı almaya devam ediyorum:FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
chepukha

1
@DatabaseCoder Bildiğim kadarıyla, böyle bir şey işe yaramayacak. Ne zaman böyle bir şeye ihtiyacım olsa, ilk sorguyu yapmalı ve sonra "--hiveconf" üzerinden geçmeliyim
libjack

21

Buradaki yanıtların çoğu , değişkeni depolamak için ad alanını kullanmayı hiveconfveya hivevarad alanını önermiştir . Ve tüm bu cevaplar doğru. Ancak, bir ad alanı daha vardır.

namespacesDeğişkenleri tutmak için toplam üç tane mevcuttur.

  1. hiveconf - hive bununla başladı, tüm kovan yapılandırması bu yapılandırmanın bir parçası olarak saklanır. Başlangıçta, değişken ikamesi kovanın bir parçası değildi ve tanıtıldığında, tüm kullanıcı tanımlı değişkenler de bunun bir parçası olarak saklanıyordu. Bu kesinlikle iyi bir fikir değil. Böylece iki ad alanı daha yaratıldı.
  2. hivevar : Kullanıcı değişkenlerini saklamak için
  3. system : Sistem değişkenlerini saklamak için.

Dolayısıyla, bir sorgunun parçası olarak bir değişkeni depoluyorsanız (yani tarih veya ürün_sayı), hivevarad alanını değil hiveconfad alanını kullanmalısınız.

Ve bu nasıl işlediğidir.

hiveconf hala varsayılan ad alanıdır , bu nedenle herhangi bir ad alanı sağlamazsanız değişkeninizi hiveconf ad alanında depolar.

Ancak konu bir değişkene atıfta bulunmak olduğunda doğru değildir. Varsayılan olarak hivevar ad alanını ifade eder . Kafa karıştırıcı, değil mi? Aşağıdaki örnekle daha net hale gelebilir.

Eğer yoksa ad sağlamaz aşağıda belirtildiği gibi değişken varsaklanacaktır hiveconfad.

set var="default_namespace";

Dolayısıyla, buna erişmek için hiveconf ad alanı belirtmeniz gerekir.

select ${hiveconf:var};

Ve eğer ad alanı sağlamazsanız , aşağıda belirtildiği gibi size bir hata verecektir, bunun nedeni, bir değişkene erişmeye çalışırsanız, hivevaryalnızca ad alanında kontrol etmesidir. Ve içinde hivevarisimli bir değişken yokvar

select ${var}; 

Açıkça hivevarad alanı sağladık

set hivevar:var="hivevar_namespace";

ad alanını sağladığımız için bu işe yarayacaktır.

select ${hivevar:var}; 

Ve varsayılan olarak, bir değişkene atıfta bulunurken kullanılan çalışma alanı hivevar, aşağıdakiler de çalışacaktır.

select ${var};

7

Dolar işaretini ve parantezleri şu şekilde kullanmayı denediniz mi :

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

Bu benim için çalışan tek cevap. Teklifler, ambari kovanı arayüzümde gereklidir.
Laurens Koppenol

hivevar ve hiveconf olmak üzere iki şey var - her ikisi de burada
Rahul Sharma


2

Dikkat edilmesi gereken bir şey, dizeleri belirlemek ve sonra onlara geri dönmektir. Alıntıların çakışmadığından emin olmalısın.

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

Tarihleri ​​ayarlarken, dizeler çakışabileceğinden bunlara kodla atıfta bulunun. Bu, yukarıda ayarlanan başlangıç_tarihi ile çalışmaz.

 '${hiveconf:start_date}'

Sorguda geri dönerken dizeler için iki kez tek veya çift tırnak koymamaya dikkat etmeliyiz.


2

Birinin kovan sorgusunu cli aracılığıyla parametreleştirmesi gerekmesi durumunda.

Örneğin:

hive_query.sql

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

Şimdi yukarıdaki sql dosyasını cli'den çalıştırın:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql

0

Bu yöntemi deneyin:

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

benim platformumda iyi çalışıyor.


0

Değişkeni kabuk komut dosyası dışa aktarabilirsiniz CURRENT_DATE = "2012-09-16"

Sonra hiveql'de SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}' gibi


-7

Başka bir sorgunun çıktısını bir değişkende saklayabilir ve ardından aynısını kodunuzda kullanabilirsiniz:

set var=select count(*) from My_table;
${hiveconf:var};

Yanılıyorsunuz, My_table'dan count (*) seçin; var içinde depolanacak .
Ilya Bystrov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.