在使用hive开发数据分析代码时,经常会遇到需要改变运行参数的情况,比如select语句中对日期字段值的设定,可能不同时间想要看不同日期的数据,这就需要能动态改变日期的值。如果开发量较大、参数多的话,使用变量来替代原来的字面值非常有必要,本文总结了几种可以向hive的SQL中传入参数的方法,以满足类似的需要。

准备测试表和测试数据

第一步先准备测试表和测试数据用于后续测试:

 
 
1
2
3
hive> create database test;
OK
Time taken: 2.606 seconds

然后执行建表和导入数据的sql文件:

 
 
1
2
3
4
5
6
7
8
9
10
11
[czt@www.crazyant.net testHivePara]$ hive -f student.sql
Hive history file=/tmp/crazyant.net/hive_job_log_czt_201309131615_1720869864.txt
OK
Time taken: 2.131 seconds
OK
Time taken: 0.878 seconds
Copying data from file:/home/users/czt/testdata_student
Copying file: file:/home/users/czt/testdata_student
Loading data to table test.student
OK
Time taken: 1.76 seconds

其中student.sql内容如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use test;
 
---学生信息表
create table IF NOT EXISTS student(
sno bigint comment '学号' ,
sname string comment '姓名' ,
sage bigint comment '年龄' ,
pdate string comment '入学日期'
)
COMMENT '学生信息表'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
 
LOAD DATA LOCAL INPATH
'/home/users/czt/testdata_student'
INTO TABLE student;

testdata_student测试数据文件内容如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
1 name1 21 20130901
2 name2 22 20130901
3 name3 23 20130901
4 name4 24 20130901
5 name5 25 20130902
6 name6 26 20130902
7 name7 27 20130902
8 name8 28 20130902
9 name9 29 20130903
10 name10 30 20130903
11 name11 31 20130903
12 name12 32 20130904
13 name13 33 20130904

方法1:shell中设置变量,hive -e中直接使用

测试的shell文件名:

 
 
1
2
3
4
5
#!/bin/bash
tablename="student"
limitcount="8"
 
hive -S -e "use test; select * from ${tablename} limit ${limitcount};"

运行结果:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
[czt@www.crazyant.net testHivePara]$ sh -x shellhive.sh
+ tablename=student
+ limitcount=8
+ hive -S -e 'use test; select * from student limit 8;'
1       name1    21      20130901
2       name2    22      20130901
3       name3    23      20130901
4       name4    24      20130901
5       name5    25      20130902
6       name6    26      20130902
7       name7    27      20130902
8       name8    28      20130902

由于hive自身是类SQL语言,缺乏shell的灵活性和对过程的控制能力,所以采用shell+hive的开发模式非常常见,在shell中直接定义变量,在hive -e语句中就可以直接引用;

注意:使用-hiveconf定义,在hive -e中是不能使用的

修改一下刚才的shell文件,采用-hiveconf的方法定义日期参数:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
tablename="student"
limitcount="8"
 
hive -S \
    -hiveconf enter_school_date="20130902" \
    -hiveconf min_age="26" \
    -e \
    "    use test; \
        select * from ${tablename} \
        where \
            pdate='${hiveconf:enter_school_date}' \
            and \
            sage>'${hiveconf:min_age}' \
        limit ${limitcount};"

运行会失败,因为该脚本在shell环境中运行的,于是shell试图去解析${hiveconf:enter_school_date}和${hiveconf:min_age}变量,但是这两个SHELL变量并没有定义,所以会以空字符串放在这个位置。

运行时该SQL语句会被解析成下面这个样子:

 
 
