web-dev-qa-db-fra.com

Comment définir des variables dans les scripts Hive

Je recherche l'équivalent SQL de SET varname = value dans Hive QL

Je sais que je peux faire quelque chose comme ça: 

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

Mais alors je reçois cette erreur:

le caractère '@' n'est pas supporté ici

76
user1678312

Vous devez utiliser le spécial hiveconf pour la substitution de variable .

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

de même, vous pouvez passer en ligne de commande:

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

Notez qu'il existe aussi des variables env ​​et system , vous pouvez donc référencer ${env:USER} par exemple.

Pour voir toutes les variables disponibles, à partir de la ligne de commande, exécutez

% Hive -e 'set;'

ou depuis l'invite de la ruche, exécutez

Hive> set;

Mise à jour: J'ai également commencé à utiliser les variables hivevar, en les mettant dans des extraits hql que je peux inclure à partir de Hive CLI à l'aide de la commande source (ou passer en tant qu'option -i à partir de la ligne de commande) . L'avantage ici est que la variable peut ensuite être utilisée avec ou sans le préfixe hivevar, et permet quelque chose qui ressemble à une utilisation globale ou locale.

Supposons donc que setup.hql définisse une variable de nom de table:

set hivevar:tablename=mytable;

alors, je peux apporter à Hive:

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

et utiliser dans la requête:

Hive> select * from ${tablename}

ou

Hive> select * from ${hivevar:tablename}

Je pourrais aussi définir un nom de table "local", ce qui affecterait l'utilisation de $ {nomtable}, mais pas $ {hivevar: nomtable}

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

contre

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

Cela ne veut probablement pas dire grand chose de la CLI, mais peut avoir hql dans un fichier qui utilise source, mais définir certaines des variables "localement" à utiliser dans le reste du script.

173
libjack

Avez-vous essayé d'utiliser le signe dollar et entre crochets comme ceci:

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

La plupart des réponses ici suggèrent d'utiliser soit l'espace de noms hiveconf ou hivevar pour stocker la variable. Et toutes ces réponses sont justes. Cependant, il existe un autre espace de noms. 

_ {Il y a au total trois namespaces disponibles pour les variables de maintien. 

  1. hiveconf _ - Hive a commencé avec cela, toute la configuration de Hive est stockée dans le cadre de cette conf. Initialement, la substitution de variable ne faisait pas partie de Hive et lorsqu'elle a été introduite, toutes les variables définies par l'utilisateur ont également été stockées. Ce qui n'est certainement pas une bonne idée. Deux autres espaces de noms ont donc été créés. 
  2. hivevar: Pour stocker les variables utilisateur
  3. system: pour stocker les variables système. 

Et donc, si vous stockez une variable dans le cadre d’une requête (par exemple date ou numéro de produit), vous devez utiliser l’espace de noms hivevar et non l’espace de noms hiveconf

_ {Et c'est comme ça que ça marche. 

hiveconf _ est toujours le espace de nom par défaut. Par conséquent, si vous ne fournissez pas d'espace de nom, il stockera votre variable dans l'espace de nom hiveconf. 

Cependant, lorsqu'il s'agit de faire référence à une variable, ce n'est pas vrai. Par défaut, il fait référence à hivevar namespace. Déroutant, non? Cela peut devenir plus clair avec l'exemple suivant. 

Si vous faites ne fournissez pas d'espace de nom} comme mentionné ci-dessous, la variable var sera stockée dans l'espace de nom hiveconf

set var="default_namespace";

Donc, pour y accéder, vous devez spécifier _ hiveconf namespace 

select ${hiveconf:var};

Et si vous ne fournissez pas d’espace de nommage}, vous obtiendrez une erreur, comme indiqué ci-dessous, car, par défaut, si vous essayez d’accéder à une variable, elle ne coche que l’espace de nom hivevar. Et dans hivevar il n'y a pas de variable nommée var

select ${var}; 

Nous avons explicitement fourni l'espace de noms hivevar 

set hivevar:var="hivevar_namespace";

comme nous fournissons l'espace de noms, cela fonctionnera. 

select ${hivevar:var}; 

Et par défaut, l’espace de travail utilisé lors du renvoi d’une variable est hivevar, les éléments suivants fonctionneront également. 

select ${var};
2
Gaurang Shah

Deux manières simples: 

Utilisation de Hive conf

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

Utilisation de la ruche

Sur votre CLI, définissez les vars puis utilisez-les dans Hive

set hivevar:USER_NAME='FOO';

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

Documentation:https://cwiki.Apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution

1
Savio D'Souza

Une chose à laquelle il faut être attentif est de placer les chaînes puis de les renvoyer. Vous devez vous assurer que les citations ne sont pas en collision.

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

Il faut être prudent en définissant les dates puis en les référant dans le code, car les chaînes peuvent entrer en conflit. Cela ne fonctionnerait pas avec la date de début définie ci-dessus.

 '${hiveconf:start_date}'

Lors de la définition de variables avec des guillemets de début et de fin. Nous devons être attentifs au fait de ne pas mettre deux guillemets en guise de guillemets simples ou doubles pour les chaînes lorsque nous nous y référons dans la requête.

1
blondie9x

Vous pouvez exporter la variable dans l'exportation de script Shell CURRENT_DATE = "2012-09-16"

Puis dans hiveql vous aimez SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'

0
dominicrd

Essayez cette méthode:

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

cela fonctionne bien sur ma plate-forme.

0
typhoonbxq