Cách đặt các biến trong tập lệnh HIVE


102

Tôi đang tìm kiếm SQL tương đương với SET varname = valuetrong Hive QL

Tôi biết tôi có thể làm điều gì đó như sau:

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

Nhưng sau đó tôi gặp lỗi này:

ký tự '@' không được hỗ trợ ở đây


Thật không may, không có cách nào an toàn để đặt biến chuỗi vì nếu ai đó chạy truy vấn mà không đặt biến, thì chuỗi sẽ chỉ sử dụng lệnh gọi biến dưới dạng chuỗi. :(
combinatorist,

Câu trả lời:


201

Bạn cần sử dụng hiveconf đặc biệt để thay thế biến. ví dụ

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

tương tự, bạn có thể chuyển dòng lệnh:

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

Lưu ý rằng có các biến envhệ thống , vì vậy bạn có thể tham khảo${env:USER} ví dụ.

Để xem tất cả các biến có sẵn, từ dòng lệnh, hãy chạy

% hive -e 'set;'

hoặc từ dấu nhắc tổ ong, chạy

hive> set;

Cập nhật: Tôi cũng đã bắt đầu sử dụng các biến hivevar , đưa chúng vào các đoạn mã hql mà tôi có thể đưa vào từ hive CLI bằng sourcelệnh (hoặc chuyển tùy chọn dưới dạng -i từ dòng lệnh). Lợi ích ở đây là biến sau đó có thể được sử dụng có hoặc không có tiền tố hivevar và cho phép một cái gì đó tương tự như sử dụng toàn cầu và cục bộ.

Vì vậy, giả sử có một số setup.hql đặt biến tên bảng:

set hivevar:tablename=mytable;

sau đó, tôi có thể đưa vào tổ ong:

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

và sử dụng trong truy vấn:

hive> select * from ${tablename}

hoặc là

hive> select * from ${hivevar:tablename}

Tôi cũng có thể đặt tên bảng "cục bộ", tên này sẽ ảnh hưởng đến việc sử dụng $ {tablename}, nhưng không ảnh hưởng đến $ {hivevar: tablename}

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

vs

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

Có lẽ không có ý nghĩa quá nhiều từ CLI, nhưng có thể có hql trong tệp sử dụng nguồn , nhưng hãy đặt một số biến "cục bộ" để sử dụng trong phần còn lại của tập lệnh.


1
Điều này đang truyền một tham số từ dòng lệnh Tôi đang phát triển các truy vấn trong Karmasphere và cần thiết lập một số nội dung trong trường hợp cầu xin để tôi không viết mã ngày 10 lần trong tập lệnh của mình. Một cái gì đó như vậy có thể?
user1678312

làm việc cả hai cách, nếu bạn làm set CURRENT_DATE='2012-09-16';bạn có thể tham khảo nó sau này với${hiveconf:CURRENT_DATE}
libjack

1
Điều này hoạt động như thế nào nếu tôi có nhiều công việc Hive chạy đồng thời? Liệu cuối cùng họ có nhận các giá trị từ nhau không? Trong tự động hóa, tôi đang xây dựng một tệp HQL bằng cách thêm nó với một số câu lệnh SET. Tôi muốn đảm bảo rằng nếu tôi gửi đồng thời hai công việc sử dụng cùng một tên biến, một công việc sẽ không nhận giá trị từ công việc kia. Ngữ nghĩa ở đây không rõ ràng từ câu trả lời của bạn.
MattD

5
điều này phù hợp với tôi trên máy chủ Hive. Tuy nhiên, tôi đã thiết lập một số kiểm tra tích hợp trên máy cục bộ trong IntelliJ. Tôi tiếp tục gặp lỗi sau khi cố gắng sử dụng biến theo cách này:FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
chepukha

1
@DatabaseCoder Theo hiểu biết của tôi, không có gì như vậy sẽ hoạt động. Bất cứ khi nào tôi cần một cái gì đó như vậy, tôi phải thực hiện truy vấn đầu tiên và sau đó chuyển qua "--hiveconf"
libjack

21

Hầu hết các câu trả lời ở đây đều gợi ý sử dụng hiveconfhoặchivevar không gian tên để lưu trữ biến. Và tất cả những câu trả lời đó đều đúng. Tuy nhiên, có một không gian tên nữa.

Có tổng cộng ba namespacesbiến số có sẵn để nắm giữ.

  1. hiveconf - hive bắt đầu với điều này, tất cả cấu hình hive được lưu trữ như một phần của conf này. Ban đầu, thay thế biến không phải là một phần của hive và khi nó được giới thiệu, tất cả các biến do người dùng định nghĩa cũng được lưu trữ như một phần của điều này. Đó chắc chắn không phải là một ý kiến ​​hay. Vì vậy, hai không gian tên khác đã được tạo.
  2. hivevar : Để lưu trữ các biến người dùng
  3. system : Để lưu trữ các biến hệ thống.

Và vì vậy nếu bạn đang lưu trữ một biến như một phần của truy vấn (tức là ngày tháng hoặc product_number), bạn nên sử dụng hivevarkhông gian tên chứ không phải không hiveconfgian tên.

Và đây là cách nó hoạt động.

hiveconf vẫn là không gian tên mặc định , vì vậy nếu bạn không cung cấp bất kỳ không gian tên nào, nó sẽ lưu trữ biến của bạn trong không gian tên hiveconf.

Tuy nhiên, khi đề cập đến một biến, điều đó không đúng. Theo mặc định, nó đề cập đến hivevar không gian tên . Khó hiểu đúng không? Nó có thể trở nên rõ ràng hơn với ví dụ sau.

Nếu bạn không cung cấp không gian tên như được đề cập bên dưới, biến varsẽ được lưu trữ trong hiveconfkhông gian tên.

set var="default_namespace";

Vì vậy, để truy cập điều này, bạn cần chỉ định hiveconf không gian tên

select ${hiveconf:var};

Và nếu bạn không cung cấp không gian tên, nó sẽ cung cấp cho bạn một lỗi như được đề cập bên dưới, lý do là theo mặc định nếu bạn cố gắng truy cập vào một biến, nó chỉ kiểm tra trong hivevarkhông gian tên. Và trong hivevarđó không có biến có tênvar

select ${var}; 

Chúng tôi đã cung cấp hivevarkhông gian tên một cách rõ ràng

set hivevar:var="hivevar_namespace";

vì chúng tôi đang cung cấp không gian tên, điều này sẽ hoạt động.

select ${hivevar:var}; 

Và theo mặc định, không gian làm việc được sử dụng trong khi giới thiệu một biến là hivevar, vùng sau cũng sẽ hoạt động.

select ${var};

7

Bạn đã thử sử dụng ký hiệu đô ladấu ngoặc như thế này chưa:

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

Đây là câu trả lời làm việc duy nhất cho tôi. Các báo giá được yêu cầu trong giao diện ambari hive của tôi.
Laurens Koppenol

có hai điều hivevar và hiveconf- cả được giải thích một cách chi tiết ở đây
Rahul Sharma

3

Hai cách dễ dàng:

Sử dụng hive conf

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

Sử dụng hive vars

Trên CLI của bạn đặt các vars và sau đó sử dụng chúng trong tổ ong

set hivevar:USER_NAME='FOO';

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

Tài liệu: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution


2

Một điều cần lưu ý là thiết lập các chuỗi sau đó tham chiếu trở lại chúng. Bạn phải đảm bảo rằng các câu trích dẫn không đụng nhau.

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

Khi đặt ngày, hãy đề cập đến chúng trong mã vì các chuỗi có thể xung đột. Điều này sẽ không hoạt động với bộ start_date ở trên.

 '${hiveconf:start_date}'

Chúng tôi phải lưu ý không đặt hai lần dấu ngoặc kép đơn hoặc kép cho các chuỗi khi tham chiếu trở lại chúng trong truy vấn.


2

Chỉ trong trường hợp ai đó cần tham số hóa truy vấn hive qua cli.

Ví dụ:

hive_query.sql

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

Bây giờ thực thi tệp sql trên từ cli:

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

0

Hãy thử phương pháp này:

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

nó hoạt động tốt trên nền tảng của tôi.


0

Bạn có thể xuất biến trong xuất tập lệnh shell CURRENT_DATE = "2012-09-16"

Sau đó, trong hiveql, bạn thích SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'


-7

Bạn có thể lưu trữ kết quả đầu ra của một truy vấn khác trong một biến và sau đó bạn có thể sử dụng kết quả tương tự trong mã của mình:

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

Bạn đã nhầm, chọn count (*) từ My_table; sẽ được lưu trữ trong var .
Ilya Bystrov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.