Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

So sánh các ngày được lưu trữ dưới dạng varchar

Việc lưu trữ các giá trị ngày dưới dạng varchar chỉ là sai.

Nếu có thể, bạn nên thay đổi bảng để lưu trữ chúng dưới dạng kiểu dữ liệu ngày tháng.
Bạn có thể thực hiện điều đó trong một vài bước đơn giản:

  1. Đổi tên các cột hiện tại (tôi đoán ScheduleStartDate cũng là varchar) thành columnName_old. Điều này có thể dễ dàng thực hiện bằng cách sử dụng sp_rename .

  2. Sử dụng alter table để thêm các cột với kiểu dữ liệu thích hợp.

  3. Sao chép các giá trị từ các cột cũ sang các cột mới bằng cách sử dụng câu lệnh cập nhật. Vì tất cả các ngày được lưu trữ ở cùng một định dạng, bạn có thể sử dụng convert như thế này:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103) Nếu phiên bản máy chủ sql của bạn là 2012 trở lên, hãy sử dụng try_convert . Lưu ý rằng tôi đã sử dụng nullif , ltrimrtrim để chuyển đổi các giá trị chỉ chứa khoảng trắng thành rỗng.
  4. Thả và tạo lại các chỉ mục tham chiếu đến các cột này. Cách đơn giản nhất để thực hiện việc này là nhấp chuột phải vào chỉ mục trên SSMS và chọn script index as -> drop and create .
  5. Sử dụng alter table để xóa các cột cũ.

Lưu ý: nếu các cột này đang được tham chiếu trong bất kỳ đối tượng nào khác trên cơ sở dữ liệu, bạn cũng sẽ phải thay đổi các đối tượng này. Điều này bao gồm các thủ tục được lưu trữ, khóa ngoại, v.v. '.

Nếu bạn không thể thay đổi loại dữ liệu của các cột và phiên bản máy chủ sql của bạn thấp hơn năm 2012, bạn cần sử dụng chuyển đổi như sau:

SELECT * FROM tblServiceUsersSchedule 
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103) 
      < CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL

Lưu ý rằng nếu bạn có ngay cả một hàng trong đó dữ liệu của cột không ở định dạng dd / MM / yyyy, điều này sẽ gây ra lỗi.

Đối với phiên bản máy chủ sql 2012 trở lên, hãy sử dụng Try_convert . Hàm này sẽ chỉ trả về null nếu chuyển đổi không thành công:

SELECT * FROM tblServiceUsersSchedule 
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
      < CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL

Lưu ý: Tôi đã sử dụng CAST(GETDATE() as Date) để xóa phần thời gian của ngày hiện tại. Điều này có nghĩa là bạn sẽ chỉ nhận được các bản ghi trong đó ScheduleEndDate ít nhất một ngày tuổi. Nếu bạn cũng muốn lấy các bản ghi trong đó ScheduleEndDate là ngày hôm nay, hãy sử dụng <= thay vì < .

Một điều cuối cùng: Việc sử dụng các hàm trên các cột trong mệnh đề where sẽ ngăn Máy chủ Sql sử dụng bất kỳ lập chỉ mục nào trên các cột này.
Đây là một lý do khác tại sao bạn nên thay đổi các cột của mình thành kiểu dữ liệu thích hợp.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Không thể mở cơ sở dữ liệu mặc định người dùng. Đăng nhập thất bại. sau khi cài đặt SQL Server Management Studio Express

  2. Cách tìm vị trí tệp mặc định cho tệp dữ liệu và tệp nhật ký trong SQL Server

  3. Cách kết hợp ngày từ một trường với thời gian từ một trường khác - MS SQL Server

  4. Cách COUNT () hoạt động trong SQL Server

  5. Ràng buộc SQL DEFAULT để Chèn cột có giá trị mặc định vào bảng SQL Server