我正在使用 3 个不同的系统,需要跨系统获取数据。我们在中间使用 SAS,我需要它的目的基本上是从 GCP 表中执行 SELECT *,执行几个步骤(例如创建一些 CSV 和本地数据表),最后将整个表上传到远程 Oracle 服务器。
我的问题是原始列的顺序与最终 Oracle 表中的顺序不同。我在 SAS 中执行的步骤之一是从目标表中按顺序收集列名称并将其存储在临时表中。
有什么方法可以将存储在表中的列用作 INSERT 语句中的嵌套查询吗?我的问题是,在源位置可以随时添加列,但在目的地(已经添加这些列的位置)很可能会采用不同的顺序。
我正在尝试做这样的事情(实际上没有运行SQL):
INSERT INTO destination_table SELECT ( SELECT * FROM temp_columns_table ) FROM original_table
这将代替正常的:
INSERT INTO destination_table SELECT col_1, col_2, col_3 FROM original_table
这样做的原因是,更改可能会很快失败,而无需编辑 SAS 文件来添加新列,这可能需要长达一周的时间才能到达生产服务器。如果我设法做这样的事情,我可以在几个小时内添加一个新列。
提前致谢!
除了尝试类似上面的方法之外,我还尝试在 SELECT 之后“转换”列名称,并使用它在 INSERT 处显式声明列名称。没有任何效果。
在我看来,你不应该寻找任何类型的捷径。
从你的角度来看,最无聊和最不想要的方式实际上是你可以采取的最好方式。
insert into destination_table
(id, name, address, whatever)
select id, name, address, whatever
from original_table;
任何其他情况都会导致错误和错误导入的数据。尽管通配符对于快速执行某些操作来说非常有用,但我不建议您在生产中使用它们。无法保证列顺序在三个(!)系统中始终匹配。
想象一个简单的例子:您必须将 city
和
country
添加到表格中。不过,由于您无权访问第一个系统,因此被允许这样做的开发人员会通知您他们已经这样做了。 “酷”,你会说,“我也会添加它们”。但他们并没有说他们先添加了
country
,然后添加了city
。使用通配符,insert into target select * from source
可以正常工作,因为城市和国家都是字符串,你最终会得到
城市=法国 国家=巴黎column_id
SQL> select column_name, data_type, column_id
2 from user_tab_columns where table_name = 'DEPT'
3 order by column_id;
COLUMN_NAM DATA_TYPE COLUMN_ID
---------- ---------- ----------
DEPTNO NUMBER 1
DNAME VARCHAR2 2
LOC VARCHAR2 3
SQL>
user_tab_columns
中提取信息并动态
创建
insert
语句的代码,例如
SQL> select 'insert into destination_table (' ||
2 listagg(column_name, ', ') within group (order by column_id) || ') ' ||
3 'select ' ||
4 listagg(column_name, ', ') within group (order by column_id) ||
5 ' from original_table' as stmt
6 from user_tab_columns
7 where table_name = 'DEPT';
STMT
----------------------------------------------------------------------------------------------------
insert into destination_table (DEPTNO, DNAME, LOC) select DEPTNO, DNAME, LOC from original_table
SQL>
(或其任何衍生物;包括 PL/SQL)但是 - 再一次 - 如果我是你,我就不会这样做。