返回带有dblink的语句会出错。

huangapple go评论58阅读模式
英文:

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.
>

huangapple
  • 本文由 发表于 2023年6月8日 02:16:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76426049.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定