将具有动态列数的单行转换为 Oracle 中的单列

Convert a single row with dynamic number of columns into a single column in Oracle

我必须将通过 select 语句获得的单行转换为单列,并将结果的各个列的值串联起来。问题是这些列是未知的,并且数量可能会有所不同。

假设 table 看起来类似于:

Table USER
Name  Surname  Age  Logindate  City

Max   Smith    25   20.05.20   NY

我需要 SELECT * FROM USER 并将结果转换为单个字符串,例如 Max, Smith, 25, 20.05.20, NY 或带有列名 Name: Max, Surname: Smith, Age: 25, Logindate: 20.05.20, City: NY 的字符串,之后我可以将其插入其他 [=28= 的列中].我 select 来自的 table 的名称是已知的,并被硬编码到在存储过程中执行的 SELECT 语句中。

由于列数和列名未知,我无法使用 CONCAT 函数。 SELECT JSON_OBJECT(*) FROM USER 的输出格式我也很满意,但是在 Oracle18c 中不支持使用星号运算符的函数(在 Oracle19c 中)。

将单行的列值转换为单个字符串似乎是一个基本操作,但我找不到任何简单的解决方案。

使用数据字典生成正确的SQL语句,然后使用动态SQL执行。

--Sample tables for input and output:
create table user_table as
select 'Max' Name, 'Smith' Surname, 25 Age, date '2020-05-20' LoginDate, 'NY' City
from dual;

create table concatenated_values(value varchar2(4000));


--Procedure to read all columns from USER_TABLE and write them to CONCATENATED_VALUES.
create or replace procedure concatenate_values(p_table_name varchar2) is
    v_sql varchar2(4000);
begin
    --Generate a SQL statement to concatenate all the values.
    select
        'select ' ||
        listagg(column_name, '||'',''||') within group (order by column_id) ||
        ' from ' || owner || '.' || table_name
    into v_sql
    from all_tab_columns
    where owner = user
        and table_name = p_table_name
    group by owner, table_name;

    --Run the SQL statement and insert the value.
    execute immediate 'insert into concatenated_values ' || v_sql;
end;
/


--Call the procedure.
begin
    concatenate_values('USER_TABLE');
end;
/


--Results:
select * from concatenated_values;

VALUE
-------------------------
Max,Smith,25,20-MAY-20,NY