8.3. SQL 语法

8.3.1. 查询和子查询

查询是指数据库中用来获取数据的方式,它可搭配条件限制子句(例如 WHERE),排列顺序子句(例如 ORDER BY)等语句来获取查询结果。 子查询是指嵌套在一个上层查询中的查询。上层的查询一般被称为父查询或外部查询。子查询的结果作为输入传递回父查询或外部查询。父查询将这个值结合到计算中,以便确定最后的输出。 SQL 语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。同时,子查询可以出现在 SQL 语句中的各种子句中,例如 SELECT 语句、FROM 语句和 WHERE 语句等。

请参考Oracle2LightDB-Oracle:

查询和子查询

以下是和Oracle2LightDB-Oracle有差异的部分语法:

8.3.1.1. 分区表查询

CREATE TABLE unisql_partition (
unisql_id NUMBER,
unisql_name VARCHAR2(50),
unisql_salary NUMBER(10,2),
unisql_hire_date DATE,
CONSTRAINT unisql_partition_pk PRIMARY KEY (unisql_id, unisql_hire_date)
)
PARTITION BY RANGE (unisql_hire_date) (
PARTITION unisql_partition_p1 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),
PARTITION unisql_partition_p2 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD'))
);

INSERT INTO unisql_partition (unisql_id,unisql_name,unisql_salary, unisql_hire_date)values (1, 'John', 5000, TO_DATE('2023-01-01','YYYY-MM-DD'));
INSERT INTO unisql_partition (unisql_id,unisql_name,unisql_salary, unisql_hire_date)values (2, 'Mary', 6000, TO_DATE( '2023-02-15','YYYY-MM-DD'));
INSERT INTO unisql_partition (unisql_id,unisql_name,unisql_salary, unisql_hire_date)values (3, 'Tom', 7000, TO_DATE( '2023-03-20','YYYY-MM-DD'));
INSERT INTO unisql_partition (unisql_id,unisql_name,unisql_salary, unisql_hire_date)values (4, 'Alice', 8000, TO_DATE('2023-04-10','YYYY-MM-DD'));
INSERT INTO unisql_partition (unisql_id,unisql_name,unisql_salary, unisql_hire_date)values (5, 'Bob', 9000, TO_DATE('2023-05-01','YYYY-MM-DD'));

-- 转换前Oracle SQL:
SELECT unisql_id,unisql_name,unisql_salary, unisql_hire_date FROM unisql_partition PARTITION (unisql_partition_p1);
UNISQL_ID|UNISQL_NAME|UNISQL_SALARY|UNISQL_HIRE_DATE       |
---------+-----------+-------------+-----------------------+
        1|John       |         5000|2023-01-01 00:00:00.000|
        2|Mary       |         6000|2023-02-15 00:00:00.000|
        3|Tom        |         7000|2023-03-20 00:00:00.000|
        4|Alice      |         8000|2023-04-10 00:00:00.000|
        5|Bob        |         9000|2023-05-01 00:00:00.000|

-- 转换后达梦 SQL:
SELECT unisql_id,unisql_name,unisql_salary, unisql_hire_date FROM unisql_partition PARTITION (unisql_partition_p1)
unisql_id|unisql_name|unisql_salary|unisql_hire_date       |
unisql_id|unisql_name|unisql_salary|unisql_hire_date|
---------+-----------+-------------+----------------+
        1|John       |      5000.00|      2023-01-01|
        2|Mary       |      6000.00|      2023-02-15|
        3|Tom        |      7000.00|      2023-03-20|
        4|Alice      |      8000.00|      2023-04-10|
        5|Bob        |      9000.00|      2023-05-01|

8.3.1.2. pivot行转列

CREATE TABLE unisql_pivot(id int ,name varchar(64),score NUMBER ,subject varchar2(64));
INSERT INTO unisql_pivot VALUES(1,'张三',70,'CHINESE');
INSERT INTO unisql_pivot VALUES(1,'张三',90,'MATH');
INSERT INTO unisql_pivot VALUES(1,'张三',95,'ENGLISH');
INSERT INTO unisql_pivot VALUES(2,'李四',75,'CHINESE');
INSERT INTO unisql_pivot VALUES(2,'李四',85,'MATH');
INSERT INTO unisql_pivot VALUES(2,'李四',90,'ENGLISH');
INSERT INTO unisql_pivot VALUES(3,'王五',90,'CHINESE');
INSERT INTO unisql_pivot VALUES(3,'王五',90,'MATH');
INSERT INTO unisql_pivot VALUES(3,'王五',90,'ENGLISH');

-- 转换前Oracle SQL:
SELECT id,name,chinese_score,match_score,english_score
FROM unisql_pivot
pivot(
    min(score) FOR subject IN('CHINESE' AS chinese_score,'MATH' AS match_score,'ENGLISH' AS english_score)
    )
WHERE id IN (1, 2, 3) ORDER BY id;
ID|NAME|CHINESE_SCORE|MATCH_SCORE|ENGLISH_SCORE|
--+----+-------------+-----------+-------------+
1|张三  |           70|         90|           95|
2|李四  |           75|         85|           90|
3|王五  |           90|         90|           90|

-- 转换后达梦 SQL:
SELECT id,name,chinese_score,match_score,english_score
FROM unisql_pivot
pivot(
    min(score) FOR subject IN('CHINESE' AS chinese_score,'MATH' AS match_score,'ENGLISH' AS english_score)
    )
WHERE id IN (1, 2, 3) ORDER BY id
id|name|chinese_score|match_score|english_score|
--+----+-------------+-----------+-------------+
1|张三  |           70|         90|           95|
2|李四  |           75|         85|           90|
3|王五  |           90|         90|           90|

8.3.1.3. unpivot列转行

-- 建表语句
CREATE TABLE unisql_unpivot(id INT,name VARCHAR(64),chinese NUMBER,math INT,english INT);
INSERT INTO unisql_unpivot VALUES(1,'张三',70,90,95);
INSERT INTO unisql_unpivot VALUES(2,'李四',75,85,90);
INSERT INTO unisql_unpivot VALUES(3,'张三',90,90,90);

-- 转换前Oracle SQL:
SELECT
id,
name,
score ,
subject
FROM
unisql_unpivot UNPIVOT(score FOR subject IN(chinese, math, english))
WHERE
id IN (1, 2, 3) ORDER BY id;
ID|NAME|SCORE|SUBJECT|
--+----+-----+-------+
1|张三  |   70|CHINESE|
1|张三  |   90|MATH   |
1|张三  |   95|ENGLISH|
2|李四  |   75|CHINESE|
2|李四  |   85|MATH   |
2|李四  |   90|ENGLISH|
3|张三  |   90|CHINESE|
3|张三  |   90|MATH   |
3|张三  |   90|ENGLISH|

