HIVEスクリプトで変数を設定する方法


102

SET varname = valueHive QLで同等のSQLを探しています

私はこのようなことができることを知っています:

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

しかし、それから私はこのエラーを受け取ります:

文字「@」はここではサポートされていません


残念ながら、誰かが変数を設定せずにクエリを実行すると、文字列は単に変数呼び出しを文字列として使用するため、文字列変数を設定する安全な方法はありません。:(
コンビ

回答:


201

変数の置換には特別なhiveconfを使用する必要があります。例えば

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

同様に、コマンドラインで渡すことができます:

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

envシステム変数もあるので${env:USER}、たとえば参照できることに注意してください。

使用可能なすべての変数を表示するには、コマンドラインから次のコマンドを実行します。

% hive -e 'set;'

またはハイブプロンプトから実行

hive> set;

更新:hivevar変数も 使用し始め、コマンドを使用してhive CLIから含めることができるhqlスニペットにそれらを入れましたsource(またはコマンドラインから-iオプションとして渡します)。ここでの利点は、変数をhivevarプレフィックスの有無にかかわらず使用でき、グローバルとローカルの使用に似たものを許可することです。

したがって、tablename変数を設定するsetup.hqlがあるとします。

set hivevar:tablename=mytable;

次に、ハイブを持ち込むことができます。

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

クエリで使用:

hive> select * from ${tablename}

または

hive> select * from ${hivevar:tablename}

$ {hivevar:tablename}ではなく、$ {tablename}の使用に影響する「ローカル」テーブル名を設定することもできます

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

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

おそらくCLIからはあまり意味がありませんが、sourceを使用するファイルにhqlを含めることができますが、残りのスクリプトで使用するために一部の変数を「ローカル」に設定します。


1
これはコマンドラインからパラメーターを渡しているので、Karmasphereでクエリを開発していて、スクリプトで日付を10回ハードコードしないように、物乞いでいくつかの定数を設定する必要があります。そのようなことは可能ですか?
user1678312 '19

両方の方法で動作しset CURRENT_DATE='2012-09-16';ますが、後で参照できます${hiveconf:CURRENT_DATE}
libjack

1
複数のHiveジョブを同時に実行している場合、これはどのように機能しますか?彼らはお互いから価値を拾うことになるのでしょうか?自動化では、いくつかのSETステートメントを付加してHQLファイルを作成しています。同じ変数名を使用する2つのジョブを同時に送信した場合、一方のジョブが他方のジョブから値を取得しないことを確認したいと思います。ここのセマンティクスは、あなたの答えから明確ではありません。
MattD 14

5
これは私にとってHiveサーバーで機能します。ただし、IntelliJのローカルマシンでいくつかの統合テストをセットアップしました。私は、変数をこの方法を使用しようとすると、次のエラーを取得しておく:FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
chepukha

1
@DatabaseCoder私の知る限り、そのようなものは機能しません。そのようなものが必要なときはいつでも、最初のクエリを実行してから、「
hiveconf

21

ここでのほとんどの答えは、変数を格納するために、hiveconfまたはhivevar名前空間を使用することを提案しています。そして、それらすべての答えは正しいです。ただし、名前空間がもう1つあります。

namespaces変数を保持するために利用可能な合計3つがあります。

  1. ハイブコンフ -はこれで始まり、すべてのハイブ構成はこのconfの一部として保存されます。当初、変数の置換はハイブの一部ではなく、導入されると、すべてのユーザー定義変数もハイブの一部として格納されました。これは間違いなく良い考えではありません。したがって、さらに2つの名前空間が作成されました。
  2. hivevar:ユーザー変数を格納する
  3. system:システム変数を格納します。

したがって、クエリの一部として変数(つまり、日付またはproduct_number)を格納する場合は、hivevar名前空間ではなくhiveconf名前空間を使用する必要があります。

そして、これはそれがどのように機能するかです。

hiveconfは引き続きデフォルトの名前空間であるため、名前空間を指定しない場合、変数はhiveconf名前空間に格納されます。

ただし、変数を参照する場合、それは真実ではありません。デフォルトでは、hivevarを参照します名前空間をます。紛らわしいですよね?次の例を使用すると、より明確になります。

下記のように名前空間を指定しない場合、変数varhiveconf名前空間に格納されます。

set var="default_namespace";

したがって、これにアクセスするには、 hiveconf名前空間を指定する必要があります

select ${hiveconf:var};

また、名前空間を指定しないと、以下に示すエラーが発生します。デフォルトでは、変数にアクセスしようとすると、hivevar名前空間のみをチェックするためです。そして、中にhivevarあっという名前の変数がありませんvar

select ${var}; 

hivevar名前空間を明示的に提供しました

set hivevar:var="hivevar_namespace";

名前空間を提供しているので、これは機能します。

select ${hivevar:var}; 

また、デフォルトではhivevar、変数の参照中に使用されるワークスペースはです。以下も機能します。

select ${var};


3

2つの簡単な方法:

hive confの使用

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

ハイブ変数を使用する

CLIで変数を設定し、ハイブで使用します

set hivevar:USER_NAME='FOO';

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

ドキュメント: https : //cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution


2

注意すべきことの1つは、文字列を設定してから参照することです。あなたは引用符が衝突していないことを確認する必要があります。

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

日付を設定する場合、文字列が競合する可能性があるため、コードで日付を参照します。これは、上記のstart_dateセットでは機能しません。

 '${hiveconf:start_date}'

クエリで文字列を参照するときは、文字列に一重引用符または二重引用符を2回設定しないように注意してください。


2

誰かがcliを使用してハイブクエリをパラメーター化する必要がある場合に備えて。

たとえば:

hive_query.sql

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

ここで、cliから上記のsqlファイルを実行します。

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

0

この方法を試してください:

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

それは私のプラットフォームでうまく機能します。


0

変数はシェルスクリプトでエクスポートできますexport CURRENT_DATE = "2012-09-16"

次に、hiveqlでSELECT * FROM foo WHERE day> = '$ {env:CURRENT_DATE}'を好みます


-7

別のクエリの出力を変数に格納でき、後者をコードで使用できます。

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

間違いです。My_tableからcount(*)を選択してください。varに格納されます。
Ilya Bystrov、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.