Hive Procedural SQL
Posted 一木呈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive Procedural SQL相关的知识,希望对你有一定的参考价值。
1 Hive Procedural SQL特点概述
Hive 1.0版本中没有提供类似存储过程的功能,使用Hive做数据开发时候,一般是将一段一段的HQL语句封装在Shell或者其他脚本中,然后以命令行的方式调用,完成一个业务或者一张报表的统计分析。与Bash脚本、Java、Python或Scala程序相比,hpl/sql对于bi/sql开发人员来说是简洁、易读和可维护的。
hpl/sql试图尽可能地支持所有广泛使用的过程语言的语法。不需要从头开始学习一种新的过程语言。这促进了新代码的开发以及将现有代码库迁移到Hadoop。
hpl/sql允许使用变量、表达式、流控制语句和迭代实现业务逻辑。hpl/sql支持使用异常和条件处理程序的错误处理。可以开发管理和控制分布式过程的程序,但同时也不是系统的瓶颈。
hpl/SQL的一个关键特性是它允许使SQL更加动态。可以使用高级表达式,各种内置的函数,根据用户配置动态生成SQL,以前查询的结果,来自文件或非hadoop数据源的数据等等。
传统上,数据库管理系统提供程序SQL语言,广泛用于实现高级数据操作场景和工作流。这种方法对于数据库开发人员和数据分析人员来说是简单而熟悉的。与Python相比,Java或Linux shell脚本,HPL / SQL允许Hadoop BI分析人员和开发人员的更广泛的受众。
Hadoop扩展了使用RDBMS产品构建的传统数据仓库。这意味着您必须集成多个系统,包括Hadoop、RDBMS、NoSQL和其他系统。hpl/sql允许您在一个脚本中使用多个系统,因此可以为不同类型的工作负载选择最好的所有系统,并轻松地集成它们。
2 配置HPL/SQL与Hive的连接
创建Hplsql连接初始化文件$HIVE_HOME/conf/hplsql-site.xml(前提已开启hiveserver2服务)
<configuration> <property> <name>hplsql.conn.default</name> <value>hive2conn</value> <description>The default connection profile</description> </property>
<property> <name>hplsql.conn.convert.hive2conn</name> <value>true</value> </property>
<property> <name>hplsql.conn.hive2conn</name> <value>org.apache.hive.jdbc.HiveDriver;jdbc:hive2://hadoop002:10000;hadoop;bonchadoop</value> </property>
<property> <name>hplsql.conn.init.hive2conn</name> <value> sethive.execution.engine=mr; usedefault; </value> </property> </configuration> |
3 hplsql使用
3.1 基本cli命令
hplsql -e 'query' | -f file
[-mainprocname]只执行指定函数或存储过程
[-d | --define | -hiveconf | -hivevar var=value ...]
[-version | --version]
[-trace| --trace] 打印debug信息
[-H |--help]
-d,--define,-hivevar和-hiveconf是等价的,允许定义输入变量。
[hadoop@hadoop-2 conf]$ hplsql -e "PRINT a ||', ' || b" -d a=Hello -d b=world
Hello, world
[hadoop@hadoop-2 ~]$ more script.sql
desc test;
[hadoop@hadoop-2 ~]$ hplsql -f script.sql
Open connection: jdbc:hive2://hadoop002:10000 (569 ms)
Starting SQL statement
SQL statement executed successfully (107 ms)
name string 姓名
age int 年龄
3.2 多连接
hpl/sql允许您从单个hpl/sql脚本同时访问多个数据库。使用Hive或其他sql-on-hadoop工具来查询数据时,您可以使用RDBMS或NoSQL:
写入日志和审计记录
访问查询维度表
读取和写入配置参数
保存查询结果等等。
备注:HQL/SQL支持关系型数据库类型包括:DB2、mysql、TeraData、Oracle、PostgreSQL、Netezza6种
配置:
确保JDBC驱动程序jar在类路径中,在$HIVE_HOME/conf/hplsql-site.xml增加连接配置
<value>JDBC Driver;JDBC ConnectionString;User;Password</value>
<property>
<name>hplsql.conn.mysqlconn</name>
<value>com.mysql.jdbc.Driver;jdbc:mysql://hadoop002/test;hadoop;hadoop</value>
</property>
例如,可以在Hive中运行SELECT,但是将消息记录到MySQL
Hplsql脚本:
默认情况下,hpl/sql使用hplsql.conn.default选项定义的连接配置文件。一旦配置了多个连接配置文件,就可以使用映射对象语句将一个表或视图映射到指定的连接。当访问SQL语句时,hpl/SQL将使用适当的连接对象:
[hadoop@hadoop-2 ~]$ more script.sql
MAP OBJECT log TO test.log_data AT mysqlconn;
DECLARE cnt INT;
SELECT count(*) INTO cnt FROM test.trlog WHEREplatform = "WEB";
INSERT INTO log (message) VALUES ('Number of users:' || cnt);
执行:
[hadoop@hadoop-2 ~]$ hplsql -f script.sql
which: no hbase in(/opt/beh/core/hive/bin:/opt/beh/core/hadoop/bin:/opt/beh/core/hadoop/sbin:/opt/beh/core/zookeeper/bin:/opt/beh/core/jdk8/bin:/opt/beh/core/jdk8/jre/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mysql/bin:/home/hadoop/.local/bin:/home/hadoop/bin)
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in[jar:file:/opt/beh/core/hive/lib/log4j-slf4j-impl-2.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in[jar:file:/opt/beh/core/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings foran explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Open connection: jdbc:hive2://hadoop002:10000 (512 ms)
Starting query
Query executed successfully (24.71 sec)
Fri Mar 09 17:20:23 CHOT 2018 WARN: Establishing SSL connectionwithout server's identity verification is not recommended. According to MySQL5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established bydefault if explicit option isn't set. For compliance with existing applicationsnot using SSL the verifyServerCertificate property is set to 'false'. You needeither to explicitly disable SSL by setting useSSL=false, or set useSSL=trueand provide truststore for server certificate verification.
Open connection: jdbc:mysql://hadoop002/test (343 ms)
Starting SQL statement
SQL statement executed successfully (14 ms)
3.3 定义函数和过程
3.3.1在当前脚本中定义函数和过程
使用hpl/sql函数和过程的最简单方法是在实际使用之前在当前脚本中定义它们。(String参数使用单引号)
[hadoop@hadoop-2 ~]$ vi script.sql
CREATE FUNCTION hello(text STRING)
RETURNSSTRING
BEGIN
RETURN'Hello, ' || text || '!';
END;
CREATE PROCEDURE set_message(IN name STRING, OUTresult STRING)
BEGIN
SET result ='Hello, ' || name || '!';
END;
-- Invoke the function
PRINT hello('world');
-- Call the procedure and print the results
DECLARE str STRING;
CALL set_message('world', str);
PRINT str;
执行:
[hadoop@hadoop-2 ~]$ hplsql -f script.sql
which: no hbase in(/opt/beh/core/hive/bin:/opt/beh/core/hadoop/bin:/opt/beh/core/hadoop/sbin:/opt/beh/core/zookeeper/bin:/opt/beh/core/jdk8/bin:/opt/beh/core/jdk8/jre/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mysql/bin:/home/hadoop/.local/bin:/home/hadoop/bin)
Hello, world!
Hello, world!
3.3.2永久函数和存储过程
hpl/sql允许在hpl/sql脚本之间共享函数和过程,因此不需要将它们的内容放到每个脚本中。与传统数据库不同,hpl/sql将它们存储在本地文件中。
可以将函数和过程放到.hplsqlrc文件中。当启动hplsql工具时,该文件的内容会自动执行。hplsqlrc文件是从执行目录加载的
[hadoop@hadoop-2 ~]$ more .hplsqlrc
CREATE FUNCTION testrc()
RETURNSSTRING
BEGIN
RETURN 'thefunction testrc successful invoke!';
END;
执行之前的脚本末尾加上:PRINTtestrc()
[hadoop@hadoop-2 ~]$ hplsql -f ~/script.sql
which: no hbase in (/opt/beh/core/hive/bin:/opt/beh/core/hadoop/bin:/opt/beh/core/hadoop/sbin:/opt/beh/core/zookeeper/bin:/opt/beh/core/jdk8/bin:/opt/beh/core/jdk8/jre/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mysql/bin:/home/hadoop/.local/bin:/home/hadoop/bin)
Hello, world!
Hello, world!
the function testrc successful invoke!
INCLUDE statement INCLUDE语句声明
使用INCLUDE语句,您可以从任何文件加载函数和过程定义。注意,还可以在.hplsqlrc文件中使用INCLUDE语句。
[hadoop@hadoop-2 ~]$ more/home/hadoop/cdy/hplsqlrc.sql
CREATE FUNCTION includerc()
RETURNSSTRING
BEGIN
RETURN 'thefunction includerc successful invoke!';
END;
[hadoop@hadoop-2 ~]$ more script.sql
INCLUDE /home/hadoop/cdy/hplsqlrc.sql;
PRINT includerc()
[hadoop@hadoop-2 ~]$
[hadoop@hadoop-2 ~]$ hplsql -f ~/script.sql
which: no hbase in(/opt/beh/core/hive/bin:/opt/beh/core/hadoop/bin:/opt/beh/core/hadoop/sbin:/opt/beh/core/zookeeper/bin:/opt/beh/core/jdk8/bin:/opt/beh/core/jdk8/jre/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mysql/bin:/home/hadoop/.local/bin:/home/hadoop/bin)
the function includerc successful invoke!
3.3.3在Hive查询中使用hpl/sql用户定义函数
hpl/sql包含一个Hive UDF函数,它允许在Hive查询中执行hpl/sql脚本(用户定义的函数,用hpl/sql语言编写)。
例如:
[hadoop@hadoop-2 ~]$ more hplsqludf
CREATE FUNCTION hello(text STRING)
RETURNSSTRING
BEGIN
RETURN'Hello, ' || text || '!';
END;
在Hive中注册hpl/sql UDF(jar和配置文件以及该文件的路径):
ADD JAR /opt/beh/core/hive/lib/hive-hplsql-2.3.2.jar;
ADD JAR /opt/beh/core/hive/lib/antlr-runtime-3.5.2.jar;
ADD FILE /opt/beh/core/hive/conf/hplsql-site.xml;;
ADD FILE /home/hadoop/hplsqludf;
CREATE TEMPORARY FUNCTIONhplsql AS 'org.apache.hive.hplsql.Udf';
3.4 动态sql转换
hpl/sql支持许多过程性方言,允许在不更改的情况下重用现有的代码。
例如:
IF code = 'A' THEN
CREATETABLE dept
(
deptnoNUMBER(2,0),
dname NUMBER(14),
loc VARCHAR2(13),
CONSTRAINT pk_dept PRIMARY KEY (deptno)
);
END IF;
在本例中,IF语句是由pl/hql本身执行的。它检查代码变量的值,如果它等于'A',hpl/sql将执行CREATE TABLE语句。hpl/sql不能执行CREATE TABLE,该语句必须被发送到数据库,以创建一个可访问其他会话的物理持久表。但是,可以看到CREATE TABLE的语法不符合Hive,它使用NUMBER和VARCHAR2数据类型以及约束。
下面是动态SQL转换的作用。在将CREATE TABLE语句发送到Hive之前,hpl/sql将其转换为:
CREATE TABLE dept
(
deptnoDECIMAL(2,0),
dname DECIMAL(14),
loc STRING
);
3.4.1数据类型转换
在CREATE TABLE语句中的数据类型转换:
Source |
Hive SQL |
BIT |
TINYINT |
DATETIME |
TIMESTAMP |
INT(n) |
INT |
INT2 |
SMALLINT |
INT4 |
INT |
INT8 |
BIGINT |
NCHAR(n) |
STRING |
NVARCHAR(n) |
STRING |
NUMBER(p,s) |
DECIMAL(p,s) |
NUMERIC(p,s) |
DECIMAL(p,s) |
TEXT |
STRING |
VARCHAR(MAX) |
STRING |
VARCHAR2(n) |
STRING |
3.4.2操作符的转换
SQL DDL和DML语句中的语言元素和操作符的转换:
Source |
Hive SQL |
|
“identifier”, [identifier] |
Identifier |
`identifier` |
dbo, [dbo] |
Schema name |
Removed |
expr || expr2 || ... |
String concatenation |
CONCAT(expr, expr2, ...) |
3.4.3函数转换
在可执行SQL语句中转换内置的SQL函数:
Source |
Hive SQL |
CURRENT_DATE |
TO_DATE(FROM_UNIXTIME(UNIX_TIMESTAMP())) |
CURRENT DATE |
|
CURRENT_TIMESTAMP |
FROM_UNIXTIME(UNIX_TIMESTAMP()) |
CURRENT TIMESTAMP |
3.4.4sql语句转换
Source |
Hive SQL |
|
SELECT TOP n … FROM … |
Row limit |
SELECT … FROM … LIMIT n |
FROM TABLE (VALUES … ) clause |
Row constructor |
SELECT UNION ALL subquery |
DELETE FROM table ALL |
TRUNCATE TABLE table |
SET CURRENT SCHEMA = name |
USE name |
3.5 HPL / SQL错误处理
hpl/sql允许使用异常、条件处理程序和错误代码来处理错误。Hplsql.onerror配置选项定义了hpl/sql如何处理当前会话中的错误。它接受以下值:
Exception (default)
在这种情况下,当出现错误时,hpl/sql会引发异常。如果这个错误有一个异常或条件处理程序,它将被执行。
Seterror
当指定了Seterror时,hpl/sql将错误代码设置为SQLCODE、ERRORCODE和HOSTCODE(用于OS命令)变量并继续执行。您可以使用IF语句来检查错误。
Stop
hpl/sql停止执行脚本和退出。
注意可以动态地更改Hplsql.onerror。在脚本中执行SET语句的onerror选项:
SET hplsql.onerror = exception | seterror | stop;
参考:http://www.hplsql.org/error-handling
以上是关于Hive Procedural SQL的主要内容,如果未能解决你的问题,请参考以下文章