本帖最后由 zhuqitian 于 2017-3-6 10:01 编辑
问题:如何在使用hive -f时传参到脚本中,不用硬编码
办法1:
hive0.9以及之前的版本是不支持传参的
hive1.0版本之后支持 hive -f 传递参数
先创建个test.hql文件
[mw_shl_code=sql,true]select * from ods.tracklog where day='${hiveconf:day}' and requesturl like '%${hiveconf:url}%' limit 10;[/mw_shl_code]
调用命令:
[mw_shl_code=sql,true]hive -hiveconf day=20161101 -hiveconf url=baidu.com -f test.hql[/mw_shl_code]
办法2:封装jar包
[mw_shl_code=java,true]package com.adtime.hiveF.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
/**
* 获取sql,并替换参数
* @author 圣斗士宙斯
*
*/
public class Utils
{
public static final String BEGIN = "${";
public static final String END = "}";
public static String getSql(File file) throws FileNotFoundException {
FileReader fr = null;
try {
fr = new FileReader(file);
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
BufferedReader bf = new BufferedReader(fr);
StringBuffer sqlBuffer = new StringBuffer();
String temp = null;
try {
while ((temp = bf.readLine()) != null) {
String tmp = temp.trim();
if ((tmp.length() != 0) && (!tmp.startsWith("#")) && (!tmp.startsWith("--"))){
sqlBuffer.append(tmp + " ");
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
bf.close();
} catch (IOException e) {
e.printStackTrace();
}
return sqlBuffer.toString();
}
/**
* 接受getSql()的返回值,用Parse()替换参数
* @param sql
* @param map
* @return
*/
public static String parse(String sql, Map<String, String> map)
{
int begin = sql.indexOf(BEGIN);
while (begin != -1)
{
String suffix = sql.substring(begin + BEGIN.length());
int end = begin + BEGIN.length() + suffix.indexOf("}");
String key = sql.substring(begin + BEGIN.length(), end).trim();
if ((map != null) && (map.get(key) != null)) {
sql = sql.substring(0, begin) + (String)map.get(key) + sql.substring(end + 1, sql.length());
}
else
{
throw new RuntimeException("Invalid Expression.....");
}
begin = sql.indexOf("${");
}
return sql;
}
}[/mw_shl_code]
==============
[mw_shl_code=java,true]package com.adtime.hiveF.parseArgs;
import java.util.HashMap;
import java.util.Map;
/**
* 循环解析多参数,put到map里,不以"-"开头就argsNumber++
* @author 圣斗士宙斯
*
*/
public class Parse {
private Map<String,String> map = null;
public Parse(String[] args){
map = new HashMap<String, String>();
if(args.length == 0){
return ;
}
int argsNumber = 0;
while (argsNumber < args.length) {
String pre = args[argsNumber].trim();
if (pre.startsWith("-")) {
String key = pre.substring(1);
argsNumber++;
String value = "";
if (args.length > argsNumber) {
value = args[argsNumber].trim();
if (args[argsNumber].startsWith("\"") || args[argsNumber].startsWith("\'")) {
value = value.substring(1,value.length() - 1);
}
}
map.put(key, value);
argsNumber++;
}else {
argsNumber++;
}
}
}
public Map<String, String> getMap() {
return map;
}
}[/mw_shl_code]
==================
[mw_shl_code=java,true]package main;
import java.io.File;
import com.adtime.hiveF.parseArgs.Parse;
import com.adtime.hiveF.util.Utils;
public class MainHive {
public static void main(String[] args) {
/*args = new String[5];
args[0] = "C:/Users/zhuqitian/Desktop/dwd_ev_pub_user_act_app_rmd.txt";
args[1] = "-date";
args[2] = "20160627";
args[3] = "-date2";
args[4] = "20160628";*/
Parse parse = new Parse(args);
String sql = null;
try {
sql = Utils.getSql(new File(args[0]));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Utils.parse(sql, parse.getMap()));
}
}[/mw_shl_code]
================shell脚本封装一个命令
[mw_shl_code=shell,true]vi /usr/bin/.hivef
#!/bin/bash
2
3 . /etc/profile
4
5 sql=`/usr/java/jdk1.8.0_91/bin/java -jar /opt/soft/hivef.jar $*`
6
7 echo "${sql}"
8
9 hive -e "${sql}"
10
11 exit 0;
chmod 111 /usr/bin/.hivef[/mw_shl_code]
讨论:大家有好的方法可以一起讨论下
暂时还有个想法:可以完善下命令:判断下命令的第一个参数是什么,
比如是2mysql,就执行一个类(或调用另一个jar包)把hive数据同步到关系型数据库
当然可以接受其他参数,比如frommysql -table -columns -where等参数,如果觉得冗杂
可以写成配置文件的形式
以上是我的个人想法,不一定啥时候实现,如果哪位提前ok了,望与我取得联系!
zhuqitian13@126.com/284678311
|
|