Oracle 从 varray 更改列数据类型

Posted

技术标签:

【中文标题】Oracle 从 varray 更改列数据类型【英文标题】:Oracle change column datatype from varray 【发布时间】:2021-07-16 15:27:34 【问题描述】:

在 Oracle 数据库中,我有两个模式,其中两个表相互镜像,除了两个表中的一列是数字可变数组,但在模式 A 中是 A.VARRAY,在模式 B 中是 B.VARRAY

因此,我无法在表之间迁移数据,因为它们具有不一致的数据类型

有什么方法可以将列数据类型从A.varray 更改为B.varray 而不会丢失数据?

【问题讨论】:

请显示您的 VARRAY 的 DDL。据我记得,如果它们的类型相同,它们可以隐式转换。 两者相同,只是存在于不同的架构中:CREATE OR REPLACE TYPE V_TYPE AS VARRAY(5000) OF NUMBER(1) 【参考方案1】:

只需使用cast(col as B.VARRAYTYPE):

SQL> CREATE OR REPLACE TYPE V_TYPE_1 AS VARRAY(5000) OF NUMBER(1);
  2  /

Type created.

SQL> CREATE OR REPLACE TYPE V_TYPE_2 AS VARRAY(5000) OF NUMBER(1);
  2  /

Type created.

SQL> create table t1 (a V_TYPE_1);

Table created.

SQL> insert into t1 values(v_type_1(1,2,3,4,5));

1 row created.

SQL> create table t2 (a V_TYPE_2);

Table created.

SQL> insert into t2 select cast(a as v_type_2) from t1;

1 row created.

SQL> select * from t2;

A
-------------------------
V_TYPE_2(1, 2, 3, 4, 5)

1 row selected.

【讨论】:

【参考方案2】:

CAST 是,我同意Sayan。不过,由于涉及到两个用户,因此需要一些中间步骤 - grant execute on type 是最重要的,我想说。这是一个例子。

我的用户是scottmike。它们中的每一个都有相同的表描述。 scott 应该将行插入到mike 的表中。

连接为scott:

SQL> show user
USER is "SCOTT"
SQL> create or replace type v_type as varray(5000) of number(1);
  2  /

Type created.

SQL> create table test (id number, a v_type);

Table created.

SQL> insert into test(id, a) values (1, v_type(1));

1 row created.

SQL>

连接为mike:使用与scott相同的类型:

SQL> show user
USER is "MIKE"
SQL> create or replace type v_type as varray(5000) of number(1);
  2  /

Type created.

SQL> create table test (id number, a v_type);

Table created.

SQL> grant insert on test to scott;

Grant succeeded.

SQL>

scott 连接,尝试将行插入mike 的表:

SQL> show user
USER is "SCOTT"
SQL> insert into mike.test (id, a) select id, a from test;
insert into mike.test (id, a) select id, a from test
                                         *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected MIKE.V_TYPE got SCOTT.V_TYPE

我们试试CAST:

SQL> insert into mike.test (id, a) select id, cast(a as mike.v_type) from test;
insert into mike.test (id, a) select id, cast(a as mike.v_type) from test
                                                   *
ERROR at line 1:
ORA-00904: : invalid identifier


SQL>

为了使其工作,mike 必须将其类型上的执行授予scott

SQL> show user
USER is "MIKE"
SQL> grant execute on v_type to scott;

Grant succeeded.

SQL>

终于,它起作用了

SQL> show user
USER is "SCOTT"
SQL> insert into mike.test (id, a) select id, cast(a as mike.v_type) from test;

1 row created.

SQL>

【讨论】:

【参考方案3】:

您是否愿意在其中一个表中添加一列,用另一列中的值填充新列,例如通过更新语句,然后删除旧列?

T1(c1 V_TYPE_1); T2(c1 V_TYPE_2);

(1) 将列添加到 T2: T2(c1 V_TYPE_2, c2 V_TYPE_1);

(2) 更新 T2,使 c1 和 c2 对于每一行都是相同的值。

(3) 从 T2 中删除旧列: T2(c2 V_TYPE_1);

如果表不活动,此解决方案会更容易一些。如果表处于活动状态,您将需要添加一个触发器,以便两列同步。

【讨论】:

以上是关于Oracle 从 varray 更改列数据类型的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 和 Oracle VARRAYS/嵌套表

Oracle PL/SQL:如何从 VARRAY 的 REF 中进行 DEREF?

Oracle SQL 在包含数据时将列类型从数字更改为 varchar2

oracle 如何将字段类型varchar 改为blob 更改提示数据类型的变更无效

如何在表列中访问 SQL 中的 varray 元素

如何使用 varray 在 oracle 函数中接收多个参数