3
我正在使用Oracle數據庫並且想要使用多字節字符集(UTF-8)確定NCLOB的字節長度。使用多字節字符集確定CLOB/NCLOB的字節長度
LENGTHB()
不支持具有多字節字符集的NCLOBS或CLOB。我可能將NCLOB轉換爲BLOB並獲得它的長度。但是,沒有更好的方法來做到這一點嗎?
我正在使用Oracle數據庫並且想要使用多字節字符集(UTF-8)確定NCLOB的字節長度。使用多字節字符集確定CLOB/NCLOB的字節長度
LENGTHB()
不支持具有多字節字符集的NCLOBS或CLOB。我可能將NCLOB轉換爲BLOB並獲得它的長度。但是,沒有更好的方法來做到這一點嗎?
Oracle以UTF-16存儲CLOB
(或可能是您的NCHARACTER_SET
?)。每個字符存儲爲兩個字節。
這裏是你如何能看到原始數據:
SQL> CREATE TABLE test_clob (c CLOB, v VARCHAR2(10 CHAR), nv NVARCHAR2(10));
Table created
SQL> INSERT INTO test_clob VALUES ('', '', '');
1 row inserted
SQL> SELECT dbms_rowid.rowid_relative_fno(ROWID),
2 dbms_rowid.rowid_block_number(ROWID)
3 FROM test_clob;
DBMS_ROWID.ROWID_RELATIVE_FNO(DBMS_ROWID.ROWID_BLOCK_NUMBER(
------------------------------ ------------------------------
13 94314
SQL> alter system dump datafile 13 block 94314;
System altered
瀏覽到您的USER_DUMP_DEST
目錄並打開跟蹤文件,你會看到這樣的事情:
col 0: [56]
00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 03 64 c6 a5 00 24 09 00 00
00 00 00 00 14 00 00 00 00 00 01 00 30 00 31 00 32 00 33 00 34 00 35 00 36
00 37 00 38 00 39
LOB
Locator:
Length: 84(56)
Version: 1
Byte Length: 2
LobID: 00.00.00.01.00.00.03.64.c6.a5
Flags[ 0x02 0x0c 0x80 0x00 ]:
Type: CLOB
[...]
Inline data[20]
[...]
col 1: [10] 30 31 32 33 34 35 36 37 38 39
col 2: [20] 00 30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39
正如你所看到的CLOB
(第0列)由一些標題字節和與UTF-16 NVARCHAR2
列相同的字節原始數據組成。
因此,我認爲您必須將您的CLOB
轉換爲UTF-8才能確定其在此字符集中的長度。
下面是我用DBMS_LOB.converttoblob
使用的例子:
SQL> DECLARE
2 l_clob CLOB := 'abcdéfghij'; -- the é will take two bytes!
3 l_blob BLOB;
4 l_dest_offset NUMBER := 1;
5 l_src_offset NUMBER := 1;
6 l_lang_context NUMBER := 0;
7 l_warning NUMBER;
8 BEGIN
9 dbms_lob.createtemporary(l_blob, FALSE, dbms_lob.call);
10 dbms_lob.converttoblob(dest_lob => l_blob,
11 src_clob => l_clob,
12 amount => dbms_lob.lobmaxsize,
13 dest_offset => l_dest_offset,
14 src_offset => l_src_offset,
15 blob_csid => nls_charset_id('AL32UTF8'),
16 lang_context => l_lang_context,
17 warning => l_warning);
18 dbms_output.put_line('byte length:'||dbms_lob.getlength(l_blob));
19 dbms_lob.freetemporary(l_blob);
20 END;
21/
byte length:11
PL/SQL procedure successfully completed
您可以轉換到使用功能nls_charset_id
任何字符集。
這就是我實際上在做我的UTF-8 NCLOB的長度之前所做的。我在Windows-1252字符集中有一個CLOB,我試着調用'CONVERT(my_clob,'UTF8','WE8MSWIN1252')'將它轉換爲UTF-8的NCLOB。但事實證明'CONVERT(CLOB,VARCHAR2,VARCHAR2)'返回一些僞UTF-8 CLOB(而不是NCLOB)和一些奇數的填充,可能是UTF-16 ... – Dave
@dave我不認爲' convert'會做你認爲它做的事。 ['CONVERT'](http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions034.htm#i77037)將返回一個與第一個字符集具有相同原始字符的CLOB,儘管數據會有所不同。我已經用'dbms_lob.converttoblob'添加了一個應該與所有clobs一起工作的例子。 –
文森特,不知道爲什麼,但我得到字節長度:15對於這個例子,如果我轉儲這個字符串,我得到預期的長度爲11.不知道爲什麼差異,雖然。 – tbone