ฉันกำลังมองหา SQL ที่เทียบเท่าSET varname = value
ใน Hive QL
ฉันรู้ว่าฉันสามารถทำสิ่งนี้ได้:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
แต่แล้วฉันก็ได้รับข้อผิดพลาดนี้:
ที่นี่ไม่รองรับอักขระ "@"
ฉันกำลังมองหา SQL ที่เทียบเท่าSET varname = value
ใน Hive QL
ฉันรู้ว่าฉันสามารถทำสิ่งนี้ได้:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
แต่แล้วฉันก็ได้รับข้อผิดพลาดนี้:
ที่นี่ไม่รองรับอักขระ "@"
คำตอบ:
คุณต้องใช้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 แล้วเช่นกันโดยใส่ไว้ใน hql snippets ที่ฉันสามารถรวมจาก hive CLI โดยใช้source
คำสั่ง (หรือผ่านตัวเลือก -i จากบรรทัดคำสั่ง) ข้อดีคือจากนั้นตัวแปรสามารถใช้โดยมีหรือไม่มีคำนำหน้า hivevar และอนุญาตบางอย่างที่คล้ายกับการใช้งานทั่วโลกเทียบกับท้องถิ่น
ดังนั้นสมมติว่ามีsetup.hqlซึ่งตั้งค่าตัวแปร tablename:
set hivevar:tablename=mytable;
จากนั้นฉันสามารถนำเข้าสู่รัง:
hive> source /path/to/setup.hql;
และใช้ในการสืบค้น:
hive> select * from ${tablename}
หรือ
hive> select * from ${hivevar:tablename}
ฉันยังสามารถตั้งชื่อตาราง "local" ซึ่งจะส่งผลต่อการใช้ $ {tablename} แต่ไม่ใช่ $ {hivevar: tablename}
hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'
เทียบกับ
hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'
อาจไม่ได้หมายความว่ามากเกินไปจาก CLI แต่สามารถมี hql ในไฟล์ที่ใช้ซอร์สได้ แต่ตั้งค่าตัวแปรบางตัว "ในเครื่อง" เพื่อใช้ในส่วนที่เหลือของสคริปต์
set CURRENT_DATE='2012-09-16';
สามารถอ้างอิงได้ในภายหลังด้วย${hiveconf:CURRENT_DATE}
FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
คำตอบส่วนใหญ่ที่นี่แนะนำให้ใช้hiveconf
หรือhivevar
เนมสเปซเพื่อเก็บตัวแปร และคำตอบทั้งหมดนั้นถูกต้อง อย่างไรก็ตามยังมีอีกหนึ่งเนมสเปซ
มีทั้งหมดสามnamespaces
ตัวแปรสำหรับการถือครอง
ดังนั้นหากคุณจัดเก็บตัวแปรเป็นส่วนหนึ่งของแบบสอบถาม (เช่นวันที่หรือหมายเลขผลิตภัณฑ์) คุณควรใช้hivevar
เนมสเปซไม่ใช่hiveconf
เนมสเปซ
และนี่คือวิธีการทำงาน
hiveconfยังคงเป็นเนมสเปซเริ่มต้นดังนั้นหากคุณไม่ระบุเนมสเปซใด ๆ ระบบจะเก็บตัวแปรของคุณไว้ในเนมสเปซของ hiveconf
อย่างไรก็ตามเมื่อพูดถึงตัวแปรนั้นไม่เป็นความจริง โดยค่าเริ่มต้นหมายถึงเนมสเปซแบบไฮเววาร์ สับสนใช่มั้ย? จะชัดเจนขึ้นด้วยตัวอย่างต่อไปนี้
หากคุณไม่ได้ระบุเนมสเปซตามที่ระบุไว้ด้านล่างตัวแปรvar
จะถูกเก็บไว้ในhiveconf
เนมสเปซ
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};
คุณได้ลองใช้เครื่องหมายดอลลาร์และวงเล็บดังนี้:
SELECT *
FROM foo
WHERE day >= '${CURRENT_DATE}';
สองวิธีง่ายๆ:
ใช้ hive conf
hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';
การใช้ hive vars
ใน CLI ของคุณตั้งค่า vars แล้วใช้ในกลุ่ม
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
สิ่งหนึ่งที่ควรคำนึงถึงคือการตั้งค่าสตริงแล้วอ้างอิงกลับมา คุณต้องแน่ใจว่าเครื่องหมายคำพูดไม่ชนกัน
set start_date = '2019-01-21';
select ${hiveconf:start_date};
เมื่อตั้งค่าวันที่แล้วให้อ้างถึงในรหัสเนื่องจากสตริงอาจขัดแย้งกัน สิ่งนี้ใช้ไม่ได้กับ start_date ที่ตั้งไว้ด้านบน
'${hiveconf:start_date}'
เราต้องจำไว้ว่าอย่าตั้งอัญประกาศสองครั้งเดี่ยวหรือสองครั้งสำหรับสตริงเมื่ออ้างถึงกลับไปในข้อความค้นหา
ในกรณีที่มีคนต้องการกำหนดพารามิเตอร์การสืบค้นแบบรังผ่าน cli
เช่น:
hive_query.sql
SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'
ตอนนี้เรียกใช้ไฟล์ sql ด้านบนจาก cli:
hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
ลองใช้วิธีนี้:
set t=20;
select *
from myTable
where age > '${hiveconf:t}';
มันทำงานได้ดีบนแพลตฟอร์มของฉัน
คุณสามารถส่งออกตัวแปรในการส่งออกเชลล์สคริปต์ CURRENT_DATE = "2012-09-16"
จากนั้นใน hiveql คุณชอบ SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'
คุณสามารถจัดเก็บผลลัพธ์ของแบบสอบถามอื่นในตัวแปรและหลังคุณสามารถใช้สิ่งเดียวกันนี้ในโค้ดของคุณ:
set var=select count(*) from My_table;
${hiveconf:var};