Db2
clp 將字節追加到輸出
我正在將一些數據庫遷移到 UTF-8,並且剛剛發現了我不知道的現象。當選擇數據輸出到終端時,額外的字節被添加到輸出中。例子:
~]$ x=$(db2 -x "values 'a'") ~]$ echo "${x}b" a b
後一個額外的空格
~]$ x=$(db2 -x "values 'aa'") echo "${x}b" aa b
aa 後面的兩個額外空格
一個字元在 utf8 中佔用多少字節似乎並不重要:
~]$ x=$(db2 -x "values '𝄞'") ~]$ echo "${x}b" 𝄞 b
g-譜號後加一個空格
~]$ x=$(db2 -x "values '𝄞𝄞'") ~]$ echo "${x}b" 𝄞𝄞 b
g-clef 後的兩個額外空格 g-clef
數據庫配置文件:
Database territory = SE Database code page = 1208 Database code set = UTF8 Database country/region code = 46 Database collating sequence = SYSTEM_819_SE
終端具有編碼 UTF8(嘗試過終止符和 gnome-terminal),並且在連接到數據庫之前我做了:
export LC_CTYPE=sv_SE.utf8
上面當然只是愚蠢的例子,但我在類似的腳本中有相當多的測試:
dbtype=`db2 -x "values nya.get_db_type()"` if [ "${dbtype}" = "N" ]; then ...
我需要以一種或另一種方式更改測試的地方。
關於配置的任何想法,可以擺脫額外的字節?
~]$ uname -a Linux nya-ladok3-release 3.10.0-1062.9.1.el7.x86_64 #1 SMP Mon Dec 2 08:31:54 EST 2019 x86_64 x86_64 x86_64 GNU/Linux ~]$ db2level DB21085I This instance or install (instance name, where applicable: "db2inst1") uses "64" bits and DB2 code release "SQL11050" with level identifier "0601010F". Informational tokens are "DB2 v11.5.0.0", "s1906101300", "DYN1906101300AMD64", and Fix Pack "0". Product is installed at "/opt/ibm/db2/V11.5".
這是我從IBM支持那裡得到的解釋,我自己沒有測試過,但看起來很合理。建議的解決方法適用於我現在能想到的所有情況:
CLP 中填充的額外空格是預期的行為。這是因為有一些多字節字元佔用超過 1 個物理空間。請參見下面的範例,該範例展示了相同的內容:
比如說,U+FF2D 全寬拉丁文大寫字母 M
$ db2 "select a, hex(a) from table(values('A' || u&'\FF2D' || 'B'),('A B')) t(a)" A 2 ----- ---------- AMB 41EFBCAD42 —> Here wide-M is taking more space than a normal multi/single byte character. A B 41204220202 record(s) selected.
如果您在腳本中使用了很多函式,例如 get_db_type(),您可以更改這些函式中的返回值以將其修改為 OCTETS:
類似於以下內容:
CREATE OR REPLACE FUNCTION get_db_type() RETURNS VARCHAR(1 OCTETS) DETERMINISTIC NO EXTERNAL ACTION CONTAINS SQL BEGIN ATOMIC RETURN 'N'; END @
我將保留目前的解決方法,如下所示:
如果沒有其他任何東西出現,我可能會按照以下方式做一些事情:
x=$(db2 -x "values ('𝄞𝄞')") x="${x%"${x##*[![:space:]]}"}" echo ${x}b 𝄞𝄞b
一開始,我想:
x=$(db2 -x "values ('𝄞𝄞')" | xargs echo)
可以,但是管道引入了一個子shell,所以:
echo ${x}b SQL1024N A database connection does not exist. SQLSTATE=08003b
這沒用。