参考文档地址
数据类型
可以在HPL/SQL程序中使用以下数据类型:
数据类型 | 描述 |
---|---|
BIGINT / INT8 | 64位整数 |
BINARY_DOUBLE | 双精度浮点数 |
BINARY_FLOAT | 单精度浮点数 |
BINARY_INTEGER | 32位整数 |
BIT | 0、1或NULL |
BOOL / BOOLEAN | 真或假 |
CHAR(n) / CHARACTER(n) | 固定长度字符串 |
DECIMAL(p,s) | 定点数 |
DATE | 日期(年、月和日) |
DATETIME | 日期和时间 |
DOUBLE / DOUBLE PRECISION | 双精度浮点数 |
FLOAT | 单精度浮点数 |
INT / INTEGER / INT4 | 32位整数 |
NCHAR(n) | 固定长度字符串 |
NVARCHAR(n) | 变长字符串 |
NUMERIC(p,s) | 定点数 |
NUMBER(p,s) | 定点数 |
PLS_INTEGER | 32位整数 |
REAL | 单精度浮点数 |
RECORD | 任意记录 |
SIMPLE_DOUBLE | 双精度浮点数 |
SIMPLE_FLOAT | 单精度浮点数 |
SIMPLE_INTEGER | 32位整数 |
SMALLINT / INT2 | 16位整数 |
SYS_REFCURSOR | 游标变量 |
TIMESTAMP | 日期和时间 |
TINYINT | 8位整数 |
VARCHAR(n) / VARCHAR(max) | 变长字符串 |
VARCHAR2(n) | 变长字符串 |
UTL_FILE.FILE_TYPE | 文件句柄 |
数据类型转换
如果CREATE TABLE包含Hive不支持的数据类型,HPL/SQL会自动进行转换。
目前,HPL/SQL执行以下转换:
来源 | 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 |
语法声明
可以使用 DECLARE 块或语句来声明变量。
请注意,可以在单个程序中混合使用这两种语法。DECLARE 块和语句可以出现在程序的任何部分。
DECLARE 块
DECLARE 块具有以下语法:
sql
DECLARE
var 数据类型 [NOT NULL] [:= | = | 默认表达式];
...
BEGIN
...
END;
HPL/SQL 还允许定义一个常量:
sql
var 常量 数据类型 := | 默认表达式
示例:
sql
DECLARE
code CHAR(10);
status INT := 1;
count SMALLINT = 0;
limit INT 默认 100;
max_limit 常量 INT := 1000;
END;
兼容性: 声明块语法类似于 Oracle PL/SQL、PostgreSQL PL/pgSQL 和 Netezza NZPLSQL。
DECLARE 语句
DECLARE 语句具有以下语法:
sql
DECLARE var [, var2, ...] [AS] 数据类型 [:= | = | 默认表达式] [, ...];
示例:
sql
DECLARE code CHAR(10);
DECLARE status, status2 INT 默认 1;
DECLARE count SMALLINT, limit INT 默认 100;
兼容性: 声明语句语法类似于 IBM DB2 SQL PL、Teradata、Microsoft SQL Server Transact-SQL 和 MySQL。
赋值
可以使用赋值运算符或语句在HPL/SQL中为变量设置新值。
如果在赋值之前没有明确声明变量,则会创建一个新变量,并且其数据类型将从赋值表达式中推导出来。
赋值运算符
可以使用赋值运算符 := 或 = 来设置值。
语法:
sql
var [:= | = ] 表达式;
示例:
sql
code := 'A';
status := 1;
count = 0;
兼容性: Oracle PL/SQL、PostgreSQL PL/pgSQL 和 Netezza NZPLSQL。
版本: PL/HQL 0.01
赋值语句
还可以使用 SET 语句为变量分配值。
语法:
sql
SET var = 表达式 [, ...];
|
SET (var [, var2, ...]) = (表达式 [, 表达式2, ...])
示例:
sql
SET code = 'A';
SET status = 1, count = 0;
SET (count, limit) = (0, 100);
兼容性: IBM DB2、Teradata、Microsoft SQL Server 和 MySQL。
版本: PL/HQL 0.01
从SELECT语句赋值
还可以使用 SET 语句从查询结果的第一行赋值:
语法:
sql
SET var = (SELECT 列 FROM ...);
|
SET (var [, var2, ...]) = (SELECT 列 [, 列2, ... ] FROM ...);
|
SELECT var = 列 [, var2 = 列2, ...] FROM ... -- 自HPL/SQL 0.3.11以来
示例:
sql
SET code = (SELECT code FROM conf WHERE name = 'A');
SET (count, limit) = (SELECT count, limit FROM conf WHERE name = 'A');
SELECT @count = count, @limit = limit FROM conf WHERE name = 'A';
兼容性: IBM DB2、Teradata、Microsoft SQL Server 和 MySQL。
版本: PL/HQL 0.3.7
Date的用法
DATE字面量允许使用'YYYY-MM-DD'格式的字符串来指定一个日期常量。然后,可以在任何需要DATE数据类型的表达式中使用这个日期值。
示例:
sql
DATE '2014-12-20'
DATE '2014-12-20' + 1 -- 结果:日期类型的2014-12-21
DATE '2014-12-20' - 1 -- 2014-12-19
兼容性: Oracle、IBM DB2 和 Teradata
版本: PL/HQL 0.01
TimeStamp的用法
TIMESTAMP字面量允许使用'YYYY-MM-DD HH:MI:SS.FFF'或'YYYY-MM-DD-HH.MI.SS.FFF'格式的字符串来指定一个时间戳常量。
可以在任何需要TIMESTAMP数据类型的表达式中使用这个时间戳值。
示例:
sql
TIMESTAMP '2015-03-03 11:39:31.123'
TIMESTAMP '2015-03-03-11.39.31.123' -- DB2语法
注意:
- 小数部分是可选的
兼容性: Oracle、IBM DB2
版本: PL/HQL 0.03
间隔表达式
间隔表达式允许将间隔值添加或从DATE和TIMESTAMP值中减去。
语法:
sql
[INTERVAL] expression DAYS | DAY | MICROSECONDS | MICROSECOND
注意:
- 由于Java的限制,MICROSECOND表达式会被转换为毫秒表达式。
示例1:
将1天添加到DATE和TIMESTAMP值:
sql
DATE '2015-03-12' + 1 DAY;
--
2015-03-13
TIMESTAMP '2015-03-12' + 1 DAY;
--
2015-03-13 00:00:00
示例2:
将表达式的结果添加到DATE和TIMESTAMP值:
sql
DATE '2015-03-12' + NVL(NULL, 3) DAYS;
--
2015-03-15
TIMESTAMP '2015-03-12' + NVL(NULL, 3) DAYS;
--
2015-03-15 00:00:00
示例3:
从TIMESTAMP值中减去1毫秒(不支持微秒):
sql
TIMESTAMP '2015-03-12 10:10:10.000' - 1 MICROSECOND; /* 被视为毫秒 */
--
2015-03-12 10:10:09.999
示例4:
减去多个间隔字段:
sql
TIMESTAMP '2015-03-12' - 1 DAY - 1 MICROSECOND;
--
2015-03-10 23:59:59
示例5:
使用INTERVAL关键字:
sql
date '2016-01-27' - interval '3' day;
--
2016-01-24
兼容性: IBM DB2、Oracle、Teradata
版本:
- INTERVAL关键字 - HPL/SQL 0.3.17
- 引入 - HPL/HQL 0.3
Case表达式
CASE表达式允许在表达式中实现IF-THEN-ELSE逻辑。
语法:
简单CASE表达式:
sql
CASE 表达式
WHEN 表达式 THEN 表达式
...
[ELSE 表达式]
END
搜索CASE表达式:
sql
CASE
WHEN 布尔表达式 THEN 表达式
...
[ELSE 表达式]
END
注意:
- 如果没有匹配任何WHEN表达式且未指定ELSE子句,则返回NULL。
示例:
简单CASE表达式:
sql
CASE state
WHEN 'AZ' THEN '亚利桑那'
WHEN 'CA' THEN '加利福尼亚'
ELSE 'N/A'
END
搜索CASE表达式:
sql
CASE
WHEN state = 'AZ' THEN '亚利桑那'
WHEN state = 'CA' THEN '加利福尼亚'
ELSE 'N/A'
END
兼容性: Oracle、IBM DB2、SQL Server、Teradata、MySQL、PostgreSQL 和 Netezza。
版本: PL/HQL 0.01
Type属性
以下是转换成Markdown格式的%TYPE属性部分,并将描述语句翻译成中文:
%TYPE属性
%TYPE属性允许声明一个变量,该变量具有与指定的引用列相同的数据类型。
语法:
sql
var_name [schema.]table.column_name%TYPE
- 如果//table.column_name//找不到,数据类型将从第一个赋值表达式中推导出来。
示例:
sql
DECLARE
i orders.item%TYPE;
BEGIN
SELECT item INTO i FROM orders LIMIT 1;
DBMS_OUTPUT.PUT_LINE('物品: ' || i);
END;
兼容性: Oracle
版本: HPL/SQL 0.3.13
RowType属性
以下是转换成Markdown格式的%ROWTYPE属性部分,并将描述语句翻译成中文:
%ROWTYPE属性
%ROWTYPE属性允许声明一个记录变量,该变量具有与指定数据库表相同的列和数据类型。
语法:
sql
var_name [schema.]table_name%ROWTYPE
示例:
sql
DECLARE
v orders%ROWTYPE;
BEGIN
SELECT * INTO v FROM orders LIMIT 1;
DBMS_OUTPUT.PUT_LINE('物品: ' || v.name || ' - ' || v.description);
END;
sql
DECLARE
v orders%ROWTYPE;
CURSOR c IS SELECT * FROM orders;
BEGIN
OPEN c1;
FETCH c1 INTO v1;
DBMS_OUTPUT.PUT_LINE('物品: ' || v.name || ' - ' || v.description);
CLOSE c1;
END;
sql
BEGIN
FOR v IN (SELECT * FROM orders)
LOOP
DBMS_OUTPUT.PUT_LINE('物品: ' || v.name || ' - ' || v.description);
END LOOP;
END;
sql
DECLARE
v orders%ROWTYPE;
BEGIN
EXECUTE IMMEDIATE 'SELECT * FROM orders LIMIT 1' INTO v;
DBMS_OUTPUT.PUT_LINE('物品: ' || v.name || ' - ' || v.description);
END;
兼容性: Oracle
版本: HPL/SQL 0.3.13
游标属性
以下是转换成Markdown格式的游标属性部分,并将描述语句翻译成中文:
游标属性
游标属性允许您获取有关当前游标状态的信息。
语法:
sql
cursor_name%ISOPEN
cursor_name%FOUND
cursor_name%NOTFOUND
- //cursor_name// 是已声明的游标或游标变量的名称。
===== %ISOPEN 属性 =====
%ISOPEN 如果游标是打开状态,则返回//true//,否则返回//false//。
===== %FOUND 属性 =====
%FOUND 在从游标获取数据之前返回NULL,在最后一次获取时返回//true//,否则返回//false//。
===== %NOTFOUND 属性 =====
%NOTFOUND 在从游标获取数据之前返回NULL,在最后一次获取时返回//false//,否则返回//true//。
示例:
sql
DECLARE
CURSOR c1 IS SELECT name FROM users LIMIT 1;
v1 VARCHAR(30);
BEGIN
OPEN c1;
IF c1%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('游标已打开');
END IF;
FETCH c1 INTO v1;
IF c1%FOUND THEN
DBMS_OUTPUT.PUT_LINE('找到行');
END IF;
FETCH c1 INTO v1;
IF c1%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('未找到行');
END IF;
CLOSE c1;
END;
兼容性: Oracle
版本: HPL/SQL 0.3.11