[SQL Server] SELECT เมื่อพบข้อมูลวันที่เป็น 1990-01-01 ให้แสดงเป็น String ว่าง

ปัญหาที่ได้เจอวันนี้ คือ SELECT ข้อมูลวันที่ ที่บาง Record เก็บข้อมูลไม่ได้มีการเก็บข้อมูลวันที่ แต่ผลลัพธ์ที่ได้กลับเป็น 01-Jan-1990 (SQL Server ใจดีใส่ให้) ถ้าหาก User มาเห็นคงตกใจ คิดว่าระบบงานของเราเกิด Defect ชิ้นใหญ่แน่นอน

เตรียมข้อมูล

  • กำหนดโครงสร้างตาราง ดังรูป

1

  • ใส่ข้อมูลคร่าวๆลงไป ดังรูป

2

ความต้องการ

  • แสดงข้อมูลยอด BUY/SELL โดยต้องแสดง TX_ID, PRODUCT_NAME, TX_UNIT, TX_TYPE, TX_TradeDate และ TX_IsConfirm
  • ต้องการให้แถวที่มีข้อมูล Date ข้อมูลวันที่เป็น 1990-01-01 ระบบต้องไม่แสดงผลเป็น 1990-01-01 แต่แสดงผลเป็น String ว่างแทน
  • ภาพด้านล่างแสดงตัวอย่างปัญหาที่ SELECT ข้อมูลมาแล้ว เกิดมา 1990-01-01 ติดมา

3

1990-01-01 มาจากไหน เกิดขึ้นได้อย่างไร

  • Insert ข้อมูลประเภทวันที่แล้วลืม ' ครอบ เช่น 1990-04-23 (ที่ถูกควรเป็น '1990-04-23' ) ระบบเลยมองว่าเป็น 0 แต่ถ้าใช้พวก ORM ปัญหาเหล่านี้น่าจะหมดไป เพราะเราไม่ต้องยุ่งกับ SQL
  • Insert 0 ใส่ลงไป
  • Insert ข้อมูลวันที่ผิด Format (Format ที่ถุกต้องคือ YYYY-MM-DD)
  • มีการแก้ไขข้อมูลในฐานข้อมูลโดยตรงจาก DBA ซึ่งอาจจะเกิดข้อผิดพลาดได้

หมายเหตุ 1990-01-01 มีค่าเท่ากับ 0 (SQL Server มองเป็นวันที่วันแรกของระบบ)

วิธีแก้ปัญหา

  • มีหลากหลายวิธีมากทั้งแก้ไขจาก Source Code หรือจากตัว Query SQL เอง จะใช้แบบไหน แล้วแต่กรณี และความเหมาะสมครับ ^__^ โดยผมได้ลองเขียนสองแบบ ดังนี้
    • ใช้คำสั่ง CASE ตามตัวอย่าง ดังนี้

[sql]SELECT OT.TX_ID,
P.PRODUCT_NAME AS PRODUCT_NAME,
OT.TX_UNIT,
OT.TX_TYPE,
CASE OT.TX_TradeDate
WHEN '1990-01-01' THEN ''
ELSE OT.TX_TradeDate
END AS TX_TRADEDATE,
OT.TX_IsConfirm
FROM OrderTX OT
LEFT OUTER JOIN Product P
on OT.PRODUCT_ID = P.PRODUCT_ID
[/sql]

    • ใช้ฟังก์ชั่น Replace

[sql]SELECT OT.TX_ID,
P.PRODUCT_NAME AS PRODUCT_NAME,
OT.TX_UNIT,
OT.TX_TYPE,
CASE OT.TX_TradeDate
WHEN '1990-01-01' THEN ''
ELSE OT.TX_TradeDate
END AS TX_TRADEDATE,
OT.TX_IsConfirm
FROM OrderTX OT
LEFT OUTER JOIN Product P
on OT.PRODUCT_ID = P.PRODUCT_ID
[/sql]

ผลการแก้ไข สามารถแสดงข้อมูลได้ตรงตามความต้องการ ดังรูป
4

สรุป

  • วิธีแก้ปัญหาของปัญหานี้ พบว่ามีทางแก้ได้หลากหลายวิธี ซึ่งจะแก้ที่ตัว SQL หรือมาแก้ใน Source Code โปรแกรมก็ได้ครับ (แต่ละวิธีก็เขียนได้หลายแบบ) ในกรณีนี้ผมเลือกจะแก้จากตัว Query SQL ซึ่งแต่ละแบบก็มีข้อดี และข้อเสียที่แต่ต่างกัน โดยสรุปคร่าวๆ ดังนี้
    • แก้จาก Source Code
      • จุดเด่น คือ SQL ของเรามีความเป็นมาตรฐาน สามารถใช้งานได้กับ DBMS ที่หลากหลาย เพราะไม่ได้ใช้ฟังก์ชั่นเฉพาะ
      • จุดด้อย คือ เราต้องเสียเวลาไปไล่แก้ Code เพื่อป้องกันปัญหาที่เกิดขึ้น
    • แก้จาก SQL
      • จุดเด่น คือ แก้ที่ SQL จุดเดียว ไม่ต้องไปไล่แก้เก็บใน Source Code
      • จุดด้อย คือ Query SQL ที่ใช้นั้น อาจจะมีบางฟังค์ชั่นที่ใช้ได้เฉพาะในฐานข้อมูลนั้นๆ จึงทำให้ระบบของเราไม่สามารถไปใช่งานกับฐานข้อมูลอื่นได้ เช่น ในที่นี้ใน MS SQL SERVER แต่ถ้าเปลี่ยนไปเป็น DB2 หรือ ORACLE เราอาจจะต้องมานั่งไป SQL กับใหม่

Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts to your email.