Bỏ qua cách tiếp cận đúng
trong giây lát, lý do xảy ra là bạn đang sử dụng cfsqltype
không chính xác cho các tham số. Vì vậy, bạn thực sự đang gửi các giá trị khác nhau đến cơ sở dữ liệu (và do đó thực hiện một phép so sánh khác) so với bạn đang nghĩ. Kết quả là, truy vấn không tìm thấy bất kỳ bản ghi phù hợp nào. Đó là lý do tại sao biểu đồ của bạn trống.
Bằng cách sử dụng cf_sql_timestamp
bạn đang chuyển đổi "giá trị" thành một đối tượng ngày / giờ đầy đủ. Tuy nhiên, YEAR () chỉ trả về một số có bốn chữ số. Vì vậy, bạn đang so sánh táo và cam. Về mặt khái niệm, truy vấn của bạn thực sự đang thực hiện điều này:
WHERE 2014 = {ts '2009-02-13 23:31:30'}
Lý do nó không gây ra lỗi là các giá trị ngày / giờ được lưu trữ dưới dạng số trong nội bộ. Vì vậy, bạn thực sự đang so sánh một số nhỏ (tức là năm) với một số thực sự lớn (tức là ngày / giờ). Rõ ràng giá trị ngày tháng sẽ lớn hơn nhiều, vì vậy nó gần như không bao giờ khớp với số năm. Một lần nữa, về mặt khái niệm truy vấn của bạn đang thực hiện điều này:
WHERE 2014 = 1234567890
Vì cfsqltype là tùy chọn nên nhiều người nghĩ rằng nó không quan trọng lắm - nhưng đúng là như vậy.
-
Xác thực: Ngoài các lợi ích khác của nó, cfqueryparam xác thực "giá trị" được cung cấp, dựa trên
cfsqltype
(ngày, tháng và giờ, số, vân vân). Điều này xảy ra trước sql đã từng được gửi đến cơ sở dữ liệu. Vì vậy, nếu đầu vào không hợp lệ, bạn không lãng phí một cuộc gọi cơ sở dữ liệu. Nếu bạn bỏ qua cfsqltype hoặc chỉ sử dụng chuỗi tức là mặc định, thì bạn sẽ mất xác thực bổ sung đó. -
Độ chính xác Việc chọn cfsqltype thích hợp đảm bảo bạn gửi đúng giá trị đến cơ sở dữ liệu. Như đã trình bày ở trên, việc sử dụng sai kiểu có thể khiến CF gửi sai giá trị đến cơ sở dữ liệu.
cfsqltype
cũng đảm bảo các giá trị được gửi đến cơ sở dữ liệu ở định dạng không mơ hồ mà cơ sở dữ liệu sẽ diễn giải theo cách bạn mong đợi. Về mặt kỹ thuật, bạn có thể gửi mọi thứ đến cơ sở dữ liệu một chuỗi. Tuy nhiên, điều đó buộc cơ sở dữ liệu phải thực hiện chuyển đổi ngầm (thường là không mong muốn).Với chuyển đổi ngầm định, việc giải thích các chuỗi hoàn toàn phụ thuộc vào cơ sở dữ liệu - và nó có thể không phải lúc nào cũng đưa ra câu trả lời mà bạn mong đợi. Gửi ngày tháng dưới dạng chuỗi, thay vì đối tượng ngày tháng, là một ví dụ điển hình về điều đó. Cơ sở dữ liệu hiện tại sẽ diễn giải chuỗi ngày tháng như "05/04/2014" như thế nào? Là ngày 5 tháng 4 hay ngày 4 tháng 5? Nó phụ thuộc. Thay đổi cơ sở dữ liệu hoặc cài đặt cơ sở dữ liệu và kết quả có thể hoàn toàn khác.
Cách duy nhất để đảm bảo kết quả nhất quán là chỉ định cfsqltype thích hợp. Nó phải khớp với kiểu dữ liệu của cột / hàm so sánh hoặc ít nhất là một kiểu tương đương. Trong trường hợp của YEAR()
, nó trả về một số có bốn chữ số. Vì vậy, bạn nên sử dụng cf_sql_integer
, như Adrian đã đề cập đến các nhận xét
. Điều tương tự cũng áp dụng cho MONTH ()
WHERE Year(ColumnName) = <cfqueryparam value="2014" cfsqltye="CF_SQL_INTEGER">
AND Month(ColumnName) = <cfqueryparam value="11" cfsqltye="CF_SQL_INTEGER">
Bây giờ đã nói tất cả những điều đó, đề xuất của Dan
là cách tốt hơn để thực hiện so sánh ngày. Mô hình đó
thân thiện với chỉ mục hơn và hoạt động bất kể cột mục tiêu của bạn có chứa ngày (chỉ) hay ngày giờ. Lưu ý việc sử dụng cf_sql_date
trong ví dụ của mình.
-
cf_sql_timestamp
- gửi cả ngày và giờ -
cf_sql_date
- chỉ gửi một ngày. giá trị thời gian bị cắt ngắn