1. 程式人生 > 資料庫 >PostgreSQL去掉表中所有不可見字元的操作

PostgreSQL去掉表中所有不可見字元的操作

問題描述

資料庫中的某些資料中包含了某些不可見字元。ASCII碼中的0-31,127屬於控制字元,不可見。

這些不可見字元往往是不需要的,我們要想辦法刪除它。

解決辦法

寫一函式,將所有欄位中的不可見字元替換為空格。

測試流程

環境準備

建表,並插入帶不可見字元的記錄。注:下列資料中的不可見字元在貼上過來的時候自動去掉了,請按ALT+數字鍵加入。

CREATE TABLE public.test_table
(

 xm character varying(50),pinyin character varying(200),sm character(15)
)
WITH (
 OIDS=FALSE
);
ALTER TABLE public.test_table
 OWNER TO postgres;


-- ----------------------------
-- Records of test_table
-- ----------------------------
INSERT INTO ry_syrk_copy VALUES ('周小星xx','xx測試','測試' );
INSERT INTO ry_syrk_copy VALUES ('李華','測試xx','世xx界' );

注:因不可見字元無法在CSDN中無法打出,故用xx代替。實際上在其它地方可以用ALT+數字鍵打印出來。

去掉表中所有的不可見字元

-- 函式說明:將表test_table中所有的不可見字元替換掉
CREATE OR REPLACE FUNCTION delete_special_char() RETURNS int8 AS $$
DECLARE
 row RECORD;  
BEGIN

-- 查詢表中所有型別為字串的列
FOR row in select column_name from information_schema.columns where table_name = 'test_table' and data_type like 'character%' LOOP 
 FOR i IN 1..31 LOOP --替換所有的不可見字元為空格(除了chr(0)之外)
  EXECUTE 'update test_table set ' || row.column_name || ' = replace(' || row.column_name || ',chr(' || i || '),'' '' )';
 END LOOP;   
END LOOP;

RETURN 1;

END;

$$ LANGUAGE plpgsql;

執行函式

執行函式–select * from delete_special_char(),之後查看錶資料,所有的不可見字元都被替換為空格。

補充–如何刪除chr(0)

值得注意的是上述函式並不能刪除chr(0)的不可見字元,見如下測試。

PostgreSQL去掉表中所有不可見字元的操作

但oracle中上述語句卻可以成功執行,下面我就來講一講吧~

Oracle中varchar2欄位的不可見字元處理

在以前的專案中,曾經出現加密後的字串資料丟失,加密內容無法正常解密的情況,經查詢原因,發現是資料庫表的varchar2欄位中有chr(0)的不可見字元(即我們通常所說的\0),當出現這種情況時,由於java和c++中對字串處理的不同,將會導致所取得的字串長度不同。

在java中,字串的長度可以通過取字串的位元組陣列來獲得,這樣得到的字串長度為字串實際的大小(漢字2個位元組,其他1個位元組);在c++中通過strlen函式獲得的字串長度為第一個位元組\0之前的字元長度。

當我們在編寫jni的時候,經常會遇到將java的字串轉換為c++中的字串的情況,這樣,當java中的字串包含\0的空位元組時,在對c++轉換後的字串求取長度時,不要使用strlen函式,否則,其僅僅對\0位元組之前的內容求取長度,與實際大小不同。

解決該類問題,根據所屬應用的不同,可通過三種手段解決:

在資料庫層解決:

Oracle資料庫中,可在查詢語句中使用函式replace來去除字串中的非可見字元,例如:

select replace(content,chr(0),null) from bossquery_request where sky_command = '02';

以後大家如果遇到類似情況,可通過replace(欄位名,chr(ASCII碼值),null)來去掉其中對應的ASCII碼值的字元。

在java程式中解決:

在java程式中,大家可通過獲取String物件的所有位元組內容,對位元組內容進行掃描,來去掉其中不需要的位元組。

在JNI層解決:

在JNI層解決該問題的方式是,不要使用strlen函式來獲取字串長度,可通過GetArrayLength取位元組陣列長度函式或者其他類似函式來獲取字串長度,則可避免該情況發生。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。