Oracle兼容-语法-GLOBAL|PRIVATE TEMPORARY TABLE
1. 语法
1. SET sql_mode = ORACLE;
3. create_temporary_table:
4. create_global_temporary | create_private_temporary
6. create_global_temporary:
7. CREATE GLOBAL TEMPORARY TABLE
8. [ schema . ] table_ident [ ( relational_properties ) ]
9. [ ON COMMIT { DELETE | PRESERVE } ROWS ]
10. table_properties
12. create_private_temporary:
13. CREATE PRIVATE TEMPORARY TABLE
14. [ schema . ] table_ident [ ( relational_properties ) ]
15. [ ON COMMIT { DROP | PRESERVE } DEFINITION ]
16. table_properties
需要先切换到 ORACLE 模式下才能支持本语法。
2. 定义和用法
GreatSQL中支持创建 GLOBAL|PRIVATE 两种不同的临时表。
-
- 创建
GLOBAL TEMPORARY TABLE。
- 创建
- 会立即创建一个临时表定义,但不会立即创建临时表实体。
- 具体创建时机为SQL语句有插入的操作时。若创建后,在当时的SQL没有插入任何记录,则会在该SQL结束时,删除该临时表实例。
ON COMMIT子句指定DELETE ROWS时,表示在当前事务结束时,会删除该临时表实例;ON COMMIT子句指定PRESERVE ROWS时,则在当前事务结束时,会保留该临时表实例及内容。- 当省略
ON COMMIT子句时,默认为DELETE ROWS。 - 当前连接会话结束时,会删除该临时表实例。
- 执行
TRUNCATE语句也会删除该临时表实例。 - 当系统内有任何该临时表的实例创建时,不可以对该临时表进行DDL操作,例如:
ALTER TABLE,CREATE INDEX等操作。 - 执行
DROP TABLE可以立即删除当前会话该临时表实例(若存在的话)及临时表定义。若是由其他会话创建该临时表的实例时,则只会删除当前会话的临时表实例,并会在删除临时表定义时报错。 - 执行
SHOW CREATE TABLE可以显示当前会话是否已经创建临时表实例。若当前会话存在该临时表实例时(例如:对该表有写入数据), 此时会显示为CREATE TEMPORARY TABLE,不带`GLOBAL标识。 -
- 创建
PRIVATE TEMPORARY TABLE。
- 创建
- 会立即创建一个临时表。
ON COMMIT子句指定DROP DEFINITION时,表示在当前事务结束时,会删除该临时表ON COMMIT子句指定PRESERVE DEFINITION时,则在当前事务结束时,会保留该临时表。- 当省略
ON COMMIT子句时,默认为DROP DEFINITION。 - 当前会话结束时,会删除该临时表。
- 执行
DROP TABLE会删除该临时表。
3. Oracle兼容说明
- 临时表的维护及使用,是基于GreatSQL的临时表。因此任一临时表都只能在当前语句中被引用一次。例如:t1是临时表,则
SELECT * FROM t1 UNION SELECT * FROM t1会报错,见下方详细案例。 - 在MGR环境中,其中一个节点创建临时表实例时,在其他节点的DDL操作并不会被锁阻塞,只会依照目前MGR环境中的DDL操作规则,对临时表定义进行操作。
- 与GreatSQL临时表相同,
SHOW TABLES命令不会显示已创建的GLOBAL|PRIVATE TEMPORARY TABLE临时表实例。 - 如果同时使用GreatSQL原生的
TEMPORARY TABLE创建同名的GLOBAL TEMPORARY TABLE,会让后续SQL语句以原生的TEMPORARY TABLE为主。 - 与GreatSQL常规临时表支持的数据类型一致,当临时表中包含
BLOB类型列时不会报错。 - 不支持对
GLOBAL TEMPORARY TABLE创建触发器。但触发器及视图内可以引用GLOBAL TEMPORARY TABLE。 - 执行
RENAME TABLE与ALTER TABLE .. RENAME语句时,必须当时没有GLOBAL TEMPORARY TABLE临时表同名实例(Oracle 沒有這個限制)。 - 每个
GLOBAL TEMPORARY TABLE实例的AUTO_INCREMENT字段都一律由1开始(Oracle没这个约束)。 - 当创建临时表实例后,在任何会话中删除
GLOBAL TEMPORARY TABLE所在的数据库时,该临时表实例会继续存在。若之后继续创建同名的数据库及同名的GLOBAL TEMPORARY TABLE,并不会对已经生成的临时表实例有影响。 - 由于在
PRIVATE TEMPORARY TABLE中是不支持指定主键的,因此在创建PRIVATE TEMPORARY TABLE时不能显式指定主键,也必须设置sql_generate_invisible_primary_key=0,避免隐式创建主键,否则会提示不支持该用法。 - 执行
TRUNCATE语句会终止当前事务,会对当前事务中创建的临时表有影响。
4. 示例
1. greatsql> SET sql_mode = ORACLE;
3. greatsql> CREATE TEMPORARY TABLE t1 (id INT);
4. Query OK, 0 rows affected (0.01 sec)
6. greatsql> INSERT INTO t1 VALUES (1);
7. Query OK, 1 row affected (0.00 sec)
9. -- 1. 普通临时表在同一个SQL语句中,只能被引用一次
10. greatsql> SELECT * FROM t1 UNION SELECT * FROM t1;
11. ERROR 1137 (HY000): Can not reopen table: 't1'
13. greatsql> SELECT * FROM t1;
14. +------+
15. | id |
16. +------+
17. | 1 |
18. +------+
19. 1 row in set (0.01 sec)
21. -- 2. 创建GLOBAL TEMPORARY TABLE,指定不同的ON COMMIT子句
23. -- 先切换到ORACLE模式下
24. greatsql> SET sql_mode = ORACLE;
26. greatsql> CREATE GLOBAL TEMPORARY TABLE gtt1 (
27. id INT PRIMARY KEY,
28. c1 VARCHAR(16));
30. -- 不指定ON COMMIT子句,默认为DELETE ROWS
31. greatsql> SHOW CREATE TABLE gtt1\G
32. *************************** 1. row ***************************
33. Table: gtt1
34. Create Table: CREATE GLOBAL TEMPORARY TABLE "gtt1" (
35. "id" int NOT NULL,
36. "c1" varchar(16) DEFAULT NULL,
37. PRIMARY KEY ("id")
38. ) ON COMMIT DELETE ROWS ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
40. -- 指定ON COMMIT PRESERVE ROWS
41. greatsql> CREATE GLOBAL TEMPORARY TABLE gtt2 (
42. id INT PRIMARY KEY,
43. c1 VARCHAR(16)
44. ) ON COMMIT PRESERVE ROWS;
46. greatsql> SHOW CREATE TABLE gtt2\G
47. *************************** 1. row ***************************
48. Table: gtt2
49. Create Table: CREATE GLOBAL TEMPORARY TABLE "gtt2" (
50. "id" int NOT NULL,
51. "c1" varchar(16) DEFAULT NULL,
52. PRIMARY KEY ("id")
53. ) ON COMMIT PRESERVE ROWS ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
55. greatsql> INSERT INTO gtt1 SELECT 1, 'c11' FROM DUAL;
56. Query OK, 0 rows affected (0.40 sec)
57. Records: 1 Duplicates: 0 Warnings: 0
59. -- 上面的SQL中未显式启用事务,SQL执行结束后等于事务也结束了,所以查询不到数据
60. greatsql> SELECT * FROM gtt1;
61. Empty set (0.00 sec)
63. greatsql> INSERT INTO gtt2 SELECT 1, 'c12' FROM DUAL;
64. Query OK, 0 rows affected (0.04 sec)
65. Records: 1 Duplicates: 0 Warnings: 0
67. -- SQL语句执行结束后还能查询到数据
68. greatsql> SELECT * FROM gtt2;
69. +----+------+
70. | id | c1 |
71. +----+------+
72. | 1 | c12 |
73. +----+------+
74. 1 row in set (0.00 sec)
76. -- 再次查看DDL,gtt1不变
77. greatsql> SHOW CREATE TABLE gtt1\G
78. *************************** 1. row ***************************
79. Table: gtt1
80. Create Table: CREATE GLOBAL TEMPORARY TABLE "gtt1" (
81. "id" int NOT NULL,
82. "c1" varchar(16) DEFAULT NULL,
83. PRIMARY KEY ("id")
84. ) ON COMMIT DELETE ROWS ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
85. 1 row in set (0.00 sec)
87. -- 再次查看DDL,gtt2变成了普通临时表
88. greatsql> SHOW CREATE TABLE gtt2\G
89. *************************** 1. row ***************************
90. Table: gtt2
91. Create Table: CREATE TEMPORARY TABLE "gtt2" (
92. "id" int NOT NULL,
93. "c1" varchar(16) DEFAULT NULL,
94. PRIMARY KEY ("id")
95. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
96. 1 row in set (0.00 sec)
98. -- 3. 显式开启事务测试
99. greatsql> DELETE FROM gtt1;
100. greatsql> DELETE FROM gtt2;
102. greatsql> BEGIN;
103. greatsql> INSERT INTO gtt1 SELECT 1, 'c11' FROM DUAL;
104. greatsql> INSERT INTO gtt2 SELECT 1, 'c12' FROM DUAL;
106. -- 此时事务尚未提交,gtt1表能查询到数据
107. greatsql> SELECT * FROM gtt1;
108. +----+------+
109. | id | c1 |
110. +----+------+
111. | 1 | c11 |
112. +----+------+
113. 1 row in set (0.00 sec)
115. greatsql> SELECT * FROM gtt2;
116. +----+------+
117. | id | c1 |
118. +----+------+
119. | 1 | c12 |
120. +----+------+
121. 1 row in set (0.00 sec)
123. -- 再次查看DDL,发现都变成了普通临时表
124. greatsql> SHOW CREATE TABLE gtt1\G
125. *************************** 1. row ***************************
126. Table: gtt1
127. Create Table: CREATE TEMPORARY TABLE "gtt1" (
128. "id" int NOT NULL,
129. "c1" varchar(16) DEFAULT NULL,
130. PRIMARY KEY ("id")
131. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
132. 1 row in set (0.00 sec)
134. greatsql> SHOW CREATE TABLE gtt2\G
135. *************************** 1. row ***************************
136. Table: gtt2
137. Create Table: CREATE TEMPORARY TABLE "gtt2" (
138. "id" int NOT NULL,
139. "c1" varchar(16) DEFAULT NULL,
140. PRIMARY KEY ("id")
141. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
142. 1 row in set (0.00 sec)
144. -- 提交事务后再次查询数据,发现gtt1表被清空
145. greatsql> COMMIT;
147. greatsql> SELECT * FROM gtt1;
148. Empty set (0.00 sec)
150. greatsql> SELECT * FROM gtt2;
151. +----+------+
152. | id | c1 |
153. +----+------+
154. | 1 | c12 |
155. +----+------+
156. 1 row in set (0.00 sec)
158. -- 再次查看DDL,gtt1恢复成GLOBAL TEMPORARY TABLE,gtt2继续保持普通临时表
159. greatsql> SHOW CREATE TABLE gtt1\G
160. *************************** 1. row ***************************
161. Table: gtt1
162. Create Table: CREATE GLOBAL TEMPORARY TABLE "gtt1" (
163. "id" int NOT NULL,
164. "c1" varchar(16) DEFAULT NULL,
165. PRIMARY KEY ("id")
166. ) ON COMMIT DELETE ROWS ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
168. greatsql> SHOW CREATE TABLE gtt2\G
169. *************************** 1. row ***************************
170. Table: gtt2
171. Create Table: CREATE TEMPORARY TABLE "gtt2" (
172. "id" int NOT NULL,
173. "c1" varchar(16) DEFAULT NULL,
174. PRIMARY KEY ("id")
175. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
178. -- 3. 创建PRIVATE TEMPORARY TABLE,指定不同的ON COMMIT子句,
179. -- 3.1 指定PRESERVE DEFINITION子句
180. greatsql> SET sql_mode = ORACLE;
181. greatsql> CREATE PRIVATE TEMPORARY TABLE ora$ptt_s1(
182. id INT,
183. c1 VARCHAR(30)
184. )ON COMMIT PRESERVE DEFINITION;
186. greatsql> INSERT INTO ora$ptt_s1 VALUES (1, 'ora$ptt_s1-1');
187. greatsql> INSERT INTO ora$ptt_s1 VALUES (2, 'ora$ptt_s1-2');
189. -- 查看table
190. greatsql> SHOW CREATE TABLE ora$ptt_s1\G
191. *************************** 1. row ***************************
192. Table: ora$ptt_s1
193. Create Table: CREATE PRIVATE TEMPORARY TABLE "ora$ptt_s1" (
194. "id" int DEFAULT NULL,
195. "c1" varchar(30) DEFAULT NULL
196. ) ON COMMIT PRESERVE DEFINITION ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
198. -- 查询数据
199. greatsql> SELECT * FROM ora$ptt_s1;
200. +------+--------------+
201. | id | c1 |
202. +------+--------------+
203. | 1 | ora$ptt_s1-1 |
204. | 2 | ora$ptt_s1-2 |
205. +------+--------------+
206. 2 rows in set (0.00 sec)
208. -- 3.2 指定DROP DEFINITION子句
210. -- 开始事务
211. greatsql> BEGIN;
212. -- 不指定ON COMMIT子句默认使用DROP DEFINITION
213. greatsql> CREATE PRIVATE TEMPORARY TABLE ora$ptt_t0(
214. id INT,
215. c1 VARCHAR(30)
216. );
218. greatsql> CREATE PRIVATE TEMPORARY TABLE ora$ptt_t1(
219. id INT,
220. c1 VARCHAR(30)
221. ) ON COMMIT DROP DEFINITION;
223. -- 写入数据
224. greatsql> INSERT INTO ora$ptt_t0 VALUES (10, 'ora$ptt_t0-10');
225. greatsql> INSERT INTO ora$ptt_t0 VALUES (20, 'ora$ptt_t0-20');
226. greatsql> INSERT INTO ora$ptt_t1 VALUES (100, 'ora$ptt_t1-100');
227. greatsql> INSERT INTO ora$ptt_t1 VALUES (200, 'ora$ptt_t1-200');
229. -- 查看表DDL
230. greatsql> SHOW CREATE TABLE ora$ptt_t0\G
231. *************************** 1. row ***************************
232. Table: ora$ptt_t0
233. Create Table: CREATE PRIVATE TEMPORARY TABLE "ora$ptt_t0" (
234. "id" int DEFAULT NULL,
235. "c1" varchar(30) DEFAULT NULL
236. ) ON COMMIT DROP DEFINITION ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
238. greatsql> SHOW CREATE TABLE ora$ptt_t1\G
239. *************************** 1. row ***************************
240. Table: ora$ptt_t1
241. Create Table: CREATE PRIVATE TEMPORARY TABLE "ora$ptt_t1" (
242. "id" int DEFAULT NULL,
243. "c1" varchar(30) DEFAULT NULL
244. ) ON COMMIT DROP DEFINITION ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
246. -- 查询数据
247. greatsql> SELECT * FROM ora$ptt_t1;
248. +------+----------------+
249. | id | c1 |
250. +------+----------------+
251. | 100 | ora$ptt_t1-100 |
252. | 200 | ora$ptt_t1-200 |
253. +------+----------------+
254. 2 rows in set (0.00 sec)
256. -- 提交事务
257. greatsql> COMMIT;
259. -- 查询数据
260. greatsql> SELECT * FROM ora$ptt_s1;
261. +------+--------------+
262. | id | c1 |
263. +------+--------------+
264. | 1 | ora$ptt_s1-1 |
265. | 2 | ora$ptt_s1-2 |
266. +------+--------------+
267. 2 rows in set (0.00 sec)
269. -- 事务提交后,PRIVATE TEMPORARY TABLE会被删除
270. greatql> SELECT * FROM ora$ptt_t0;
271. ERROR 1146 (42S02): Table 'greatsql.ora$ptt_t0' doesn't exist
273. greatsql> SELECT * FROM ora$ptt_t1;
274. ERROR 1146 (42S02): Table 'greatsql.ora$ptt_t1' doesn't exist
276. -- 显式指定PRIMARY KEY,或者当sql_generate_invisible_primary_key=1时会报告不支持
277. greatsql> CREATE PRIVATE TEMPORARY TABLE ora$ptt_t1(
278. id INT,
279. c1 VARCHAR(30),
280. PRIMARY KEY(id));
281. ERROR 7561 (HY000): unsupported feature with temporary table
283. greatsql> SET sql_generate_invisible_primary_key = 1;
284. greatsql> CREATE PRIVATE TEMPORARY TABLE ora$ptt_t1(
285. id INT,
286. c1 VARCHAR(30));
287. ERROR 7561 (HY000): unsupported feature with temporary table
问题反馈
联系我们
扫码关注微信公众号

