เท่าที่ดูๆ DOS BATCH มันไม่ได้มี function อะไรสำหรับ support การใช้วันที่ตามปี “พุทธศักราช” Buddhist Era เลยต้องเอามาบวกลบ 543 เอาเอง
ทีนี้โจทย์วันนี้ คือ ต้องการให้มันเปรียบเทียบวันที่จากค่าตั้งต้น กับ วันที่ปัจจุบัน
* เดิมมีระบบการ verify ข้อมูลรายวัน ที่ดึง query จากฐานข้อมูลมาเพื่อเช็คความถูกต้องของ DATA ที่ถูก RESTORE เข้าไปมันตรงตามวันหรือไม่ หรือว่ามีปัญหาในขั้นตอนการถ่ายโอนไฟล์ .BAK
ซึ่งการส่ง verify ทุกๆ วัน ใน Line กลุ่ม มันจะสร้างความรำคาญ หากมันไม่มีปัญหาอะไรเกิดขึ้น เป็นข้อมูลเดิมๆ ซ้ำๆ กันทุกวัน ที่เข้ามาอ่านบ้าง ไม่อ่านบ้าง อ่านแล้วปกติ ก็ผ่านไป ถ้าไม่ปกติ ก็ต้องกลับมาดูว่าปัญหามันเกิดจากอะไร จึงต้องการให้มันแจ้งเตือนเฉพาะข้อผิดพลาดที่เกิดขึ้นเท่านั้น จึงต้องมีการเปรียบเทียบวันที่จากข้อมูลที่ได้จากฐานข้อมูล
SQL ที่ดึงข้อมูลจากตาางเก็บในไฟล์
sqlcmd -S . -d DATABASE_NAME -E -s\ -W -Q "set nocount on;SELECT * FROM dbo.TABLE_NAME" > output.txt
ไฟล์ที่ได้จาก SQL
today\lastHN\lastAN\lastUpd
-----\------\------\-------
25610424\ 376343\6106008\2018-04-24 02:27:46.547
Batch อ่านข้อมูลจากไฟล์
FOR /F "tokens=*" %%A IN (%file%) DO CALL SET msg=%%msg%% %%A
สุดท้ายมาลองตัด string ที่เป็นวันที่ เพื่อใช้ในการคำนวน
%msg%
ข้อความที่อ่านได้จากไฟล์
SET/a date_a=%msg:~57,8%
ตัดในตำแหน่งที่ 57 มีจำนวน 8 ตัวอักษร จะได้วันที่แบบ พ.ศ. มา
SET d=%DATE:~6,4%
ตัดในตำแหน่งที่ 6 จำนวน 4 ตัวอักษร จะได้ปี ค.ศ. ปัจจุบัน
SET/a ybe=%d%+543
บวกด้วย 543 เพื่อให้เป็นปี พ.ศ.ที่นำไปใช้งานได้ ซึ่งต้อง /a ด้วยเพื่อบอกว่ามีการใช้ค่าเพื่อคำนวณ
IF %date_a% NEQ %date_b%
เปรียบเทียบวันที่ NEQ คือ Not Equal หรือ ไม่เท่ากับ
ECHO.--------------------------------------------
ECHO.READ DATA FROM %file%
ECHO.--------------------------------------------
ECHO.Result : %msg%
ECHO.------ SPLIT STRING ------
ECHO.%msg:~0,6% : %msg:~57,8% {DATE_A}
SET/a date_a=%msg:~57,8%
ECHO.%msg:~7,6% : %msg:~67,6%
ECHO.%msg:~14,6% : %msg:~74,7%
ECHO.%msg:~21,6% : %msg:~82,23%
ECHO.------ COMMON ERA TO BUDDHIST ERA ------
ECHO.Date CE : %date%
ECHO.format : %DATE:~6,4%%DATE:~3,2%%DATE:~0,2%
SET d=%DATE:~6,4%
SET/a ybe=%d%+543
SET/a date_b=%ybe%%DATE:~3,2%%DATE:~0,2%
ECHO.Date BE : %date_b% {DATE_B}
ECHO.--------------------------------------------
IF %date_a% NEQ %date_b% (
ECHO.{DATE_A} NOT EQUAL {DATE_B}
) ELSE (
ECHO.DATE_A EQU DATE_B
)
เมื่อสำเร็จแล้ว ภาพจะออกมาแบบนี้ ลองอ่านไฟล์ output.txt และ today.txt ที่เปลี่ยนวันที่เป็นวันปัจจุบัน เพื่อเปรียบเทียบการทำงาน
แก้ปัญหาการใช้ format วันที่ไม่เหมือนกัน
เนื่องจากการตั้งรูปแบบวันที่ของแต่ละเครื่องไม่เหมือนกัน เราจึงต้องทำการ qualified โดย echo %date%
จะรู้ว่าเราใช้ format แบบไหน ซึ่งที่แก้ไขตอนนี้ ใช้ได้ 2 รูปแบบด้วยกันคือ ddd MM/DD/YYYY และ DD/MM/YYYY ตามตัวอย่าง code ดังนี้
FOR /F "tokens=2" %%i IN ('date /t') DO (SET mydate=%%i)
IF [%mydate%] == [] (
rem 24/04/2018
rem ECHO.---- DD/MM/YYYY ---- %DATE%
SET year=%DATE:~6,4%
SET /a ybe=!year!+543
SET /a date_b=!ybe!%DATE:~3,2%%DATE:~0,2%
rem ECHO.Date BE : !date_b! {DATE_B}
) ELSE (
rem Tue 04/24/2018
rem ECHO.----ddd MM/DD/YYYY ---- %DATE%
rem ECHO.%mydate%
SET year=%DATE:~10,4%
SET /a ybe=!year!+543
SET /a date_b=!ybe!%DATE:~7,2%%DATE:~4,2%
rem ECHO.Date BE : !date_b! {DATE_B}
)
สรุป.
เพื่อลดการแจ้งเตือนพร่ำเพรื่อ ซ้ำๆซากๆ เลยต้องใช้ไม้นี้แทน แต่เพิ่มการเก็บ log ให้สามารถตรวจสอบได้ว่า วันที่นี้ task นี้ได้ทำงานไปแล้ว และผลการทำงานเป็นอย่างไร
อ้างอิง
- DOS – String Manipulation การจัดการกับสตริง อ่านตรงนี้ได้ความรู้มาก บอกค่อนข้างละเอียด
https://www.dostips.com/DtTipsStringManipulation.php - Guide to Windows Batch Scripting แนะนำเกี่ยวกับ variables, return, if/then, loop, function แบบสั้นๆ เข้าใจง่าย
http://steve-jansen.github.io/guides/windows-batch-scripting/index.html - https://stackoverflow.com/questions/2541767/what-is-the-proper-way-to-test-if-variable-is-empty-in-a-batch-file?answertab=active#tab-top