-- 转换后达梦 SQL:
SELECT
id,
name,
score ,
subject
FROM
unisql_unpivot UNPIVOT(score FOR subject IN(chinese, math, english))
WHERE
id IN (1, 2, 3) ORDER BY id
id|name|score|subject|
--+----+-----+-------+
1|张三  |   90|math   |
1|张三  |   70|chinese|
1|张三  |   95|english|
2|李四  |   85|math   |
2|李四  |   90|english|
2|李四  |   75|chinese|
3|张三  |   90|math   |
3|张三  |   90|chinese|
3|张三  |   90|english|

8.3.1.4. MINUS 差集

{ (< SQL- 查询语句 1>) }
MINUS
{ (< SQL- 查询语句 2>) }

-- 转换前Oracle SQL:
SELECT * FROM unisql_collect_1
    MINUS
SELECT * FROM unisql_collect_2;
ID|NAME|CHINESE|MATH|ENGLISH|
--+----+-------+----+-------+
3|王五  |     90|  90|     90|
4|秦六  |     65|  65|     60|

-- 转换后达梦 SQL:
SELECT * FROM unisql_collect_1
    MINUS
SELECT * FROM unisql_collect_2
id|name|chinese|math|english|
--+----+-------+----+-------+
3|王五  |     90|  90|     90|
4|秦六  |     65|  65|     60|

8.3.1.5. AS作为别名

通常AS在数据库中作为保留关键字,一般不建议作为字段的别名,但是有时候开发人员在编写SQL语句时,存在使用AS作为别名的情况。 统一SQL支持AS作为别名时到目标库的转换。

示例

-- 转换前Oracle SQL:
SELECT 0 as, 1 as,2 "as", 3 a, 4 as b, count(*) as FROM dual;
0AS|1AS|as|A|B|COUNT(*)AS|
---+---+--+-+-+----------+
  0|  1| 2|3|4|         1|

-- 转换后达梦 SQL:
SELECT 0 AS "as",1 AS "as",2 AS "as",3 AS a,4 AS b,count(1) AS "as" FROM dual
as|as|as|a|b|as|
--+--+--+-+-+--+
0| 1| 2|3|4| 1|

8.3.2. 伪列

伪列(Pseudocolumn)的行为与表中的列相同,但并未存储具体数值。因此,伪列只具备读属性,不可以对伪列进行插入、更新、删除的等行为。本节主要介绍 统一SQL 所支持的伪列及使用说明。

请参考Oracle2LightDB-Oracle:

伪列

以下是和Oracle2LightDB-Oracle有差异的部分语法:

8.3.2.1. 序列伪列

序列(Sequence)是数据库按照一定规则生成的自增数字序列。因其自增的特性,通常被用作主键和唯一键。本节主要介绍序列的取值方法和应用场景。

8.3.2.2. 序列的取值方法

可以使用如下伪列引用 SQL 语句中的序列值:

  • CURRVAL:返回序列的当前值。

  • NEXTVAL:返回序列的下一个自增值。

使用序列伪列时,必须在 CURRVAL 和 NEXTVAL 前带上序列的名称,并用句点(.)引用。例如,序列的名称为 SEQ_FOO,则可以通过 SEQ_FOO.CURRVAL 获取 SEQ_FOO 序列的当前值。同样,可以通过 SEQ_FOO.NEXTVAL 获取 SEQ_FOO 序列的下一个自增值。

8.3.2.3. 序列值的应用场景

通过 CURRVAL 和 NEXTVAL 引用的序列值可以用于以下位置:

  • 非子查询或者视图中的 SELECT 语句的选择列表中。

  • INSERT 语句中子查询的选择列表中。

  • INSERT 语句中的 VALUE 子句中。

  • UPDATE 语句中的 SET 子句中。

序列 CURRVAL 和 NEXTVAL 的值不能用于以下位置:

  • DELETE、SELECT 或者 UPDATE 语句的子查询中。

  • 视图的查询中。

  • 带 DISTINCT 运算符的 SELECT 语句中。

  • 带 GROUP BY 子句或者 ORDER BY 子句的 SELECT 语句中。

  • 与另一个 SELECT 语句通过 UNION、INTERSECT 或者 MINUS 集合运算符进行联合的 SELECT 语句中。

  • SELECT 语句的 WHERE 子句中。

  • CREATE TABLE 或者 ALTER TABLE 语句中列的 DEFAULT 值。

  • CHECK 约束的条件中。

  • 带 FROM TABLE 语句中。

-- 创建sequence
create sequence uni_seq increment by 1 start with 1;

-- 转换前Oracle SQL:
-- 获取下一个sequence的值
SELECT uni_seq.nextval FROM DUAL;
NEXTVAL|
-------+
      1|

-- 转换后达梦 创建sequence SQL:
create sequence uni_seq increment by 1 start with 1
-- 转换后达梦 SQL:
SELECT uni_seq.nextval FROM DUAL
nextval|
-------+
      1|

8.3.2.4. ROWID 伪列

ROWID 伪列提供了快速定位表中某一行的能力,ROWID 值由主键编码得到,不会进行实际的存储。

-- 转换前Oracle SQL:
SELECT ROWID,ke.* FROM unisql_employee ke;
ROWID             |EMPLOYEE_ID|NAME |SALARY|DEPARTMENT_ID|HIRE_DATE |COMMISSION_PCT|
------------------+-----------+-----+------+-------------+----------+--------------+
AAA2fQAAMAAIbD0AAA|          1|JACK |  5000|            1|2023-01-01|          0.05|
AAA2fQAAMAAIbD0AAB|          2|TOM  | 10000|            1|2023-02-01|          0.15|
AAA2fQAAMAAIbD0AAC|          3|LINDA| 15000|            1|2023-03-01|           0.2|
AAA2fQAAMAAIbD0AAD|          4|ADA  | 20000|            2|2023-04-01|           0.1|
AAA2fQAAMAAIbD0AAE|          5|TINA | 30000|            2|2023-05-01|           0.2|
AAA2fQAAMAAIbD0AAF|          6|KATE | 50000|            3|2023-06-01|           0.3|


