LightDB 支持 ignore_row_on_dupkey_index hint
LightDB 从23.4 开始支持oracle的 ignore_row_on_dupkey_index hint, 这个hint是用来忽略唯一键冲突的。类似与mysql的 insert ignore。
语法如下:
在LightDB中ignore_row_on_dupkey_index的效果等同于on conflict do nothing 子句。
下面说明一下这个hint的注意点以及使用示例。
注意点
- 您必须指定一个正确的索引。如果没有指定索引,那么该语句将导致LT008错误(oracle是ORA-38912)。
- 如果指定了多个索引,那么该语句会导致LT010错误(oracle是ORA-38915)。
- 如果指定了index,那么索引必须存在且唯一。否则,该语句导致LT009错误(oracle是ORA-38913)。
- IGNORE_ROW_ON_DUPKEY_INDEX提示仅适用于单表插入操作。
- 如果指定的列对应有多个索引,那么这条语句会导致LT010错误(oracle没有这个特性,因为同一个字段不能有多个索引)。
- 不能与on conflict 一起使用(oracle 没有on conflict)
- 在Canopy 下,目前只支持对insert select 使用,且select 的表也需要为分布式表。
note
在ltsql 中可以通过\errverbose 查看错误码及其他详细信息
lightdb@postgres=# \errverbose
ERROR: LT008: An index must be specified in the index hint
LOCATION: IgnoreDupKeyHintParse, pg_hint_plan.c:7232
lightdb@postgres=#
使用示例
初始化
create table test_ignore_dupkey(key1 int, key2 int, key3 int, key4 int);
create unique index test_ignore_dupkey_ui1 on test_ignore_dupkey(key1, key2);
create unique index test_ignore_dupkey_ui2 on test_ignore_dupkey(key3, key4);
create index test_ignore_dupkey_i on test_ignore_dupkey(key3);
示例
lightdb@postgres=# insert into test_ignore_dupkey values(1, 1, 1, 1);
INSERT 0 1
lightdb@postgres=# insert into test_ignore_dupkey values(1, 1, 1, 1);
ERROR: duplicate key value violates unique constraint "test_ignore_dupkey_ui1"
DETAIL: Key (key1, key2)=(1, 1) already exists.
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_ui1) */ into test_ignore_dupkey values(1, 1, 1, 2);
INSERT 0 0
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey(key1, key2)) */ into test_ignore_dupkey values(1, 1, 1, 2);
INSERT 0 0
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey) */ into test_ignore_dupkey values(1, 1, 1, 2);
ERROR: An index must be specified in the index hint
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_ui3) */ into test_ignore_dupkey values(1, 1, 1, 2);
ERROR: An index must be specified in the index hint
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_i) */ into test_ignore_dupkey values(1, 1, 1, 2);
ERROR: Index specified in the index hint is invalid
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_ui1 test_ignore_dupkey_ui2) */ into test_ignore_dupkey values(1, 1, 1, 2);
ERROR: Multiple indexes in ignore duplicate key hint
lightdb@postgres=# update/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_ui1) */ test_ignore_dupkey set key2 = 2 where key1 = 1;
ERROR: IGNORE_ROW_ON_DUPKEY_INDEX hint disallowed for this operation
lightdb@postgres=# create unique index test_ignore_dupkey_ui3 on test_ignore_dupkey(key3, key4);
CREATE INDEX
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey(key3, key4)) */ into test_ignore_dupkey values(1, 2, 1, 1);
ERROR: Multiple indexes in ignore duplicate key hint
DETAIL: find multiple indexes by fields
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey test_ignore_dupkey_ui1) */ into test_ignore_dupkey values(1, 1, 1, 2)
lightdb@postgres-# on conflict (key1, key2) do nothing;
ERROR: IGNORE_ROW_ON_DUPKEY_INDEX hint disallowed for this operation
DETAIL: insert operation with on confict clause is not supported
lightdb@postgres=#
下面与 oracle 不同, 对于(test_ignore_dupkey()), oracle 是hint语法错误,不会报错
lightdb@postgres=# insert/*+IGNORE_ROW_ON_DUPKEY_INDEX(test_ignore_dupkey()) */ into test_ignore_dupkey values(1, 2, 1, 1);
ERROR: An index must be specified in the index hint