如何在 Oracle 中將 xml 實體轉換為 unicode 字元(具有隻讀訪問權限)?
我已連接到具有隻讀訪問權限的 Oracle 數據庫(11g 第 2 版 - 11.2.0.4)。
到這個數據庫中,一些數據是通過 XML 上傳的,或者更確切地說是 XML - 並且相當多的條目包含多次出現的 XML(特殊)字元實體,格式為
&#nnnn;
.到目前為止,我已經
&#nnnn;
在 Excel VBA 腳本中處理了這些問題,以將它們轉換為 Unicode 字元,但我寧願在我正在執行的 SQL 腳本中執行此操作以導出數據(到 Excel)。此問答涵蓋了幾乎相同的問題,但我還無法成功複製或實施我的案例中的答案,因此需要幫助。
該問答中接受的答案包含我假設(錯誤地?)我不能使用(具有隻讀訪問權限)的 SQL 命令,例如
create table
、和.insert into``declare``loop
另一個答案對我有用,因為我可以重現它(不是線上小提琴(如何?),而是在 Oracle SQL Developer 中),儘管有兩個障礙:1)它不會循環,因此只有在欄位包含時才有效一個特殊
&#nnnn;
字元(一次或多次)但不是不同的字元,並且 2)由於迄今為止不明原因,&#nnnn;
它無法與(不間斷空格)一起使用。 
在上面引用的問答的基礎上,如何在 Oracle 11g 中將這些 XML(特殊)字元轉換為具有隻讀訪問權限的 Unicode?
相關連結):
- https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions130.htm (REGEXP_REPLACE)
- https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions204.htm (UNISTR)
(失敗)迄今為止的嘗試:
SQL 1
select regexp_replace(s, '&#([0-9]+);', u) from (select s, unistr('\0' || REPLACE(TO_CHAR(TO_NUMBER(c), 'xxxx'), ' ', '')) u from (select s, regexp_replace(s, '.*&#([0-9]+);.*', '\1') c from (select 'Hallöle slovenĈina Hallöle slovenđina' s from dual)))
輸出 1
Hall 油 slovenđina Hall 油 slovenđina
評論 1
Ĉ
( = Ĉ ) 被đ
( = đ ) 有效地“覆蓋”。也就是說,此腳本僅適用於僅包含一個且相同的特殊字元的欄位;它會用一個字元覆蓋所有其他特殊字元(這很明顯是不可取的)。SQL 2
select regexp_replace(s, '&#([0-9]+);', u) from (select s, unistr('\0' || REPLACE(TO_CHAR(TO_NUMBER(c), 'xxxx'), ' ', '')) u from (select s, regexp_replace(s, '.*&#([0-9]+);.*', '\1') c from (select 'Hallöle sloven ina' s from dual)))
輸出 2(錯誤消息)
ORA-30186: ‘' 後面必須跟四個十六進製字元或另一個 ‘' 30186. 00000 - “’' 後面必須跟四個十六進製字元或另一個 ‘'” *原因:在 SQL 函式 UNISTR 的參數中, ‘' 必須後跟四個十六進製字元或另一個’' *操作:修復字元串格式
評論 2
出於某種原因,不間斷空格 (
 
) 在這裡的行為似乎與其他特殊字元不同;也許這是一個Oracle例外?SQL 3
select REGEXP_REPLACE(specialCharData,'&#([0-9]+);',unistr('\' || replace(to_char(to_number(regexp_replace(specialCharData, '.*?&#([0-9]+);.*$', '\1')), 'xxx'), ' ', '0')),1,1) as "bla", ................
輸出 3(錯誤消息)
ORA-01722: invalid number 01722. 00000 - "invalid number" *Cause: The specified number was invalid. *Action: Specify a valid number.
評論 3
specialCharData
將是我的數據庫中的欄位/列的名稱。SQL 4
select REGEXP_REPLACE(specialCharData,'&#([0-9]+);',unistr('\' || replace(regexp_replace(specialCharData, '.*?&#([0-9]+);.*$', '\1'), ' ', '0')),1,1) as "specialChar", ................
輸出 4(錯誤消息)
ORA-30186: ‘' 後面必須跟四個十六進製字元或另一個 ‘' 30186. 00000 - “’' 後面必須跟四個十六進製字元或另一個 ‘'” *原因:在 SQL 函式 UNISTR 的參數中, ‘' 必須後跟四個十六進製字元或另一個’' *操作:修復字元串格式
評論 4
specialCharData
將是我的數據庫中的欄位/列的名稱。to_char(to_number(
在這裡,我嘗試通過刪除該部分來修剪 SQL 3 。沒那麼有用,可能……隨機測試的想法……
數據看起來像是沒有 XML 標籤的原始 XML 數據,而不是翻譯後的文本。您可能應該先解決這個問題。
同時,您可以執行數據
XMLTable()
為您進行翻譯。with data as ( select 'Hallöle slovenĈina Hallöle slovenđina' str from dual ) select a.str, b.str2 from data a, xmltable( '/' passing xmltype( '<dat>' || a.str || '</dat>' ) columns str2 varchar2(4000) path '/dat' ) b
一種“步行”方式,通過嵌套的replace():
SELECT replace(replace(replace(col,'Ĉ';'Ĉ'),'đ','đ'),' ',' ')
如果循環正則表達式在給定的限制下不起作用,這可能是我最好的選擇……不是嗎?
(顯然以上內容仍然需要擴展更多字元……)