-- 转换后达梦 SQL:
SELECT ROWID,ke.* FROM unisql_employee ke
ROWID|employee_id|name |salary|department_id|hire_date |commission_pct|
-----+-----------+-----+------+-------------+----------+--------------+
    1|          1|JACK |  5000|            1|2023-01-01|          0.05|
    2|          2|TOM  | 10000|            1|2023-02-01|          0.15|
    3|          3|LINDA| 15000|            1|2023-03-01|           0.2|
    4|          4|ADA  | 20000|            2|2023-04-01|           0.1|
    5|          5|TINA | 30000|            2|2023-05-01|           0.2|
    6|          6|KATE | 50000|            3|2023-06-01|           0.3|

8.3.3. 运算符

运算符一般用于连接运算数或参数等单个数据项并返回结果。从语法上讲,运算符出现在操作数之前、操作数之后或两个操作数之间均可。本节主要介绍 统一SQL 所支持的常见运算符及使用说明。

当前支持常见运算符类型:

8.3.3.1. 串联运算符

串联运算符 || 用于连接字符串和 CLOB 数据类型的数据。使用串联运算符连接两个字符串后会得到另一个字符串。

-- 转换前Oracle SQL:
select '成交价格高于前一日收盘价;成交价格:' || 2 * 1000.00 || '元,收盘价:' || null || '' || '   '|| 'end'|| ''  FROM DUAL;
'成交价格高于前一日收盘价;成交价格:'||2*1000.00||'元,收盘价:'||NULL||''||''||'END'||''|
------------------------------------------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end                                |

-- 转换后达梦 SQL:
SELECT '成交价格高于前一日收盘价;成交价格:'||2*1000.00||'元,收盘价:'||NULL||''||'   '||'end'||'' FROM DUAL;
?column?                          |
----------------------------------+
成交价格高于前一日收盘价;成交价格:2000元,收盘价:   end|

警告

目标库、源库串联运算符优先级不同,源库中串联运算符和加法、减法在同一级,而目标库中串联运算符和加法、减法不在同一级。所以串联的字符串中含有加法或减法,两边数据库结果可能不一致。

8.3.4. DML

DML(Data Manipulation Language,数据操作语言)语句用于操作现有 Schema 对象中的数据,如增加、修改、删除等。

请参考Oracle2LightDB-Oracle:

DML

以下是和Oracle2LightDB-Oracle有差异的部分语法:

8.3.4.1. 多表插入

CREATE TABLE unisql_multi_table_small_orders (
order_id INT,
customer_id INT,
order_total INT,
sales_rep_id INT
);

CREATE TABLE unisql_multi_table_medium_orders (
    order_id INT,
    customer_id INT,
    order_total INT,
    sales_rep_id INT
);

CREATE TABLE unisql_multi_table_large_orders (
    order_id INT,
    customer_id INT,
    order_total INT,
    sales_rep_id INT
);

-- 转换前Oracle SQL:
INSERT ALL
-- 插入到 unisql_multi_table_small_orders 表中
INTO unisql_multi_table_small_orders (order_id,customer_id,order_total,sales_rep_id )
    VALUES((order_id + customer_id + 1)*2,customer_id,order_total+1,credit_limit)
-- 插入到 unisql_multi_table_medium_orders 表中
INTO unisql_multi_table_medium_orders(order_id,customer_id,order_total,sales_rep_id )
    VALUES(order_id,customer_id,(order_total + customer_id + 1)*2+2,credit_limit)
-- 插入到 unisql_multi_table_large_orders 表中
INTO unisql_multi_table_large_orders(order_id,customer_id,order_total,sales_rep_id )
    VALUES(order_id,customer_id,order_total+3,credit_limit)
SELECT (order_ +1 )*2 order_id ,(customer_ +1 )*2 customer_id,order_total,credit_limit FROM unisql_special_orders;

-- 转换后达梦 SQL:
-- INSERT ALL INTO unisql_multi_table_small_orders (order_id,customer_id,order_total,sales_rep_id) VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit) INTO unisql_multi_table_medium_orders (order_id,customer_id,order_total,sales_rep_id) VALUES (order_id,customer_id,(order_total+customer_id+1)*2+2,credit_limit) INTO unisql_multi_table_large_orders (order_id,customer_id,order_total,sales_rep_id) VALUES (order_id,customer_id,order_total+3,credit_limit) SELECT (order_+1)*2 AS order_id,(customer_+1)*2 AS customer_id,order_total,credit_limit FROM unisql_special_orders
INSERT ALL
INTO unisql_multi_table_small_orders (order_id,customer_id,order_total,sales_rep_id) VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit)
INTO unisql_multi_table_medium_orders (order_id,customer_id,order_total,sales_rep_id) VALUES (order_id,customer_id,(order_total+customer_id+1)*2+2,credit_limit)
INTO unisql_multi_table_large_orders (order_id,customer_id,order_total,sales_rep_id) VALUES (order_id,customer_id,order_total+3,credit_limit)
SELECT (order_+1)*2 AS order_id,(customer_+1)*2 AS customer_id,order_total,credit_limit FROM unisql_special_orders



-- 转换前Oracle SQL:
INSERT ALL
WHEN order_id = 4 THEN
    INTO unisql_multi_table_small_orders VALUES((order_id + customer_id + 1)*2,customer_id,order_total+1,credit_limit)
WHEN order_id = 6 THEN
    INTO unisql_multi_table_medium_orders VALUES(order_id,customer_id,(order_total + customer_id + 1)*2+2,credit_limit)
ELSE
    INTO unisql_multi_table_large_orders VALUES(order_id,customer_id,order_total+3,credit_limit)
SELECT (order_ +1 )*2 order_id ,(customer_ +1 )*2 customer_id,order_total,credit_limit FROM unisql_special_orders;

-- 转换后达梦 SQL:
-- INSERT ALL WHEN order_id=4 THEN INTO unisql_multi_table_small_orders VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit) WHEN order_id=6 THEN INTO unisql_multi_table_medium_orders VALUES (order_id,customer_id,(order_total+customer_id+1)*2+2,credit_limit) ELSE INTO unisql_multi_table_large_orders VALUES (order_id,customer_id,order_total+3,credit_limit) SELECT (order_+1)*2 AS order_id,(customer_+1)*2 AS customer_id,order_total,credit_limit FROM unisql_special_orders
INSERT ALL
WHEN order_id=4 THEN
    INTO unisql_multi_table_small_orders VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit)
WHEN order_id=6 THEN
    INTO unisql_multi_table_medium_orders VALUES (order_id,customer_id,(order_total+customer_id+1)*2+2,credit_limit)
ELSE
    INTO unisql_multi_table_large_orders VALUES (order_id,customer_id,order_total+3,credit_limit)
