# 【教學筆記 01】基礎知識介紹 內容:編碼、檔案、斷行字元、Excel、其他基礎知識介紹 --- [目錄](https://hackmd.io/Y7i9O4hCQu6xOJ94__PhNg) 教學筆記 01:編碼、檔案、斷行字元、Excel、其他基礎知識介紹 [教學筆記 02:Linux 指令介紹 ](https://hackmd.io/9D_WXaT3TsCaBrsOQKYdTw) [教學筆記 03:awk 指令介紹](https://hackmd.io/PHZRjtQMRi2v9Z-u6bD6Tg) [教學筆記 04:文件圖表表達方式的經驗分享](https://hackmd.io/xVM9lnFBSneA6uhIzdkYyA) [教學筆記 05:以 C 語言開發資料庫存取程式 (ECPG)](https://hackmd.io/4jh_5A51TfieovVipQqoXA) [推薦書籍](https://hackmd.io/t7T5FxfmT3Kih-b7PRUZrA) [補充教材](https://hackmd.io/w-BNpl_TSuysG4_qaGtmFg) --- ## 一、檔案字元集 (Character Set) 編碼的判斷、轉換 * ### 在台灣常見的編碼,有 ANSI 與 Unicode 兩大體系: * ANSI: - [x] ASCII (1 byte) [^ref01] [^ref02] - [x] BIG5 → MS950 (2 bytes) [^ref03] - [ ] GB * Unicode: - [x] UTF8 (2~3 bytes) - [x] UTF8 (BOM) (2~3 bytes) [^ref04] - [ ] UTF16 (LE) (2 bytes) - [ ] UTF16 (BE) (2 bytes) - [ ] UTF32 (LE) (2 bytes) - [ ] UTF32 (BE) (2 bytes) * ### 判斷編碼的方式: * 下載範例:[char_set.zip](https://drive.google.com/file/d/1MHGp5G1uVeC55tAkOlBxSwABwN0SvrDN/view?usp=sharing) * 文字編輯器(Windows記事本、Notepad++...等工具) * 判斷字元的位元範圍:(利用程式語言、command line) * There is no 100% reliable way to detemine if a byte stream in ANSI or UTF-8 (without BOM). [^ref05] * 可利用 Notepad++ 的 HEX-Editor 外掛程式來判斷 * 可利用 Linux 指令來判斷 (於教學筆記 02 再教) * 中文碼查詢:https://www.cns11643.gov.tw/searchQ.jsp?ID=0 * ### 轉換編碼的方式: - [x] 記事本另存新檔 - [x] 文字編輯器(notepad++) - [ ] Linux指令:iconv (於教學筆記 02 再教) --- ## 二、存放資料的檔案 (結構化的文字檔) * ### 檔案種類: * 一、以「分隔符號」 (delimiter) 區分欄位: * 適用於任何字元集編碼 * 較常見 * 常用的分隔符號:逗號(,)、空白、Tab、pipe(|)、ACSII碼(002) * 亦可同時使用多種字元、字串作為分隔符號 ``` 1,John,0911-222-333,Taipei City,中華電信總公司 2,May,0922-333-444,New Taipei City,中華電信企業客戶分公司 ... ``` * 範例:https://data.gov.tw/dataset/8355 下載 csv 檔,並觀察內容。 * 二、以「固定長度」區分欄位: * 僅適用於ASCII、BIG5等固定寬度之編碼 * 衍生議題: * 文字:左靠/右靠 * 數字:左靠/右靠/整數or小數位補幾個0 ``` 1John0911-222-333 Taipei City中華電信總公司 2 May0922-333-444New Taipei City中華電信企業客戶分公司 ... ``` * 範例:[北帳刪帳檔(10107CF.BAD.txt)](https://drive.google.com/file/d/1wcQM10vX2OtqqN3Q0wyTVW8lNaBOmgMF/view?usp=sharing) * 格式:![](https://i.imgur.com/gUuQFN8.jpg)https://i.imgur.com/gUuQFN8.jpg * 【練習】各位學員可以嘗試使用 Excel 工具開啟上述兩種檔案,看看會發生什麼問題。 * ### 檔案檢查機制: 檔案有時可能會在傳輸的過程中間遺失資料,因此接收檔案時必須有一些檢查機制。 * 方式一:檔名中包含資料筆數。(例如:FILENAME_YYYYMMDD_筆數.csv) * 衍生議題:檢查資料筆數與檔名是否相符。 * 方式二:檔案附加尾筆,確認傳輸完畢。(也可以尾筆包含筆數以提供檢查) * 衍生議題:檢查資料筆數與最後一筆是否相符、去除掉最後一列之後再處理。 ``` 第 1 筆 第 2 筆 ... 第 N 筆 *** N *** ``` * 方式三:利用控制檔,檢查整批檔案的數量、筆數、格式等屬性。 * 財稅案的資料交換規格範例: * 分為 .H 檔 (資料規格) 與 .D 檔 (資料內容) 兩類檔案 * 未來會用在 oltp -> prestage 之階段 * 範例:VLTT125.20220105.H、VLTT125.20220105.D *<連結已移除>* * .H檔格式:(佳琪提供)![](https://i.imgur.com/ny1Yl9w.jpg)https://i.imgur.com/ny1Yl9w.jpg --- ## 三、斷行字元 * 斷行字元的種類: | 作業系統種類 | 斷行字元 (※) | 以跳脫序列(escape sequence)方式表示 | | ------------ | ----------- | -------- | | WINDOWS | CRLF | \r\n | | UNIX / Linux | LF | \n | | MAC | CR | \r | ※ 補充: | 字元 | 念法 | 跳脫序列 | ASCII碼 (10進位) | ASCII碼 (16進位) | | ----| --------------- | -------- | --------------- | --------------- | | CR | Carriage Return | \r | 13 | 0D | | LF | Line Feed | \n | 10 | 0A | * 斷行字元的判斷: * 可利用 Notepad++ 的 HEX-Editor 外掛程式來判斷 * 可利用 PsPad HEX 工具來判斷 * 可利用 Linux 指令 (od) 來判斷 * 【練習】使用一些編輯器,分別在 WINDOWS 或 UNIX 模式下任意編輯,再觀察斷行字元的型態。 * 斷行字元的轉換: * Notepad++: * 視窗右下角選擇斷行字元種類。 * 設定 > 偏好設定 > 新文件預設設定 > 切換:Windows/Unix/Mac。 * PsPad:按視窗下方狀態列即可切換。 * 【補充】Linux 指令: * Windows 轉 Unix (利用 tr、sed、dos2unix 指令) * Unix 轉 Windows (利用 sed、unix2dos 指令) * 參考網址:https://www.commandlinewizardry.com/post/removing-windows-line-breaks --- ## 四、Excel 工具 * 工作中時常用來: * 撰寫文件、圖表 * 比對資料 * 產製具有固定規則的資料 * 常用功能/函式: * 開啟檔案 (以分隔符號切、以固定長度切) * 產生數列 (拉控制點 or 公式) * 判斷資料 * 設定格式化條件 * 樞紐分析表 * 統計圖 * Excel函數線上說明:https://support.microsoft.com/zh-tw/office/excel-%E5%87%BD%E6%95%B8-%E4%BE%9D%E9%A1%9E%E5%88%A5-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb * IF * COUNTIF * TRIM:移除文字中的 7 位元 ASCII 空格字元 (值 32)。在 Unicode 字元集中,有一個額外的空格字元稱為不分行空格字元,其十進位值為 160。此字元一般用於網頁中,做為 HTML 實體 &nbsp;。單獨使用 TRIM 函數,不會移除此不分行空格字元。 * CLEAN:移除文字中 7 位元 ASCII 碼的前 32 個非列印位元 (值 0 至 31)。在 Unicode 字元集中,還有額外的非列印字元 (值 127、129、141、143、144 及 157)。單獨使用 CLEAN 函數,不會移除這些額外的非列印位元。 * CONCATENATE (功能與 & 相同) * SUBSTITUTE * VLOOKUP * FIND:搜尋文字在另一字串中的起始位置。 * LEFT * RIGHT * MID * AND * OR * LEN(X):字串X的長度 * REPT(A,B):字串A重複B次 * CHAR(X):回傳十進位值為X的ASCII code。例如CHAR(65)為"A"。 * CODE(X):回傳ASCII code為X的十進位值。例如CODE("A")為65。 * DEC2HEX(X):將10進位的數字X轉為16進位。 * HEX2DEC(X):將16進位的數字X轉為10進位。 * VBA --- ## 五、de morgan 定理 ``` 非(P or Q) ≡ (非P) and (非Q) 非(P and Q) ≡ (非P) or (非Q) ``` ``` 非(P or Q or R) ≡ (非P) and (非Q) and (非R) 非(P and Q and R) ≡ (非P) or (非Q) or (非R) ``` ![](https://i.imgur.com/A5pp5A7.jpg) * 舉例:正常人的捐血資格: 1. 17歲以上,65歲以下。 2. 女性應45公斤以上,男性應50公斤以上。 3. 體溫不超過攝氏37.5度。 * 如果一個人可以捐血,就表示: ``` 「AGE >= 17歲」 and 「AGE <= 65歲」 and (「SEX = 女 and WEIGHT >= 45公斤」 or 「SEX = 男 and WEIGHT >= 50公斤」) and 「TEMPERATURE <= 37.5度」 ``` * 如果一個人無法捐血,就表示: ``` 「AGE < 17歲」 or 「AGE > 65歲」 or (「SEX = 女 and WEIGHT < 45公斤」 or 「SEX = 男 and WEIGHT < 50公斤」) or 「TEMPERATURE > 37.5度」 ``` --- ## 作業三:(EXCEL練習) * SDM下載 (V0.01):FIA_DW_SDM_Base_V0.01_20210128.ods *<連結已移除>* * SDM下載 (V0.04):FIA_DW_SDM_Base_V0.04_20210222.ods *<連結已移除>* 1. 先將 FIA_DW_SDM_Base_V0.01_20210128.ods 另存為 xlsx 檔,並找出 SDM V0.01 中的「Base基礎資料欄位對應V0_01」頁籤: (1). 檢查序號是否正確。(不要每一張表都各自拉正確的序號) ※ Hint:正確的序號計算方法:若該列的資料表名稱與上一列相同,則遞增;若不同,則由1起算。 (2). 資料欄位名稱兩側有空白的的欄位有哪些? 2. 先將 FIA_DW_SDM_Base_V0.04_20210222.ods 另存為 xlsx 檔,並利用 SDM V0.04 進行下列工作: 利用資料表名稱、資料欄位名稱、資料型態、不為空值、序號這些資料,製作出下列 CREATE、DROP、INSERT 的 SQL。 (1). 檢查 BASE 表中的序號是否正確。(不要每一張表都各自拉正確的序號) (2). 對於 STAGE 表進行資料型態的拆解,例如:VARCHAR(X)、DECIMAL(X,Y) ==> 拆出:資料型態(VARCHAR/DECIMAL)、X、Y 產生SQL: (3). 請利用 BASE 表製作 CREATE TABLE DDL: | 資料表名稱 | 資料欄位名稱 | 資料型態 | 不為空值 | 序號 | SQL(自建) | | -------- | ---------- | ------ | ------- | --- | --- | | table1 | column1 | int | Y |1 |create table base.table1 (column1 int not null, | | table1 | column2 | varchar(10) | |2 |column2 varchar(10), | | table1 | column3 | decimal(10,2)| |3 |column3 decimal(10,2)); | | table2 | column1 | varchar(5) | Y |1 |create table base.table2 (column1 varchar(5) not null, | | table2 | column2 | text | |2 |column2 text); | (4). 請利用 BASE 表製作 DROP TABLE DDL: | 資料表名稱 | 資料欄位名稱 | 資料型態 | 不為空值 | 序號 | SQL(自建) | | -------- | ---------- | ------ | ------- | --- | --- | | table1 | column1 | int | Y |1 |drop table base.table1;| | table1 | column2 | varchar(10) | |2 | | | table1 | column3 | decimal(10,2)| |3 | | | table2 | column1 | varchar(5) | Y |1 |drop table base.table2;| | table2 | column2 | text | |2 | | (5). 請利用 STAGE 表製作 INSERT SQL:(每張表填一筆資料就好) 規則:依據欄位的資料型態決定欄位的值。 * int:填 1。 * varchar(X)、char(X):填 X 個 'A' (例如:varchar(3) 填 'AAA')。 * text:固定填 'ZZZZZZZZZZ'。 * decimal(X,Y):整數填 X-Y 個 1,小數填 Y 個 1 (例如:decimal(5,2) 填 111.11)。 * decimal(X):整數填 X 個 (例如:decimal(5) 填 11111)。 * date:填 2021-01-01。 * timestamp:填 2021-01-01 00:00:00。 | 資料表名稱 | 資料欄位名稱 | 資料型態 | 不為空值 | 序號 | TYPE(自建) | X(自建) | Y(自建) | SQL(自建) | | -------- | ---------- | ------ | ------- | --- | ---- | - | - | --- | | table1 | column1 | int | Y |1 |int | | |insert into base.table1 values (1, | | table1 | column2 | varchar(10) | |2 |varchar|10| |'AAAAAAAAAA', | | table1 | column3 | decimal(10,2)| |3 |decimal|10|2|11111111.11); | | table2 | column1 | varchar(5) | Y |1 |varchar|5 | |insert into base.table2 values ('AAAAA', | | table2 | column2 | text | |2 |text | | |'ZZZZZZZZZZ'); | ※ 提示: 使用 IF、TRIM、ISERR、FIND、MID、LEN、REPT、OR、&(或CONCATENATE)。 --- ## Reference: [^ref01]: [ASCII](https://zh.wikipedia.org/wiki/ASCII) [^ref02]: [ASCII Table and Description](http://www.asciitable.com/) [^ref03]: [代碼頁950](https://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A2%BC%E9%A0%81950) [^ref04]: [位元組順序記號](https://zh.wikipedia.org/wiki/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F) [^ref05]: [How to detect encoding file in ANSI, UTF8 and UTF8 without BOM](https://social.msdn.microsoft.com/Forums/vstudio/de-DE/b172cd4d-25fe-4696-8c0f-37226c053d71/how-to-detect-encoding-file-in-ansi-utf8-and-utf8-without-bom?forum=csharpgeneral)