議決運用順序存儲和檢索 XML
XML 編碼
字符編碼
在汗青上,術語 字符集、字符編碼 和 碼頁 都有雷同的意義:一個字符集和一個二進制碼集,其中每個碼示意一個字符。(碼頁是來自 IBM 的一個術語,示意一個大型主機或 IBM PC 上的一個字符集。) 官方字符集稱號由 Internet Assigned Numbers Authority (IANA) 維護。欲觀念更多信息,請參閱 參考質料 小節。
遺留字符編碼
東方一些罕有的遺留字符集有 US-ASCII、EBCDIC、碼頁 437、碼頁 1252、8859-1、1208 和 Latin-1。這些都是將一個字符編碼為一個字節。
-
碼頁 437: 在美國的 Microsoft Windows 上,默許碼頁是 437;IANA 官方編碼稱號為 ibm-437。 它有一些非英語字符(例如 "ae" 連字、帶重音的小寫元音、一些希臘字母、法語引號 "<<" 和 ">>" 以及 48 個圖形字符(DOS 和基于字符的順序的遺產)。
-
碼頁 1252: 在 DB2 的起頭菜單組中,在 Command Line Tools 下有兩個菜單項: Command Line Processor 和 Command Window。它們都是首先運轉一個順序 db2clpcp.exe,該順序將碼頁從默許的 437 改為(美國的)1252。 碼頁 1252(Microsoft 也稱 "Latin-I")中有 "ae" 連字,大寫和小寫的重音字符以及歐元標記(十六進制碼為 0x80),然則沒有希臘字母。
-
碼頁 1208: 當執行
CREATE DATABASE USING CODESET UTF-8
時,呼應的數據庫碼頁為 1208:db2 get db cfg for sample | grep "code"Database code page = 1208Database code set = UTF-8Database country/region code = 1
-
字符集 iso-8859-1: 該字符集也稱 Latin-1,在英國或西歐的 Web 頁面上比擬罕有。它有 "ae" 連字、大寫和小寫的重音拉丁字母,然則沒有希臘字母,也沒有歐元標記。
參考質料中可以找到這些字符集和另外字符集的定義的鏈接。
回頁首
Unicode
任何遺留編碼都是有限定的,因為它只能示意多數言語中的文本。經管多種編碼是件頭痛的事情,這不僅僅是因為大大都運用順序和數據庫只能處理一種編碼,另有許多另外緣由。Unicode 便是為了處理這個成果而締造的。它是用于默匡正在運用的齊備言語中的齊備字符的字符集,而且留有增進空間。
在 Unicode 中,一個字符集的龐大思想被英華為 4 個觀念:
- 字符集 便是可以被編碼的齊備字符的集合。它沒有指定編碼。
- 編碼字符集是專一整數的集合,用于示意字符匯集的一些或全數字符,一個數字(或 碼點)對應一個字符。也稱 character set、charset 或 code set。它與碼頁是同義詞。Unicode 碼點局限為 0 到 0x10FFFF(大約 110 萬)。
-
新近,Unicode 定義了不到 64,000 字符的字符集,所以可以用 16 位(2 字節)碼點指定一個編碼字符集。跟著更多字母表的參與,字符集超越了 64,000 個字符。 另一個成果是,許多處理 US-ASCII 的計較機系統(尤其是用 C 編寫的順序)或另外計較機系統運用一個 null 或零字節(在 C 中為
\0
)標記一個字符串的掃尾。然則將 Unicode 碼點間接編碼為 16-位或更大的數字時,會包括一些 null 字節,它們會分袂這些順序。所以 Unicode 引入了一個新的觀念,即字符編碼表(CEF), ,它每每被簡稱為字符編碼(character encoding)或編碼(encoding)。CEF 是從編碼字符匯集的碼點到一組分歧的整數(或 code unit)之間的映射,這些字符理論上被編碼為其中的整數。編碼單元是用于編碼字符的最小單元。一個字符可以用一個或多個編碼單元示意,從而容許編碼更多的字符。
所以碼點 只是用于引用的,因此可以說 “那個 字符”。Java
String
、Cchar[]
或文件中的理論字節大體分歧,這取決于字符編碼表。有些 Unicode 字符編碼表是 UTF-8、UTF-16 和 UTF-32。數字 8、16 和 32 示意編碼單元中的位數。- DB2 運用 UTF-8 為每個字符運用 1 到 4 個編碼單元(即字節)。在規定 UTF-8 數據庫中的 [VAR]CHAR 列的長度時,這一點很次要:一個字符大體占 1 到 4 個字節。UTF-8 字符編碼表不包括任何 null 字節,這種字節對于 C 比擬等閑。
- 在 Java 言語運用的 UTF-16 字符編碼表中,最常用的碼點低于 64K,UTF-16 字符碼等于碼點。更高的碼點需求兩個編碼單元。
- UTF-32 是專一定長的 UTF,它議決添加空間成本簡化一些處理。編碼單元老是等于碼點。
因為 Unicode 尺度限定遺留碼點,使齊備 UTF 編碼都能示意任何碼點,因此 UTF 之間的譯碼不會組成字符損掉。
Unicode 碼點在文檔中平日被寫為
U hhhh
,其中hhhh
示意 4 個十六進制數字,用于 2 字節的碼點;對于 64K 以上的碼點,因為需求 4 個字節,因此兩次運用該語法。 詳盡,該語法是在文檔中運用的,XML 和編程言語中專門有效于指定 Unicode 筆墨的語法;欲觀念更多信息,請參閱上面的 "編碼中的字符" 小節。 -
字符編碼體例(character encoding scheme)指定在示意字符的字節流中的一個編碼單元中如何臚列字節。UTF-16 和 UTF-32 供應了指定字節按次的體例,即 big-endian(默許)或 little-endian。對于 UTF-8,一個編碼單元便是 1 字節,所以不存在按次 -- 換句話說,無論計較機的 endian 按次是什么,編碼單元的按次老是一樣的。




回頁首
哪種編碼?
不管用什么來處理字符數據,都必需知道字符集、字符編碼表和數據的字符編碼體例。
外部編碼
在 XML 之外,文本只需外部編碼。外部編碼由碼頁定義,大概由情況中的職位地方、運用順序、變量范例、函數或體例(例如 Java 體例 String.getBytes(String encoding)
)中指定的編碼來定義。
為了確天命據庫創建時所基于的數據庫碼頁,可以運轉:
db2 get db cfg for database-name
,并查察 "Database code page" 參數的值。
在 Windows 上,編碼的有些方面取決于安頓的操縱系統的版本。議決 Control Panel applet "Regional and Language Options" 可以改動地區和鍵盤的某些方面。可以掀開一個下令窗口,輸入下令 CHCP
,來看看碼頁是什么。
在 Linux 和 UNIX 上,運動情況是議決地區設置來確定的,地區設置包括關于言語、地區和編碼集的信息。為了確定運動碼頁,運轉:
locale
外部編碼
XML 數據還可以有外部編碼。外部編碼位于 XML 文檔的外部。外部編碼有兩種:
- 編碼屬性
- Byte Order Mark (BOM)
編碼屬性 在文檔頂部的 XML 聲明部門,它指定一種官方 IANA 編碼稱號:
<?xml version="1.0" encoding="UTF-8"?>
BOM 是文件開頭部門的一系列新鮮的字節,它標明一種 Unicode 編碼。為了讀取 XML 聲明,XML 理會器需求知道或推想編碼。然則它可以正確無誤地讀取 BOM。
表 1. Unicode 編碼的 Byte Order Mark
UTF-8 X'EFBBBF' UTF-8
UTF-16 Big Endian X'FEFF' UTF-16
UTF-16 Little Endian X'FFFE' UTF-16
UTF-32 Big Endian X'0000FEFF' UTF-32
UTF-32 Little Endian X'FFFE0000' UTF-32
分歧等編碼
假定 XML 文檔的理論編碼、外部編碼和外部編碼(BOM 或 XML 聲明)分歧等,那么該文檔便是不成讀的。一個破例是外部編碼為 Unicode(例如運用 UTF-16 的一個 Java String
):任何外部編碼都被忽略。當一個不撐持 XML 的進程譯碼(也便是改動理論編碼)大概在不撐持外部編碼的情況下變更文檔時,就會產生一個罕有的成果。Java 言語、CLI 和嵌入式 SQL 運用順序中對字符串的某些處理可以在不改動外部編碼的情況下舉辦譯碼。欲觀念如何防范這個成果,請參閱上面的"創議"小節。
回頁首
編碼中的字符
在 Windows 中,為了在鍵盤上輸入分歧言語的文本,可以在 Windows Control Panel 中 "Regional and Language Options" 下單擊 Languages 標簽頁上的 Details 按鈕來改動輸入言語和鍵盤機關。可以添加多種言語和鍵盤,而且用一個熱鍵在它們之間舉辦切換。(對不起,這里沒有 Unicode "言語" 或鍵盤 -- 因為它必需異終大才行!)
Windows Notepad 合用順序可以用 "ANSI"(windows-1252 或雷同)、"Unicode" (UTF-16 little endian,Intel 和 AMD CPU 的 endian 按次)、"Unicode big endian"(默許 UTF-16)和 UTF-8 編碼生涯文件。對于 UTF,Notepad 用一個 BOM(沒有 XML 聲明)事后思索文件。
在 Java String
筆墨(授與 Unicode)中,運用一個本義序列:\udddd
,其中 dddd
示意用于 Unicode 碼點的 4 個十六進制數字。
在 XML 和 HTML 中,可覺得碼點運用一個 XML 數字引用(或 字符引用):&#n
,其中 n
是用于 Unicode 的一個十進制數字。例如,歐元標記的十進制引用是 €。議決在數字前面加上 x
,也可以將碼點指定為一個十六進制數字:&#xn
。例如,歐元標記的十六進制引用是 €。十六進制引用平日更等閑,因為碼點平日是用十六進制指定的。對于數字引用,前面的 0 被忽略。每個字符都必需零丁轉移或引用:例如,"!"" 是 "!"" (嘆息號,雙引號),而 "™" 是 "?"(商標)。
表 2 展現了一些示例字符和它們的 Unicode 碼點以及 UTF 和兩種遺留的東方碼頁中的字符編碼。
回頁首
Java 言語中的編碼
Java String
(和類和體例名等標識符)是用 UTF-16 編碼的;然則源文件是用今后碼頁而不是 UTF-16 編碼的。當用 javac
編譯一個 Java 順序時,編譯器將 String
筆墨從源文件的編碼轉換為 UTF-16。為了指定源文件運用另一種編碼,可以運用 javac
選項 -encoding code-set-name
。該選項容許在標識符和筆墨字符串中運用一種分歧的編碼。
DB2 9 供應了一個助手類 com.ibm.db2.jcc.DB2Xml
,這個類可以資助在數據庫與 Java 運用順序之間傳輸和轉換數據。它對 XML 知道得更多;例如,有些體例可以依據理論的編碼轉換串行化 XML 文檔的外部編碼,使它們貫穿連接一概。
表 3. JDBC getter 體例:前去范例、編碼和聲明
getDB2String()
String
UTF-16 否getDB2XmlString()
String
ISO-10646-UCS-2 是getDB2Bytes()
byte[ ]
UTF-8 否getDB2XmlBytes(String targetEncoding)
byte[ ]
As specified 是getDB2AsciiStream()
InputStream
ASCII 否getDB2XmlAsciiStream()
InputStream
ASCII 是getDB2CharacterStream()
java.io.Reader
UTF-16 否getDB2XmlCharacterStream()
java.io.Reader
ISO-10646-UCS-2 是getDB2BinaryStream()
InputStream
UTF-8 否getDB2XmlBinaryStream(String targetEncoding)
InputStream
As specified 否DB2 9 附帶了 2 種 JDBC 驅動順序,它們可以用三種分歧的體例銜接到 DB2(DB2 9 不撐持 JDBC Type 3 驅動順序):
- DB2 Driver for JDBC and SQLJ,一種通用的 JDBC 驅動順序,可以用以下體例銜接:
- JDBC Type 4 驅動順序
- JDBC Type 2 驅動順序
- DB2 JDBC Type 2 Driver(一種遺留驅動順序)
創議運用通用的 DB2 driver for JDBC and SQLJ。從 DB2, Version 8.2 起頭,就分歧意運用遺留 Type 2 驅動順序。遺留 Type 2 JDBC 驅動順序不克不及與 DB2 類 com.ibm.db2.jcc.DB2Xml
一路運用,而且在某些 JDBC 體例中以分歧的體例處理 XML。例如,一個 XML 列的 SELECT
(沒有顯式的 XMLSERIALIZE()
)上的 get
體例(例如 ResultSet.getBinaryStream(column)
、ResultSet.getCharacterStream(column)
、ResultSet.getString(column)
)會添加一個 BOM 和 XML 聲明到串行化 XML 中。要么外部編碼(UTF-16)與理論編碼不婚配,要么 BOM 被損壞,從而招致文檔不成用。
關于 JDBC 驅動順序版本的更多信息,請參閱 表 4。
對于任何范例的 JDBC 銜接,假定要以今后用戶之外的另外用戶舉辦銜接,則必需在銜接 URL 或 getConnection()
的 Properties
參數中指定所需的用戶名和密碼。
DB2 在 IBM\SQLLIB\samples\xml\java\jdbc 中供應了示例 JDBC 運用順序,例如 XmlInsert.java。假定運用它們舉辦實驗,那么要戒備,在默許情況下,這些運用順序用遺留的 Type 2 驅動順序銜接到 DB2。(請查察 Util.java
文件中的助手類 Db
。)為了用 Type 4 驅動順序舉辦銜接,必需指定處事器、端口、用戶和密碼的下令行參數。 假定要看語法舊事,可以用參數 -help
運轉這個類:
prog_name -u2 [dbAlias] [userId passwd] (use universal JDBC type 2 driver) prog_name [dbAlias] server portNum userId passwd (use universal JDBC type 4 driver)
例如:
java -cp ".;%>
下載 小節中有演示 DB2、JDBC 和 DB2Xml
類如那處置編碼的示例代碼。
回頁首
CLI 中的編碼
當將 XML 拔出 DB2,并運用 SQLBindParameter()
將一個變量綁定到一個 XML 列時,CLI 依據上面表 5 中的輸入規則確定 XML 的編碼。假定編碼由運用順序碼頁確定,然則文檔另有一個外部編碼(一個 BOM 或 XML 聲明),則外部編碼與外部編碼必需一概。當從 DB2 中將 XML 取出到一個主變量中時,數據將依據表 5 運用一種外部編碼(含編碼屬性的一個 XML 聲明)來編碼。
表 5. CLI 范例
SQL_C_CHAR
運用順序的碼頁 與輸入不異SQL_C_DBCHAR
運用順序的碼頁 與輸入不異SQL_C_WCHAR
UCS-2 與輸入不異SQL_C_BINARY
讀外部編碼 UTF-8



回頁首
嵌入式 SQL 中的編碼
當議決一個嵌入式 SQL(ESQL)主變量將 XML 拔出 DB2 中時,XML 的編碼依據表 6 中的輸入規則來確定。假定編碼由運用順序碼頁確定,然則文檔另有一個外部編碼(一個 BOM 或 XML 聲明),則外部編碼與外部編碼必需一概。當從 DB2 中將 XML 取出到一個 ESQL 主變量中時,數據將依據表 6 運用一種外部編碼(含編碼屬性的一個 XML 聲明)來編碼。
表 6. ESQL 范例
XML AS CLOB
、XML AS CLOB_FILE
運用順序的碼頁 與輸入不異XML AS DBCLOB
、XML AS DBCLOB_FILE
運用順序的碼頁 與輸入不異XML AS BLOB
、XML AS BLOB_FILE
讀外部編碼(注 1) UTF-8char[]
之類的一個龐大范例 運用順序的混淆碼頁(注 2) 與輸入不異注 1: 假定一個 BLOB 范例的變量沒有任何外部編碼,則 DB2 假定其編碼為 UTF-8。
注 2:為了議決一個龐大范例(例如 char
)變量拔出 XML,可以運用 SQL 函數 XMLCAST(? AS XML)
將其映射到 XML。
回頁首
創議
- 將字符串筆墨(例如提示和錯誤舊事)從源代碼直達移到某種屬性或初始化文件中,大概轉移到一個數據庫表中。這樣做便于將運用順序翻譯成另外言語。然則,需求在運用順序中硬編碼一兩條錯誤舊事,以防運用順序不克不及掀開那個舊事文件大概查詢舊事表。
- 防范非 Unicode 字符集之間的譯碼,以防損掉目的字符匯集沒有的字符。
- 對于不是用 Java 言語編寫的運用順序,在運用順序情況中用分歧的碼頁對它舉辦測試。您大概不克不及節制用戶的碼頁。(Java 運用順序碼頁老是 UTF-16。)
- 用一些非 ASCII 數據測試運用順序。碼頁 437、 1252、8859-1 和 1208(UTF-8 的編碼)在前 128 個字節中都與 US-ASCII 婚配,所以 US-ASCII 數據在編碼或譯碼方面出成果的幾率更小。搜檢在譯碼時損掉的字符,這平日不會孕育產生任何錯誤舊事。
- 運用通用 DB2 Driver for JDBC and SQLJ,而不是遺留的 Type 2 驅動順序。假定不克不及節制運用順序所運用的驅動順序,那么可以用出產中將運用的驅動順序范例對運用順序舉辦測試,防范那些不是在齊備驅動順序范例中都能事情大概在分歧驅動順序中有分歧舉動的體例。
- 對于 C 運用順序,為了處理
char[]
數據范例中的 XML,運用 UTF-8 編碼,因為它不包括 null(\0
)作為有效字節。 - 對于 CLI 和 ESQL 運用順序,要清晰 CLI 會前去運用外部編碼的 XML 數據。假定舉辦譯碼,大概改動理論編碼,則文檔變得不成用。為了防范這一點,將運用順序變量綁定到
SQL_C_BINARY
范例;這樣可以使數據貫穿連接運用 UTF 編碼,從而防范從今后編碼到外埠碼頁的有損掉的譯碼。 - 對于將寄存 UTF 字符的任何數據范例,要供應充沛的空間,因為一個字符大體占多個字節。
版權聲明: 原創作品,容許轉載,轉載時請務必以超鏈接體例標明文章 原始原因 、作者信息和本聲明。不然將究查司法責任。