SELECT (order_+1)*2 AS order_id,(customer_+1)*2 AS customer_id,order_total,credit_limit FROM unisql_special_orders

-- 转换前Oracle SQL:
INSERT ALL
WHEN order_id = 4 and order_id in (select order_id FROM unisql_multi_table_small_orders WHERE order_id>1) THEN
    INTO unisql_multi_table_small_orders VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit)
ELSE
    INTO unisql_multi_table_large_orders VALUES(order_id,customer_id,order_total+3,credit_limit)
SELECT (order_ +1 )*2 order_id ,(customer_ +1 )*2 customer_id,order_total,credit_limit FROM unisql_special_orders;

-- 转换后达梦 SQL:
INSERT ALL
WHEN order_id = 4 and order_id in (select order_id FROM unisql_multi_table_small_orders WHERE order_id>1) THEN
    INTO unisql_multi_table_small_orders VALUES ((order_id+customer_id+1)*2,customer_id,order_total+1,credit_limit)
ELSE
    INTO unisql_multi_table_large_orders VALUES(order_id,customer_id,order_total+3,credit_limit)
SELECT (order_ +1 )*2 order_id ,(customer_ +1 )*2 customer_id,order_total,credit_limit FROM unisql_special_orders

8.3.5. DDL

DDL(Data Definition Language,数据定义语言)语句用来创建、修改和删除数据库对象。

备注

在 DDL 开始之前和之后,数据库会发出一个隐式的 COMMIT 语句,所以 DDL 语句执行后不可以回滚,建议在 DDL 操作之前做好备份。

请参考Oracle2LightDB-Oracle:

DDL

以下是和Oracle2LightDB-Oracle有差异的部分语法:

8.3.5.1. 创建索引

语法

CREATE [UNIQUE|BITMAP] INDEX [SCHEMA.] INDEX_NAME
ON TABLE_NAME ( COLUMN1, COLUMN2, ..., COLUMNN )
[{ LOGGING |  NOLOGGING}]
[{ GLOBAL  |  LOCAL}]
[{ USABLE  |  UNUSABLE}]
[{ ENABLE  |  DISABLE}]
[{ IMMEDIATE INVALIDATION  |  UNUSABLE}]
[tablespace tablespaceName] [local]

示例

--创建表
CREATE TABLE unisql_index_test(col1 int,col2 int,col3 int,col4 int,col5 varchar(10));

-- 删除存在的索引
DROP INDEX unisql_index_test_idx;

-- 转换前Oracle SQL:
-- 使用示例
CREATE INDEX unisql_index_test_idx ON unisql_index_test (col1);
CREATE UNIQUE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE BITMAP INDEX unisql_index_test_idx ON unisql_index_test (col1);
CREATE INDEX test.unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1 asc);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1 desc);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1,col2);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) LOGGING;
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) NOLOGGING;
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) GLOBAL;
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) USABLE;
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) UNUSABLE;



-- 转换后达梦 SQL:
CREATE INDEX unisql_index_test_idx ON unisql_index_test (col1);
CREATE UNIQUE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE BITMAP INDEX unisql_index_test_idx ON unisql_index_test (col1);
CREATE INDEX test.unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1 desc);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1,col2);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) GLOBAL;
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1);
CREATE INDEX unisql_index_test_idx ON unisql_index_test(col1) UNUSABLE;