1
+ hive -S -hiveconf enter_school_date=20130902 -hiveconf min_age=26 -e 'use test; explain select * from student where pdate='\'''\'' and sage>'\'''\'' limit 8;'

方法2:使用-hiveconf定义,在SQL文件中使用

因为换行什么的很不方便,hive -e只适合写少量的SQL代码,所以一般都会写很多hql文件,然后使用hive –f的方法来调用,这时候可以通过-hiveconf定义一些变量,然后在SQL中直接使用。

先编写调用的SHELL文件:

 
 
1
2
3
#!/bin/bash
 
hive -hiveconf enter_school_date="20130902" -hiveconf min_ag="26" -f testvar.sql

被调用的testvar.sql文件内容:

 
 
1
2
3
4
5
6
7
8
use test;
 
select * from student
where
pdate='${hiveconf:enter_school_date}'
and
sage > '${hiveconf:min_ag}'
limit 8;

执行过程:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[czt@www.crazyant.net testHivePara]$ sh -x shellhive.sh
+ hive -hiveconf enter_school_date=20130902 -hiveconf min_ag=26 -f testvar.sql
Hive history file=/tmp/czt/hive_job_log_czt_201309131651_2035045625.txt
OK
Time taken: 2.143 seconds
Total MapReduce jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Kill Command = hadoop job -kill job_20130911213659_42303
2013-09-13 16:52:00,300 Stage-1 map = 0%,  reduce = 0%
2013-09-13 16:52:14,609 Stage-1 map = 28%,  reduce = 0%
2013-09-13 16:52:24,642 Stage-1 map = 71%,  reduce = 0%
2013-09-13 16:52:34,639 Stage-1 map = 98%,  reduce = 0%
Ended Job = job_20130911213659_42303
OK
7       name7   27      20130902
8       name8   28      20130902
Time taken: 54.268 seconds

hive 传递变量的两种方式的更多相关文章

  1. 向docker镜像中传递变量的两种方式

    测试用到的python文件: #!/usr/bin/env python3 #conding: utf-8 from http.server import HTTPServer, BaseHTTPRe ...

  2. C++函数传递数组的两种方式

    数组与指针. 传首地址过去,然后通过地址输出数组元素. 1.一维数组 #include<iostream> using namespace std; #include <cstrin ...

  3. smarty获取变量的两种方式

    从上一篇随笔中,我们知道smarty可以通过assign()的方法注册变量,从而在前段读取变量:我们也可以从配置文件中获取变量,来具体看一下: 1.在configs文件夹中建一个test.conf文件 ...

  4. 【linux】linux 下 shell命令 执行结果赋值给变量【两种方式】

    方法1:[通用方法] 使用Tab键上面的反引号 例子如下: find命令 模糊查询在/apps/swapping目录下 查找 文件名中包含swapping并且以.jar结尾的文件 使用反引号 引住命令 ...

  5. Spring使用JMS传递消息的两种方式

    方式一:同步收发消息,使用JMS template 消费者阻塞等待消息的到来. 方式二:异步收发消息,使用message listener container 消费者提供一个listener,注册一个 ...

  6. hibernate createQuery查询传递参数的两种方式

    String hql = "from InventoryTask it where it.orgId=:orgId"; Session session = getSession() ...

  7. 第一课:Centos下配置java环境变量的两种方式(jdk1.8)

    配置java环境(yum安装) 1.查出java1.8的全部版本 yum list java-1.8* 2.安装你需要的java1.8 版本(安装的名字根据查询出来的结果输入这里只是举例) yum i ...

  8. mybatis 传递参数的两种方式与模糊匹配 很重要

  9. Laravel向视图传递变量的两种方法

    //方法一 return view('home.user')->with('datas', $datas); //方法二 return view('home.user.my-indent',co ...

随机推荐

  1. lintcode:合并两个排序链表

    题目: 合并两个排序链表 将两个排序链表合并为一个新的排序链表  样例 给出 1->3->8->11->15->null,2->null, 返回 1->2-& ...

  2. PHP中的多态

    多态的概念一般是强类型语言来谈的,因为强类型语言它必须要声明参数类型,比如一个手电筒对象的打开方法其参数申明了只能是蓝光,就不能传其他光.但可以用父类渲染的方式使其多态,比如声明一个光的父类,让其它颜 ...

  3. PHP获取服务器的mac地址类

    PHP获取服务器的mac地址类,不是客户端的. <?php class GetMacAddr{ var $return_array = array(); // 返回带有MAC地址的字串数组 va ...

  4. qtp与selenium2的区别

    QTP:  我觉得qtp适合的人: 对编程不是很熟悉的 厌烦了手动的功能测试,想快速进入自动化行业的 公司想快速自动化项目,并且对价格或者对盗版无所谓的 vbs脚本语言易于上手,可以培训你对代码的兴趣 ...

  5. sql 随笔 2015-07-02

    sql 自定义函数 --检查函数是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'dbo.pTitleCase') ...

  6. objectC时间用法

    #define kDEFAULT_DATE_TIME_FORMAT (@"yyyy-MM-dd HH:mm:ss") //获取当前日期,时间+(NSDate *)getCurren ...

  7. Java中常见几种数据库连接方法

    1:引入java.sql数据包;   import java.sql.*; 2:加载JDBC驱动程序   Class.forName(JDBC驱动包的名字).newInstance(); 3:产生Co ...

  8. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  9. JVM 问题排查常用工具

    一. jmap // 打印jvm的堆状况,主要是年轻代和老年代信息 jmap -heap <pid> 如: Heap Configuration: MinHeapFreeRatio = M ...

  10. POJ 2828 Buy Tickets (线段树 单点更新 变形)

    题目链接 题意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列. 分析:因为之前的序列会因为插队而变化,如果直接算时间复杂度很高,所以可以用 线段树逆序插入,把序列都插到最后一层,le ...