Hive Procedural SQL

Posted 一木呈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive Procedural SQL相关的知识,希望对你有一定的参考价值。

1 Hive Procedural SQL特点概述

  • Hive 1.0版本中没有提供类似存储过程的功能,使用Hive做数据开发时候,一般是将一段一段的HQL语句封装在Shell或者其他脚本中,然后以命令行的方式调用,完成一个业务或者一张报表的统计分析。与Bash脚本、JavaPythonScala程序相比,hpl/sql对于bi/sql开发人员来说是简洁、易读和可维护的。

  • hpl/sql试图尽可能地支持所有广泛使用的过程语言的语法。不需要从头开始学习一种新的过程语言。这促进了新代码的开发以及将现有代码库迁移到Hadoop

  • hpl/sql允许使用变量、表达式、流控制语句和迭代实现业务逻辑。hpl/sql支持使用异常和条件处理程序的错误处理。可以开发管理和控制分布式过程的程序,但同时也不是系统的瓶颈。

  • hpl/SQL的一个关键特性是它允许使SQL更加动态。可以使用高级表达式,各种内置的函数,根据用户配置动态生成SQL,以前查询的结果,来自文件或非hadoop数据源的数据等等。

  • 传统上,数据库管理系统提供程序SQL语言,广泛用于实现高级数据操作场景和工作流。这种方法对于数据库开发人员和数据分析人员来说是简单而熟悉的。与Python相比,JavaLinux shell脚本,HPL / SQL允许Hadoop BI分析人员和开发人员的更广泛的受众。

  • Hadoop扩展了使用RDBMS产品构建的传统数据仓库。这意味着您必须集成多个系统,包括HadoopRDBMSNoSQL和其他系统。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工具来查询数据时,您可以使用RDBMSNoSQL

  • 写入日志和审计记录

  • 访问查询维度表

  • 读取和写入配置参数

  • 保存查询结果等等。

备注:HQL/SQL支持关系型数据库类型包括:DB2mysqlTeraDataOraclePostgreSQLNetezza6

配置:

确保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 UDFjar和配置文件以及该文件的路径):

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,它使用NUMBERVARCHAR2数据类型以及约束。

下面是动态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 DDLDML语句中的语言元素和操作符的转换:

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将错误代码设置为SQLCODEERRORCODEHOSTCODE(用于OS命令)变量并继续执行。您可以使用IF语句来检查错误。

  • Stop

hpl/sql停止执行脚本和退出。

注意可以动态地更改Hplsql.onerror。在脚本中执行SET语句的onerror选项:

SET hplsql.onerror = exception | seterror | stop;

参考:http://www.hplsql.org/error-handling

 


以上是关于Hive Procedural SQL的主要内容,如果未能解决你的问题,请参考以下文章

SQLHive SQL详解

SQL Hive - 计算前几个月的滚动 SUM、AVG

SQL Hive:选择 (*) LIMIT 1 基于 3 列的组合,R 中的联合,RODBC

Hive MetaStore Upgrade

如何添加计数以对 SQL Hive 中的空值进行排名?

XJCO1711 Procedural Programming