英文:
Retuning statement with dblink gives error
问题
我已经创建了一个带有生成的身份列的表。下面是脚本:
CREATE TABLE "TABLESAMPLE"
("DESCRIPTION" VARCHAR2(2 BYTE),
"TID" NUMBER(5,0) GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 99 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE
) SEGMENT CREATION DEFERRED
我正在使用dblink从远程数据库插入数据,如下所示。在这里,当我返回id时,我得到以下错误(RETURNING):
Insert into TABLESAMPLE@dblink1(DESCRIPTION) values('1') RETURNING tid INTO v_tid_return;
*原因:目前不支持对象类型列、LONG列、远程表、带子查询的INSERT以及INSTEAD OF触发器的RETURNING子句。
我正在使用Oracle SQL Developer运行脚本。能否请您帮忙解决这个问题?
英文:
I have created a table with generated identity column .script below
CREATE TABLE "TABLESAMPLE"
( "DESCRIPTION" VARCHAR2(2 BYTE),
"TID" NUMBER(5,0) GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 99 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE
) SEGMENT CREATION DEFERRED
i am inserting data to the db from a remote database using dblink like below. Here when i return the id i get the below error on (RETURNING )
Insert into TABLESAMPLE@dblink1(DESCRIPTION) values('1') RETURNING tid INTO v_tid_return;
*Cause: RETURNING clause is currently not supported for object type
columns, LONG columns, remote tables, INSERT with subquery,
and INSTEAD OF Triggers.
I am using oracle sql developer to run the script. can you please help
答案1
得分: 0
以下是您请求的内容的翻译:
原因: 目前不支持对象类型列、LONG列、远程表、带子查询的INSERT以及INSTEAD OF触发器的RETURNING子句。
通过数据库链接的表是远程表。
Mike
是通过数据库链接访问的用户:
SQL> 连接 mike/lion@pdb1
已连接。
SQL> 创建表 tablesample
2 (description varchar2(2),
3 tid number 作为标识始终生成
4 );
表已创建。
SQL> 插入到 tablesample(description) values ('LF');
已创建 1 行。
SQL> 从 tablesample 中选择 *;
DE TID
LF 1
回到 scott
(其中包含到用户 mike
的数据库链接):
SQL> 连接 scott/tiger@pdb1
已连接。
SQL> 打开服务器输出
SQL> 声明
2 l_tid number;
3 开始
4 插入到 tablesample@dbl_mike (description) values ('XY')
5 返回 tid 到 l_tid;
7 dbms_output.put_line('返回值 = ' || l_tid);
8 结束;
9 /
声明
*
第 1 行处出现错误:
ORA-22816: RETURNING 子句不支持的不受支持功能
ORA-06512: 第 4 行处
在我的模式中使用同义词有帮助吗?不幸的是,不行:
SQL> 创建同义词 scott_tablesample for tablesample@dbl_mike;
同义词已创建。
SQL> 声明
2 l_tid number;
3 开始
4 插入到 scott_tablesample (description) values ('XY')
5 返回 tid 到 l_tid;
6 dbms_output.put_line('返回值 = ' || l_tid);
7 结束;
8 /
声明
*
第 1 行处出现错误:
ORA-22816: RETURNING 子句不支持的不受支持功能
ORA-06512: 第 4 行处
要做什么?关于 returning
子句,没有太多可以做的。如果重新创建表,以便 ID 不是始终生成的(即,您可以插入自己的值):
SQL> 连接 mike/lion@pdb1
已连接。
SQL> 删除表 tablesample;
已删除表。
SQL> 创建表 tablesample
2 (description varchar2(2),
3 tid number 在空值时默认生成为标识
4 );
表已创建。
SQL> 插入到 tablesample(description) values ('AB');
已创建 1 行。
SQL> 从 tablesample 中选择 *;
DE TID
AB 1
查找用于标识列的序列:
SQL> 从 user_tab_columns 中选择 data_default where table_name = 'TABLESAMPLE';
DATA_DEFAULT
"MIKE"."ISEQ$$_99985".nextval
连接为 scott
,创建一个到序列的同义词并在 insert
语句中使用它:
SQL> 连接 scott/tiger@pdb1
已连接。
SQL> 创建同义词 mike_seq for iseq$$_99985@dbl_mike;
同义词已创建。
插入:
SQL> 声明
2 l_seq number;
3 开始
4 l_seq := mike_seq.nextval;
5 插入到 tablesample@dbl_mike (description, tid)
6 values ('MN', l_seq);
7 dbms_output.put_line('TID = ' || l_seq);
8 结束;
9 /
PL/SQL 过程已成功完成。
SQL> 从 tablesample@dbl_mike 中选择 *;
DE TID
MN 2 --> 在这里
AB 1
[编辑]
如果要获取用于标识列的序列名称,请查询
SQL> 从 user_tab_identity_cols 中选择 sequence_name where table_name = 'TABLESAMPLE';
SEQUENCE_NAME
ISEQ$$_99985
[编辑 #2]
如果要在 PL/SQL 过程中使用序列名称,您将需要动态 SQL。此外,如果在此会话中尚未初始化序列,currval
将不起作用:
SQL> 显示用户
USER is "SCOTT"
SQL> 打开服务器输出
SQL> 声明
2 v_seq_name varchar2(20);
3 v_str varchar2(200);
4 v_val number;
5 开始
6 从 user_tab_identity_cols@dbl_mike 中选择 sequence_name
7 into v_seq_name
8 where table_name = 'TABLESAMPLE';
10 v_str := 'select ' || v_seq_name || '.currval@dbl_mike from dual';
11 执行立即 v_str into v_val;
12 dbms_output.put_line('值 = ' || v_val);
13 结束;
14 /
声明
*
第 1 行处出现错误:
ORA-08002: 序列 ISEQ$$_99985.CURRVAL 在此会话中尚未定义
ORA-02063: 来自 DBL_MIKE 的前一行
ORA-06512: 第 12 行处
因此,请使用 nextval
:
SQL> 声明
2 v_seq_name varchar2(20);
3 v_str varchar2(200);
4 v_val number;
5 开始
6 从 user_tab_identity_cols@dbl_mike 中选择 sequence_name
7 into v_seq_name
8 where table_name = 'TABLESAMPLE';
10 v_str := 'select ' || v_seq_name || '.nextval@dbl_mike from dual';
11 执行立即 v_str into v_val;
12 dbms_output.put_line('值 = ' || v_val);
13 结束;
14 /
值 = 7
PL/SQL 过程已成功完成。
SQL>
英文:
As it says:
> Cause: RETURNING clause is currently not supported for object type columns, LONG columns, remote tables, INSERT with subquery, and INSTEAD OF Triggers.
Table over a database link is a remote table.
Mike
is user accessed via database link:
SQL> connect mike/lion@pdb1
Connected.
SQL> create table tablesample
2 (description varchar2(2),
3 tid number generated always as identity
4 );
Table created.
SQL> insert into tablesample(description) values ('LF');
1 row created.
SQL> select * from tablesample;
DE TID
-- ----------
LF 1
Back to scott
(it contains database link to user mike
):
SQL> connect scott/tiger@pdb1
Connected.
SQL> set serveroutput on
SQL> declare
2 l_tid number;
3 begin
4 insert into tablesample@dbl_mike (description) values ('XY')
5 returning tid into l_tid;
6
7 dbms_output.put_line('Returned value = ' || l_tid);
8 end;
9 /
declare
*
ERROR at line 1:
ORA-22816: unsupported feature with RETURNING clause
ORA-06512: at line 4
Would a synonym in my own schema help? Unfortunately, not:
SQL> create synonym scott_tablesample for tablesample@dbl_mike;
Synonym created.
SQL> declare
2 l_tid number;
3 begin
4 insert into scott_tablesample (description) values ('XY')
5 returning tid into l_tid;
6 dbms_output.put_line('Returned value = ' || l_tid);
7 end;
8 /
declare
*
ERROR at line 1:
ORA-22816: unsupported feature with RETURNING clause
ORA-06512: at line 4
What to do? Nothing much, regarding the returning
clause. If you recreated the table so that the ID isn't generated always (i.e. you're allowed to insert your own values):
SQL> connect mike/lion@pdb1
Connected.
SQL> drop table tablesample;
Table dropped.
SQL> create table tablesample
2 (description varchar2(2),
3 tid number generated by default on null as identity
4 );
Table created.
SQL> insert into tablesample(description) values ('AB');
1 row created.
SQL> select * From tablesample;
DE TID
-- ----------
AB 1
Find which sequence is being used for the identity column:
SQL> select data_default from user_tab_columns where table_name = 'TABLESAMPLE';
DATA_DEFAULT
--------------------------------------------------------------------------------
"MIKE"."ISEQ$$_99985".nextval
Connected as scott
, create a synonym to the sequence and use it in insert
statement:
SQL> connect scott/tiger@pdb1
Connected.
SQL> create synonym mike_seq for iseq$$_99985@dbl_mike;
Synonym created.
Insert:
SQL> declare
2 l_seq number;
3 begin
4 l_seq := mike_seq.nextval;
5 insert into tablesample@dbl_mike (description, tid)
6 values ('MN', l_seq);
7 dbms_output.put_line('TID = ' || l_seq);
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select * from tablesample@dbl_mike;
DE TID
-- ----------
MN 2 --> here it is
AB 1
SQL>
[EDIT]
If you want to get sequence name used for identity column, query
SQL> select sequence_name
2 from user_tab_identity_cols
3 where table_name = 'TABLESAMPLE';
SEQUENCE_NAME
--------------------------------------------------------------------------------
ISEQ$$_99985
SQL>
[EDIT #2]
If you want to use sequence name in PL/SQL procedure, you'll need dynamic SQL. Apart from that, currval
won't work if sequence hasn't been initialized yet in this session:
SQL> show user
USER is "SCOTT"
SQL> set serveroutput on
SQL> declare
2 v_seq_name varchar2(20);
3 v_str varchar2(200);
4 v_val number;
5 begin
6 select sequence_name
7 into v_seq_name
8 from user_tab_identity_cols@dbl_mike
9 where table_name = 'TABLESAMPLE';
10
11 v_str := 'select ' || v_seq_name || '.currval@dbl_mike from dual';
12 execute immediate v_str into v_val;
13 dbms_output.put_line('Value = ' || v_val);
14 end;
15 /
declare
*
ERROR at line 1:
ORA-08002: sequence ISEQ$$_99985.CURRVAL is not yet defined in this session
ORA-02063: preceding line from DBL_MIKE
ORA-06512: at line 12
Therefore, use nextval
:
SQL> declare
2 v_seq_name varchar2(20);
3 v_str varchar2(200);
4 v_val number;
5 begin
6 select sequence_name
7 into v_seq_name
8 from user_tab_identity_cols@dbl_mike
9 where table_name = 'TABLESAMPLE';
10
11 v_str := 'select ' || v_seq_name || '.nextval@dbl_mike from dual';
12 execute immediate v_str into v_val;
13 dbms_output.put_line('Value = ' || v_val);
14 end;
15 /
Value = 7
PL/SQL procedure successfully completed.
SQL>
答案2
得分: 0
错误提示说不支持此操作。但是,您可以使用 dbms_sql
包通过 DB 链接执行远程 SQL 代码。
表格是空的。
值已成功插入。
英文:
As error says, it is not supported. However, you may use dbms_sql
package over DB link to execute remote SQL code.
>
> SQL> declare
> 2 l_id int;
> 3 l_value constant int := 100;
> 4 begin
> 5 insert into t@test2_dblink(val)
> 6 values(l_value)
> 7 returning id into l_id;
> 8
> 9 dbms_output.put_line(l_id);
> 10 end;
> 11 /
>
> Error starting at line : 5 in command -
> declare
> l_id int;
> l_value constant int := 100;
> begin
> insert into t@test2_dblink(val)
> values(l_value)
> returning id into l_id;
>
> dbms_output.put_line(l_id);
> end;
> Error report -
> ORA-22816: с фразой RETURNING это средство не поддерживается
> ORA-06512: на line 5
> 22816. 00000 - "unsupported feature with RETURNING clause"
> *Cause: RETURNING clause is currently not supported for object type
> columns, LONG columns, remote tables, INSERT with subquery,
> and INSTEAD OF Triggers.
> *Action: Use separate select statement to get the values.
>
>
Table is empty.
>
> SQL> select *
> 2 from t@test2_dblink
> 3 /
>
> 0 rows selected.
>
>
> SQL> declare
> 2 l_id int;
> 3 l_value constant int := 100;
> 4 l_cursor int;
> 5 l_stmt varchar2(1000);
> 6 l_rowcount int;
> 7 begin
> 8 l_stmt := q'{insert into t(val)
> 9 values(:value)
> 10 returning id into :id}';
> 11
> 12 l_cursor := dbms_sql.open_cursor@test2_dblink();
> 13 dbms_sql.parse@test2_dblink(l_cursor, l_stmt, dbms_sql.native);
> 14
> 15 dbms_sql.bind_variable@test2_dblink(l_cursor, 'value', l_value);
> 16 dbms_sql.bind_variable@test2_dblink(l_cursor, 'id', l_id);
> 17 l_rowcount := dbms_sql.execute@test2_dblink(l_cursor);
> 18 dbms_sql.variable_value@test2_dblink(l_cursor, 'id', l_id);
> 19 dbms_sql.close_cursor@test2_dblink(l_cursor);
> 20
> 21
> 22 dbms_output.put_line('ID is: ' || l_id);
> 23 commit;
> 24 end;
> 25 /
>
> ID is: 3
>
>
> PL/SQL procedure successfully completed.
>
Value was inserted successfully.
>
> SQL> select *
> 2 from t@test2_dblink
> 3 /
>
> ID VAL
> ---------- ----------
> 3 100
>
> 1 row selected.
>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论