我需要创建一个带有聚合列的视图 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。
正如文档所描述的:
如果度量列是 RAW,则返回数据类型是 RAW;否则返回值为 VARCHAR2。
因此,除非您将列作为 传递,否则RAW结果将是VARCHAR2,这还不够好,因为这意味着转换过程中数据丢失。
LISTAGG与VARCHAR2or 一起使用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.
如果我只是尝试LISTAGG在NVARCHAR2列上使用,则在转换过程中数据将丢失:
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)
| 归档时间: |
|
| 查看次数: |
2498 次 |
| 最近记录: |