-- 创建表,LOCAL索引需要创建在分区表上
CREATE TABLE unisql_local_test_orders (
    order_id   int,
    order_num int,
    customer   varchar(50)
)
PARTITION BY RANGE (order_num)
(
    PARTITION p1 VALUES LESS THAN (100),
    PARTITION p2 VALUES LESS THAN (200),
    PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

-- 删除存在的索引
DROP INDEX unisql_local_test_orders_idx;

-- 转换前Oracle SQL:
-- 使用示例
CREATE INDEX unisql_local_test_orders_idx ON unisql_local_test_orders(order_num) LOCAL;
CREATE INDEX unisql_local_test_orders_idx ON unisql_local_test_orders(order_num) tablespace test LOCAL;

-- 转换后达梦 SQL:
CREATE INDEX unisql_local_test_orders_idx ON unisql_local_test_orders (order_num)
CREATE INDEX unisql_local_test_orders_idx ON unisql_local_test_orders (order_num)

8.3.5.2. 创建分区表

分区范围支持使用函数、字符串、常数表达,统一SQL会根据表名、分区名在转化库中创建分区表,分区表名为:表名_1_prt_分区名

语法

CREATE TABLE TABLE_NAME …PARTITION BY[HASH|RANGE|LIST] (partition_list)

示例

-- 转换前Oracle SQL:
CREATE TABLE unisql_partition_by_range_test
(
product_id   NUMBER(6),
sale_time    TIMESTAMP(6),
sale_price   NUMBER(10,2)
)
PARTITION BY RANGE (sale_time)
(
PARTITION q1_2023 VALUES LESS THAN (TO_DATE('2023/04/01', 'yyyy/mm/dd')),
PARTITION q2_2023 VALUES LESS THAN (TO_DATE('2023/07/01', 'yyyy/mm/dd')),
PARTITION q3_2023 VALUES LESS THAN (TO_DATE('2023/10/01', 'yyyy/mm/dd')),
PARTITION q4_2023 VALUES LESS THAN (TO_DATE('2024/01/01', 'yyyy/mm/dd'))
);

-- 转换后达梦 SQL:
-- CREATE TABLE unisql_partition_by_range_test(product_id NUMBER(6),sale_time TIMESTAMP(6),sale_price NUMBER(10,2))PARTITION BY RANGE (sale_time)(PARTITION q1_2023 VALUES LESS THAN (TO_DATE('2023/04/01', 'yyyy/mm/dd')),PARTITION q2_2023 VALUES LESS THAN (TO_DATE('2023/07/01', 'yyyy/mm/dd')),PARTITION q3_2023 VALUES LESS THAN (TO_DATE('2023/10/01', 'yyyy/mm/dd')),PARTITION q4_2023 VALUES LESS THAN (TO_DATE('2024/01/01', 'yyyy/mm/dd')));
CREATE TABLE unisql_partition_by_range_test
(
product_id   NUMBER(6),
sale_time    TIMESTAMP(6),
sale_price   NUMBER(10,2)
)
PARTITION BY RANGE (sale_time)
(
PARTITION q1_2023 VALUES LESS THAN (TO_DATE('2023/04/01', 'yyyy/mm/dd')),
PARTITION q2_2023 VALUES LESS THAN (TO_DATE('2023/07/01', 'yyyy/mm/dd')),
PARTITION q3_2023 VALUES LESS THAN (TO_DATE('2023/10/01', 'yyyy/mm/dd')),
PARTITION q4_2023 VALUES LESS THAN (TO_DATE('2024/01/01', 'yyyy/mm/dd'))
);

-- 转换前Oracle SQL:
create table unisql_partition_by_list_test
(
id varchar2(15) not null,
city varchar2(20)
)
partition by list (city)
(
partition p1 values ('beijing'),
partition p2 values ('shanghai'),
partition p3 values ('changsha'),
partition p4 values (default)
);

-- 转换后达梦 SQL:
-- create table unisql_partition_by_list_test(id varchar2(15) not null,city varchar2(20))partition by list (city)(partition p1 values ('beijing'),partition p2 values ('shanghai'),partition p3 values ('changsha'),partition p4 values (default));
create table unisql_partition_by_list_test
(
id varchar2(15) not null,
city varchar2(20)
)
partition by list (city)
(
partition p1 values ('beijing'),
partition p2 values ('shanghai'),
partition p3 values ('changsha'),
partition p4 values (default)
);

-- 转换前Oracle SQL:
CREATE TABLE unisql_partition_by_hash_test (col1 INT, col2 VARCHAR(50), col3 TIMESTAMP )
PARTITION BY HASH (col1) PARTITIONS 4;

-- 转换后达梦 SQL:
CREATE TABLE unisql_partition_by_hash_test (col1 INT, col2 VARCHAR(50), col3 TIMESTAMP ) PARTITION BY HASH (col1) PARTITIONS 4;

8.3.5.3. 清空、删除分区表

语法

ALTER TABLE TABLE_NAME [TRUNCATE|DROP] PARTITION PARTITION_NAMES

示例

-- 转换前Oracle SQL:
ALTER TABLE unisql_partition_by_range_test TRUNCATE  PARTITION q1_2023;
ALTER TABLE unisql_partition TRUNCATE PARTITION unisql_partition_p1,unisql_partition_p2;

-- 转换后达梦 SQL:
ALTER TABLE unisql_partition_by_range_test TRUNCATE PARTITION q1_2023;
ALTER TABLE unisql_partition TRUNCATE PARTITION unisql_partition_p1;ALTER TABLE unisql_partition TRUNCATE PARTITION unisql_partition_p2;

-- 转换前Oracle SQL:
ALTER TABLE unisql_partition_by_range_test DROP  PARTITION q1_2023;
ALTER TABLE unisql_partition DROP PARTITION unisql_partition_p1,unisql_partition_p2;

-- 转换后达梦 SQL:
ALTER TABLE unisql_partition_by_range_test DROP  PARTITION q1_2023;
ALTER TABLE unisql_partition DROP PARTITION unisql_partition_p1;ALTER TABLE unisql_partition DROP PARTITION unisql_partition_p2;

8.3.5.4. 修改列的属性

语法

alter_table_stmt:
  ALTER TABLE table_name alter_table_action_list;


alter_table_action_list:
    alter_table_action [, alter_table_action ...]

alter_table_action:
    MODIFY [COLUMN] column_definition

示例

DROP TABLE unisql_modify_column_test;
CREATE TABLE unisql_modify_column_test(a int,d number);
SELECT * FROM unisql_modify_column_test;

-- 转换前Oracle SQL:
ALTER TABLE unisql_modify_column_test MODIFY (d number(10));
ALTER TABLE unisql_modify_column_test MODIFY d number(8,2) DEFAULT '12' NOT NULL;
ALTER TABLE unisql_modify_column_test MODIFY (a varchar(10),d number(10));
ALTER TABLE unisql_modify_column_test MODIFY (a varchar(10) DEFAULT '1',d number(10));
ALTER TABLE unisql_modify_column_test MODIFY (a varchar(10) DEFAULT '1' NOT NULL ,d number(10) DEFAULT 10);

-- 转换后达梦 SQL:
ALTER TABLE unisql_modify_column_test MODIFY d number(10)
ALTER TABLE unisql_modify_column_test MODIFY d number(8,2) DEFAULT '12' NOT NULL
ALTER TABLE unisql_modify_column_test MODIFY(a varchar(10) DEFAULT '1',d number(10)
ALTER TABLE unisql_modify_column_test MODIFY(a varchar(10) DEFAULT '1' NOT NULL,d number(10) DEFAULT 10)

8.3.5.5. 修改表名

语法

RENAME TABLE_NAME TO NEW_TABLE_NAME;

ALTER TABLE TABLE_NAME RENAME TO NEW_TABLE_NAME;

示例

CREATE TABLE unisql_rename_table_test(id int,name varchar(10));

-- 转换前Oracle SQL:
RENAME unisql_rename_table_test TO unisql_rename_table_test_new;
ALTER TABLE unisql_rename_table_test_new RENAME TO unisql_rename_table_test;

-- 转换后达梦 SQL:
ALTER TABLE unisql_rename_table_test RENAME TO unisql_rename_table_test_new
ALTER TABLE unisql_rename_table_test_new RENAME TO unisql_rename_table_test

8.3.5.6. 创建表

语法

CREATE [GLOBAL TEMPORARY] TABLE table_name
(table_definition_list) [partition_option] [on_commit_option]
CREATE [GLOBAL TEMPORARY] TABLE table_name
(table_definition_list) [partition_option] [AS] select;

table_definition_list:
table_definition [, table_definition ...]

table_definition:
    column_definition
    | INDEX [index_name] index_desc
    | [CONSTRAINT [constraint_name]] [PRIMARY KEY|UNIQUE]  (column_definition_list) [USING INDEX index_option_list]
    | [CONSTRAINT [constraint_name]] FOREIGN KEY (column_name, column_name ...) references_clause constraint_state
    | [CONSTRAINT [constraint_name]] CHECK(expression) constraint_state

column_definition_list:
column_definition [, column_definition ...]

column_definition:
    column_name data_type
    [VISIBLE|INVISIBLE]
    {
    [DEFAULT expression]
    [NULL | NOT NULL]
    [CONSTRAINT [constraint_name] [PRIMARY] KEY] [UNIQUE [KEY]]
    [CONSTRAINT [constraint_name] CHECK(expression)]
    [CONSTRAINT [constraint_name] references_clause]
    |
    [GENERATED ALWAYS] AS (expression) [VIRTUAL]
    [NULL | NOT NULL] [UNIQUE KEY] [[PRIMARY] KEY] [UNIQUE LOWER_KEY] [COMMENT string]
    }

references_clause:
    REFERENCES table_name [ (column_name, column_name ...) ] [ON DELETE {CASCADE}]

index_desc:
(column_desc_list) [index_option_list]

column_desc_list:
    column_desc [, column_desc ...]

column_desc:
    column_name [ASC | DESC][NULL LAST | NULL FIRST]

partition_option:
    PARTITION BY HASH(column_name_list)
    [subpartition_option] hash_partition_define
| PARTITION BY RANGE (column_name_list)
    [subpartition_option] (range_partition_list)
| PARTITION BY LIST (column_name_list)
    [subpartition_option] (list_partition_list)

on_commit_option:
ON COMMIT DELETE ROWS
| ON COMMIT PRESERVE ROWS

DEFAULT expression 可支持使用部分函数、关键字函数、字符串、常数、序列、字符串连接符。

示例

-- 转换前Oracle SQL:
CREATE TABLE kvt_ddl_1 (a NUMBER NULL, b NUMBER(5,2) NOT NULL, c NUMBER(4) DEFAULT 1 NOT NULL);
CREATE TABLE kvt_ddl_2 (id NUMBER(18) PRIMARY KEY, a FLOAT NOT NULL, b BINARY_FLOAT);
CREATE TABLE kvt_ddl_3 (id int CONSTRAINT cn_id PRIMARY key, a varchar(20) CONSTRAINT cn_a NOT NULL ,b NUMBER,c varchar(10),CONSTRAINT cn_b UNIQUE(b));
CREATE TABLE kvt_ddl_4 (id int, a varchar(20) CONSTRAINT cn4_a NOT null ,b NUMBER,c varchar(10),CONSTRAINT cn4_id PRIMARY KEY(id), CONSTRAINT cn4_b UNIQUE(b));
CREATE TABLE kvt_ddl_5 (id int, f_id int,CONSTRAINT f_id_fk FOREIGN KEY(f_id) REFERENCES kvt_ddl_3(id) );
CREATE TABLE kvt_ddl_6(id int,a int,b int CHECK(b>10),c varchar(10) CONSTRAINT cn6_c CHECK(c IN ('a','b','d')),CONSTRAINT cn6_a CHECK(a<100));
CREATE GLOBAL TEMPORARY TABLE kvt_ddl_7(id int,a int,b int);

-- 转换后达梦 SQL:
CREATE TABLE kvt_ddl_1 (a number NULL,b number(5,2) NOT NULL,c number(4) DEFAULT 1 NOT NULL);
CREATE TABLE kvt_ddl_2 (id number(18) PRIMARY KEY,a float(126) NOT NULL,b binary_float);
CREATE TABLE kvt_ddl_3 (id int PRIMARY KEY,a varchar(20) NOT NULL,b number,c varchar(10),CONSTRAINT cn_b UNIQUE(b));
CREATE TABLE kvt_ddl_4 (id int,a varchar(20) NOT NULL,b number,c varchar(10),CONSTRAINT cn4_id PRIMARY KEY(id),CONSTRAINT cn4_b UNIQUE(b));
CREATE TABLE kvt_ddl_5 (id int, f_id int,CONSTRAINT f_id_fk FOREIGN KEY(f_id) REFERENCES kvt_ddl_3(id) );
CREATE TABLE kvt_ddl_6(id int,a int,b int CHECK(b>10),c varchar(10) CONSTRAINT cn6_c CHECK(c IN ('a','b','d')),CONSTRAINT cn6_a CHECK(a<100));
CREATE GLOBAL TEMPORARY TABLE kvt_ddl_7(id int,a int,b int);

CREATE SEQUENCE unisql_default_expr_seq

-- 转换前Oracle SQL:
CREATE TABLE unisql_default_expr_table (
    col_not_null VARCHAR2 ( 1 ) DEFAULT 1 NOT NULL,
    col_current_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    col_current_localstamp DATE DEFAULT LOCALTIMESTAMP,
    col_sysdate DATE DEFAULT SYSDATE,
    col_systimestamp DATE DEFAULT SYSTIMESTAMP,
    col_name VARCHAR2(50) DEFAULT 'John Doe',
    col_to_date DATE DEFAULT TO_DATE('2000-01-01', 'YYYY-MM-DD'),
    col_nextval NUMBER DEFAULT unisql_default_expr_seq.NEXTVAL,
    col_currval NUMBER DEFAULT unisql_default_expr_seq.CURRVAL
)

-- 转换后达梦 SQL:
CREATE TABLE unisql_default_expr_table (
    col_not_null varchar2(1) DEFAULT 1 NOT NULL,
    col_current_timestamp timestamp DEFAULT CURRENT_TIMESTAMP(),
    col_current_localstamp date DEFAULT CURRENT_TIMESTAMP(),
    col_sysdate date DEFAULT SYSDATE(),
    col_systimestamp date DEFAULT SYSTIMESTAMP(),
    col_name varchar2(50) DEFAULT 'John Doe',
    col_to_date date DEFAULT TO_DATE('2000-01-01', 'YYYY-MM-DD'),
    col_nextval number DEFAULT unisql_default_expr_seq.NEXTVAL,
    col_currval number DEFAULT unisql_default_expr_seq.CURRVAL
)

8.3.5.7. 创建视图

语法

CREATE [OR REPLACE] [[NO] FORCE] VIEW view_name [(column_name_list)] AS select_stmt;

 column_name_list:
     column_name [, column_name ...]
描述
该语句用于创建视图语句,如果指定了 OR REPLACE 子句,该语句能够替换已有的视图

示例

-- 创建表
CREATE TABLE unisql_view_test(a int,b int,c varchar(10));

-- 创建视图示例
-- 转换前Oracle SQL:
CREATE VIEW unisql_view_1 AS SELECT * FROM unisql_view_test;
CREATE VIEW unisql_view_2 AS SELECT a,b FROM unisql_view_test;
CREATE VIEW public.unisql_view_3 AS SELECT a,b FROM unisql_view_test;
CREATE VIEW unisql_view_4 AS SELECT a,b FROM unisql_view_test;
CREATE VIEW unisql_view_5 AS SELECT ' ' a, ' ' b FROM dual;
CREATE VIEW unisql_view_6 AS SELECT 1 a, 2 b FROM dual;
CREATE OR REPLACE VIEW unisql_view_7 AS SELECT 1 a, 2 b FROM dual;
CREATE OR REPLACE VIEW unisql_view_8 AS SELECT 1 a, 2 b, '3' c FROM dual;
CREATE FORCE VIEW unisql_view_9 AS SELECT 1 a, 2 b, '3' c FROM dual;
CREATE NOFORCE VIEW unisql_view_10 AS SELECT 1 a, 2 b, '3' c FROM dual;
CREATE VIEW unisql_view_11(a1,b1) AS SELECT a,b FROM unisql_view_test;

-- 转换后LightDB-Oracle SQL:
CREATE VIEW unisql_view_1 AS SELECT * FROM unisql_view_test
CREATE VIEW unisql_view_2 AS SELECT a,b FROM unisql_view_test
CREATE VIEW public.unisql_view_3 AS SELECT a,b FROM unisql_view_test
CREATE VIEW unisql_view_4 AS SELECT a,b FROM unisql_view_test
CREATE VIEW unisql_view_5 AS SELECT ' ' AS a,' ' AS b FROM dual
CREATE VIEW unisql_view_6 AS SELECT 1 AS a,2 AS b FROM dual
CREATE OR REPLACE VIEW unisql_view_7 AS SELECT 1 AS a,2 AS b FROM dual
CREATE OR REPLACE VIEW unisql_view_8 AS SELECT 1 AS a,2 AS b,'3' AS c FROM dual
CREATE VIEW unisql_view_9 AS SELECT 1 AS a,2 AS b,'3' AS c FROM dual
CREATE VIEW unisql_view_10 AS SELECT 1 AS a,2 AS b,'3' AS c FROM dual
CREATE VIEW unisql_view_11 (a1,b1) AS SELECT a,b FROM unisql_view_test

8.3.5.8. 删除视图

语法

DROP VIEW [schema.] view_name [CASCADE CONSTRAINTS];
描述
该语句用于删除视图语句,该视图必须在您自己的 Schema 中,或者您必须有 DROP ANY VIEW 权限。

示例

-- 创建表
CREATE TABLE unisql_view_employees_test (
employee_id NUMBER PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
salary NUMBER
);

-- 创建视图
CREATE VIEW unisql_view_employee_names_salaries AS
SELECT first_name, salary
FROM unisql_view_employees_test;

-- 删除视图
-- 转换前Oracle SQL:
DROP VIEW unisql_view_employee_names_salaries;

-- 转换后LightDB-Oracle SQL:
DROP VIEW unisql_view_employee_names_salaries

8.3.5.9. 创建序列

语法

CREATE SEQUENCE [ schema. ] sequence_name
 { START WITH int_value
 |[ INCREMENT BY int_value ]
 |[ MINVALUE int_value | NOMINVALUE ]
 |[ MAXVALUE int_value | NOMAXVALUE ]
 |[ CACHE int_value | NOCACHE ]
 |[ ORDER | NOORDER ]
 |[ CYCLE | NOCYCLE ]
 }
 ;
描述
该语句用来创建序列。序列属于数据库对象,用户可以从序列中生成唯一整数。

参数解释

字段

描述

schema.

指定包含序列的 Schema。如果省略 Schema,则数据库会在用户当前所在的 Schema 中创建序列。

sequence_name

要创建的序列名称。

MINVALUE int_value

指定序列的最小值,int_value 的取值范围是 [-9223372036854775808,9223372036854775807]。

NOMINVALUE

NOMINVALUE 为默认值。 如果指定为 NOMINVALUE,则升序时最小值为 1,降序时最小值为 -9223372036854775808。

MAXVALUE int_value

指定序列的最大值,int_value 的取值范围是 [-9223372036854775808,9223372036854775807]。注意:同时指定 MINVALUE 和 MAXVALUE 时,MINVALUE 必须小于 MAXVALUE。MAXVALUE 和 MINVALUE 之差必须大于等于 INCREMENT BY 中 的 int_value。

NOMAXVALUE

NOMAXVALUE 为默认值。 如果指定为 NOMAXVALUE,则升序时最大值为9223372036854775807,降序时最大值为 -1。

START WITH int_value

指定序列的起始值。int_value 必须小于等于 MAXVALUE,且大于等于 MINVALUE。 如果不指定,则升序时默认取值为最小值,降序时默认取值为最大值。

INCREMENT BY int_value

指定序列的自增步数。int_value 不可以为 0。 如果指定为正数,则序列为升序;如果指定为负数,则序列为降序。 不指定时缺省值为 1。

CACHE int_value

指定在内存中预分配的自增值个数,int_value 默认为 20。CACHE int_value 的值必须大于 1,如果 CACHE INT_VALUE 的值为 1,则等价于 NOCACHE。

NOCACHE

指定序列的值为未预先分配。 如果同时省略 CACHE 和 NOCACHE,则数据库默认缓存 20 个序列号。

ORDER

指定序列的值按顺序生成。

NOORDER

NOORDER 为默认值,即不保证序列的值按顺序生成。

CYCLE

指定序列的值循环生成,即序列在达到其最大值或最小值后继续生成值。在升序达到最大值后,它会生成最小值。在降序序列达到其最小值后,它会生成其最大值。注意: 如果指定了 CYCLE,而且 INCREMENT BY int_value 小于 0 时,必须指定 MINVALUE。如果指定了 CYCLE,CACHE 的数量不能超过一个 CYCLE。

NOCYCLE

NOCYCLE 为默认值,指定序列在达到其最大值或最小值后无法生成更多值。

示例

-- 创建序列示例
-- 转换前Oracle SQL:
CREATE SEQUENCE SE_NAME MAXVALUE 100000 CYCLE;
CREATE SEQUENCE SE_NAME_1 NOCYCLE;
CREATE SEQUENCE SE_NAME_2 CACHE 20;
CREATE SEQUENCE SE_NAME_3 START WITH 1 NOCACHE;
CREATE SEQUENCE SE_NAME_4 START WITH 1 ORDER;
CREATE SEQUENCE SE_NAME_5 START WITH 1 NOORDER;
CREATE SEQUENCE SE_NAME_6 START WITH 1 KEEP;
CREATE SEQUENCE SE_NAME_7 NOKEEP START WITH 1;
CREATE SEQUENCE SE_NAME_8 NOMINVALUE MAXVALUE 9223372036854775808;
CREATE SEQUENCE SE_NAME_9 MAXVALUE 9223372036854775806;
CREATE SEQUENCE SE_NAME_10 MINVALUE -9223372036854775808 NOMAXVALUE;
CREATE SEQUENCE SE_NAME_11 MINVALUE -9223372036854775809;
CREATE SEQUENCE SE_NAME_12 MINVALUE -9999999999999999999999999999;
CREATE SEQUENCE SE_NAME_13 INCREMENT BY 9223372036854775808;
CREATE SEQUENCE SE_NAME_14 INCREMENT BY -9223372036854775809;
CREATE SEQUENCE SE_NAME_15 MINVALUE -9999999999999999999999999999;
CREATE SEQUENCE SE_NAME_16 INCREMENT BY 9223372036854775808;
CREATE SEQUENCE SE_NAME_17 INCREMENT BY -9223372036854775809;
CREATE SEQUENCE SE_NAME_18 START WITH 9223372036854775808;

-- 转换后达梦 SQL:
CREATE SEQUENCE SE_NAME MAXVALUE 100000 CYCLE;
CREATE SEQUENCE SE_NAME_1 NOCYCLE;
CREATE SEQUENCE SE_NAME_2 CACHE 20;
CREATE SEQUENCE SE_NAME_3 START WITH 1 NOCACHE;
CREATE SEQUENCE SE_NAME_4 START WITH 1 ORDER;
CREATE SEQUENCE SE_NAME_5 START WITH 1 NOORDER;
CREATE SEQUENCE SE_NAME_6 START WITH 1 KEEP; --不支持
CREATE SEQUENCE SE_NAME_7 NOKEEP START WITH 1; --不支持
CREATE SEQUENCE SE_NAME_8 NOMINVALUE MAXVALUE 9223372036854775808;
CREATE SEQUENCE SE_NAME_9 MAXVALUE 9223372036854775806;
CREATE SEQUENCE SE_NAME_10 MINVALUE -9223372036854775808 NOMAXVALUE;
CREATE SEQUENCE SE_NAME_11 MINVALUE -9223372036854775809;
CREATE SEQUENCE SE_NAME_12 MINVALUE -9999999999999999999999999999;
CREATE SEQUENCE SE_NAME_13 INCREMENT BY 9223372036854775808; --不支持
CREATE SEQUENCE SE_NAME_14 INCREMENT BY -9223372036854775809; --不支持
CREATE SEQUENCE SE_NAME_15 MINVALUE -9999999999999999999999999999;
CREATE SEQUENCE SE_NAME_16 INCREMENT BY 9223372036854775808; --不支持
CREATE SEQUENCE SE_NAME_17 INCREMENT BY -9223372036854775809; --不支持
CREATE SEQUENCE SE_NAME_18 START WITH 9223372036854775808;

8.3.5.10. 同义词

描述
同义词 (Synonym)是 Oracle 租户中表、视图、物化视图、序列、存储过程、函数、包、类型、用户自定义类型,或是其他的同义词的别名。由于其只是一个别名,所以除了在数据字典中的定义不占任何空间。本文主要介绍同义词的分类、基本特性和权限要求。
分类
  • 同义词有两种类型,Public 同义词和 Private 同义词。

  • Public 同义词属于 PUBLIC 组,每个用户都可以访问。Private 同义词属于对象所有者,只有其显式授权后其他用户才可访问。

  • 公有同义词一般由 DBA 创建,普通用户如果希望创建公有同义词,则需要 CREATE PUBLIC SYNONYM 系统权限。

基本特性
同义词扩展了数据库的使用范围,能够在不同的数据库用户之间实现无缝交互。经常用于简化对象访问和提高对象访问的安全性。

8.3.5.10.1. 创建同义词

语法

CREATE [ OR REPLACE ] [ EDITIONABLE | NONEDITIONABLE ]
[ PUBLIC ] SYNONYM
[ schema. ] synonym
[ SHARING = { METADATA | NONE } ]
FOR [ schema. ] object [ @ dblink ] ;

备注

[ EDITIONABLE | NONEDITIONABLE ]和[ SHARING = { METADATA | NONE } ] 在达梦中将被作为语法糖处理,[ @ dblink ]暂不支持!

参数解释

参数

说明

OR REPLACE

表示如果要创建的同义词名称已存在,则使用新的定义替换同义词。

EDITIONABLE/NONEDITIONABLE

如果在模式中为模式对象类型SYNONYM启用了编辑,请使用这些子句来指定同义词是已编辑对象还是非版本对象。对于私人同义词,默认是EDITABLE。对于公共同义词,默认值为NONEDITIONAL。

PUBLIC

指定 PUBLIC 来创建公共同义词,所有用户都可以使用。用户必须对基础对象具有相应的权限才能使用该同义词。 在解析对象的引用时,仅当对象没有指定 Schema 时,才会使用公共同义词。 如果不指定 PUBLIC,则同义词是私有的,只能由当前 Schema 访问,并且同义词名称在当前 Schema 中必须唯一。

[schema. ]synonym

Schema 指定当前同义词属于哪个用户。如果指定了 PUBLIC,则对同义词不能指定用户。 synonym 表示同义词的名称。

[ SHARING = { METADATA/NONE } ]

此子句仅在应用程序根目录中创建同义词时适用。这种类型的同义词称为应用程序公共对象,它可以与属于应用程序根的应用程序 PDB 共享。要确定同义词的共享方式,请指定以下共享属性之一:METADATA - 元数据链接共享同义词的元数据,但其数据对于每个容器都是唯一的。这种类型的同义词被称为元数据链接的应用程序公共对象。NONE - 不共享同义词。如果省略此子句,则数据库将使用 DEFAULT_SHARING 初始化参数的值来确定同义词的共享属性。如果 DEFAULT_SHARING 初始化参数没有值,则默认值为 METADATA。

[schema. ]object

表示同义词对应对象的名称。

[ @ dblink ]

暂不支持

示例

-- 转换前Oracle SQL:
CREATE OR REPLACE EDITIONABLE SYNONYM employee SHARING = METADATA FOR user2.emp;


-- 转换后达梦 SQL:
CREATE OR REPLACE SYNONYM employee FOR user2.emp;

8.3.5.10.2. 删除同义词

语法

DROP [PUBLIC] SYNONYM [ schema. ] synonym [FORCE] ;

备注

[FORCE] 在达梦中将被作为语法糖处理!

参数解释

参数

说明

PUBLIC

指定 PUBLIC 来删除公共同义词。如果不指定 PUBLIC,则删除私有同义词。

[schema. ]synonym

Schema 指定当前同义词属于哪个用户。如果指定了 PUBLIC,则对同义词不能指定用户。 synonym 表示同义词的名称。

FORCE

指定 FORCE 来删除同义词,即使它具有依赖表或用户定义类型。

示例

-- 转换前Oracle SQL:
DROP PUBLIC SYNONYM user1.employee FORCE;


-- 转换后达梦 SQL:
DROP PUBLIC SYNONYM user1.employee;