聚合 nvarchar2 列并在 nvarchar2 中获得结果

Ros*_*oss 3 oracle oracle-11g

我需要创建一个带有聚合列的视图 nvarchar2(4000)在 Oracle 11g 中。

我拥有的:

Table1每一列类型nvarchar2(4000)

Col_Name   txt_value
X                   a
X                   b
X                   c
Y                   a
Y                   c
Run Code Online (Sandbox Code Playgroud)

结果应该是这样的视图,两列类型为nvarchar2(4000)

Col_Name   txt_value
X                   a;b;c
Y                   a;c
Run Code Online (Sandbox Code Playgroud)

我试过:

CREATE VIEW dict (col_Name, txt_value) AS 
SELECT col_Name, LISTAGG (txt_value,';') WITHIN GROUP (ORDER BY txt_value)
FROM table1
GROUP BY col_Name 
Run Code Online (Sandbox Code Playgroud)

唯一的问题是LISTAGG()将结果转换为varchar2(4000)我需要的 bit类型的列nvarchar2

Bal*_*app 5

正如文档所描述的:

如果度量列是 RAW,则返回数据类型是 RAW;否则返回值为 VARCHAR2。

因此,除非您将列作为 传递,否则RAW结果将是VARCHAR2,这还不够好,因为这意味着转换过程中数据丢失。

LISTAGGVARCHAR2or 一起使用RAW,所以简单地说,您需要将所有内容转换为RAW,然后将结果转换回NVARCHAR2.

下面是一个例子:

SQL> select parameter, value from nls_database_parameters where parameter like '%CHARACTERSET';

PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_CHARACTERSET               EE8ISO8859P2
NLS_NCHAR_CHARACTERSET         AL16UTF16
Run Code Online (Sandbox Code Playgroud)

我的默认字符集不支持符号。

SQL> create table t1 (id number, c1 varchar2(20), c2 nvarchar2(20));

Table created.

SQL> insert into t1 values (1, 'A', 'A');

1 row created.

SQL> insert into t1 values (2,  NCHR(8364),  NCHR(8364));

1 row created.

SQL> commit;

Commit complete.

SQL> select * from t1;

        ID C1 C2
---------- -- --
         1 A  A
         2 ?  €
Run Code Online (Sandbox Code Playgroud)

如您所见,我?使用VARCHAR2.

如果我只是尝试LISTAGGNVARCHAR2列上使用,则在转换过程中数据将丢失:

select
  listagg(c2, ',') within group (order by id) as list1
from t1;

LIST1
----------
 A, ?
Run Code Online (Sandbox Code Playgroud)

如果我尝试转换结果,仍然不够好,因为在转换为VARCHAR2

select
  cast(listagg(c2, ',') within group (order by id) as nvarchar2(20)) as list2
from t1;

LIST2
----------
 A, ?
Run Code Online (Sandbox Code Playgroud)

剩下的选项是转换为RAW

select
  utl_raw.cast_to_nvarchar2(listagg(utl_raw.cast_to_raw(c2), utl_raw.cast_to_raw(',')) within group (order by id)) as list3
from t1;

LIST3
----------
A?
Run Code Online (Sandbox Code Playgroud)

转换VARCHAR2分隔符会弄乱数据,我还需要在 中指定分隔符NVARCHAR2,因此','我必须使用N','

select
  utl_raw.cast_to_nvarchar2(listagg(utl_raw.cast_to_raw(c2), utl_raw.cast_to_raw(N',')) within group (order by id)) as list4
from t1;

LIST4
----------
A,€ 
Run Code Online (Sandbox Code Playgroud)