4. 接着演示动态分区:
```sql
-- 由于我们只有一个分区,且还是动态分区,所以需要关闭严格默认。因为在严格模式下,用户必须至少指定一个静态分区
set hive.exec.dynamic.partition.mode=nonstrict;
-- 动态分区 此时查询语句的最后一列为动态分区列,即deptno
INSERT OVERWRITE TABLE emp_ptn PARTITION (deptno)
SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno FROM emp WHERE deptno=30;
```
完成后`emp_ptn`表中数据如下:
## 三、使用SQL语句插入值
```sql
INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)]
VALUES ( value [, value ...] )
```
+ 使用时必须为表中的每个列都提供值。不支持只向部分列插入值(可以为缺省值的列提供空值来消除这个弊端);
+ 如果目标表表支持ACID及其事务管理器,则插入后自动提交;
+ 不支持支持复杂类型(array, map, struct, union)的插入。
## 四、更新和删除数据
### 4.1 语法
更新和删除的语法比较简单,和关系型数据库一致。需要注意的是这两个操作都只能在支持ACID的表,也就是事务表上才能执行。
```sql
-- 更新
UPDATE tablename SET column = value [, column = value ...] [WHERE expression]
--删除
DELETE FROM tablename [WHERE expression]
```
### 4.2 示例
**1. 修改配置**
首先需要更改`hive-site.xml`,添加如下配置,开启事务支持,配置完成后需要重启Hive服务。
```xml
hive.support.concurrencytruehive.enforce.bucketingtruehive.exec.dynamic.partition.modenonstricthive.txn.managerorg.apache.hadoop.hive.ql.lockmgr.DbTxnManagerhive.compactor.initiator.ontruehive.in.testtrue
```
**2. 创建测试表**
创建用于测试的事务表,建表时候指定属性`transactional = true`则代表该表是事务表。需要注意的是,按照[官方文档](https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions)的说明,目前Hive中的事务表有以下限制:
+ 必须是buckets Table;
+ 仅支持ORC文件格式;
+ 不支持LOAD DATA ...语句。
```sql
CREATE TABLE emp_ts(
empno int,
ename String
)
CLUSTERED BY (empno) INTO 2 BUCKETS STORED AS ORC
TBLPROPERTIES ("transactional"="true");
```
**3. 插入测试数据**
```sql
INSERT INTO TABLE emp_ts VALUES (1,"ming"),(2,"hong");
```
插入数据依靠的是MapReduce作业,执行成功后数据如下:
**4. 测试更新和删除**
```sql
--更新数据
UPDATE emp_ts SET ename = "lan" WHERE empno=1;
--删除数据
DELETE FROM emp_ts WHERE empno=2;
```
更新和删除数据依靠的也是MapReduce作业,执行成功后数据如下:
## 五、查询结果写出到文件系统
### 5.1 语法
```sql
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
[ROW FORMAT row_format] [STORED AS file_format]
SELECT ... FROM ...
```
+ OVERWRITE关键字表示输出文件存在时,先删除后再重新写入;
+ 和Load语句一样,建议无论是本地路径还是URL地址都使用完整的;
+ 写入文件系统的数据被序列化为文本,其中列默认由^A分隔,行由换行符分隔。如果列不是基本类型,则将其序列化为JSON格式。其中行分隔符不允许自定义,但列分隔符可以自定义,如下:
```sql
-- 定义列分隔符为'\t'
insert overwrite local directory './test-04'
row format delimited
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':'
select * from src;
```
### 5.2 示例
这里我们将上面创建的`emp_ptn`表导出到本地文件系统,语句如下:
```sql
INSERT OVERWRITE LOCAL DIRECTORY '/usr/file/ouput'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
SELECT * FROM emp_ptn;
```
导出结果如下:
## 参考资料
1. [Hive Transactions](https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions)
2. [Hive Data Manipulation Language](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML)