Игнориране на правилния подход
за момент причината, която се случва е, че използвате неправилния cfsqltype
за параметрите. Така че всъщност изпращате различни стойности към базата данни (и следователно извършвате различно сравнение), отколкото си мислите. В резултат на това заявката не успява да намери съвпадащи записи. Ето защо диаграмата ви е празна.
С помощта на cf_sql_timestamp
преобразувате "стойността" в пълен обект за дата/час. Въпреки това, YEAR() връща само четирицифрено число. Така че сравнявате ябълки и портокали. Концептуално, вашата заявка всъщност прави това:
WHERE 2014 = {ts '2009-02-13 23:31:30'}
Причината да не хвърля грешка е, че стойностите за дата/час се съхраняват вътрешно като числа. Така че всъщност сравнявате малко число (т.е. година) с наистина голямо число (т.е. дата/час). Очевидно стойността на датата ще бъде много по-голяма, така че почти никога няма да съответства на номера на годината. Отново, концептуално вашата заявка прави това:
WHERE 2014 = 1234567890
Тъй като cfsqltype не е задължителен, много хора смятат, че не е много важно, но е така.
-
Проверка: В допълнение към другите си предимства, cfqueryparam валидира предоставената "стойност" въз основа на
cfsqltype
(дата, дата и час, номер и т.н.). Това се случва преди sql винаги се изпраща към базата данни. Така че, ако входът е невалиден, не губите извикване на база данни. Ако пропуснете cfsqltype или просто използвате низа по подразбиране, т.е., губите тази допълнителна проверка. -
Точност Изборът на правилния cfsqltype гарантира, че изпращате правилната стойност към базата данни. Както беше показано по-горе, използването на грешен тип може да накара CF да изпрати грешна стойност към базата данни.
cfsqltype
също така гарантира, че стойностите се подават в базата данни в недвусмислен формат, който базата данни ще интерпретира по начина, по който очаквате. Технически бихте могли да изпратите всичко в базата данни като низ. Това обаче принуждава базата данни да изпълнява неявно преобразуване (обикновено нежелателно).При имплицитното преобразуване, интерпретацията на низовете е оставена изцяло на базата данни - и тя не винаги може да излезе с отговора, който бихте очаквали. Представянето на дати като низове, а не като обекти за дата, е отличен пример за това. Как текущата база данни ще интерпретира низ от дата като "05/04/2014"? Като 5 април или 4 май? Зависи. Променете базата данни или настройките на базата данни и резултатът може да е напълно различен.
Единственият начин да осигурите последователни резултати е да посочите подходящия cfsqltype. Трябва да съответства на типа данни на колоната/функцията за сравнение или поне на еквивалентен тип. В случай на YEAR()
, връща четирицифрено число. Така че трябва да използвате cf_sql_integer
, тъй като Ейдриън спомена коментарите
. Същото важи и за вашия MONTH() сравнение.
WHERE Year(ColumnName) = <cfqueryparam value="2014" cfsqltye="CF_SQL_INTEGER">
AND Month(ColumnName) = <cfqueryparam value="11" cfsqltye="CF_SQL_INTEGER">
След като каза всичко това, Предложение на Дан
е по-добрият начин за извършване на сравнения на дати. Тази парадигма
е по-удобен за индексиране и работи независимо дали вашата целева колона съдържа дата (само) или дата и час. Обърнете внимание на използването на cf_sql_date
в неговия пример.
cf_sql_timestamp
- изпраща дата и часcf_sql_date
- изпраща само дата. стойността на времето е съкратена