De juiste aanpak
negeren even, de reden dat dit gebeurt, is dat je het verkeerde cfsqltype
. gebruikt voor de parameters. U stuurt dus eigenlijk andere waarden naar de database (en voert dus een andere vergelijking uit) dan u denkt. Als gevolg hiervan kan de query geen overeenkomende records vinden. Daarom is uw diagram leeg.
Door cf_sql_timestamp
. te gebruiken u converteert de "waarde" naar een volledig datum/tijd-object. Echter, YEAR() geeft alleen een getal van vier cijfers terug. Je bent dus appels en peren aan het vergelijken. Conceptueel doet uw vraag eigenlijk dit:
WHERE 2014 = {ts '2009-02-13 23:31:30'}
De reden dat er geen fout wordt gegenereerd, is dat de datum-/tijdwaarden intern als getallen worden opgeslagen. U vergelijkt dus eigenlijk een klein aantal (dwz jaar) met een heel groot aantal (dwz datum/tijd). Het is duidelijk dat de datumwaarde veel groter zal zijn, dus het zal bijna nooit overeenkomen met het jaarnummer. Nogmaals, conceptueel uw vraag doet dit:
WHERE 2014 = 1234567890
Omdat cfsqltype optioneel is, denken veel mensen dat het niet erg belangrijk is, maar dat is het wel.
-
Validatie: Naast de andere voordelen valideert cfqueryparam de geleverde "waarde", op basis van het
cfsqltype
(datum, datum en tijd, nummer, enzovoort). Dit gebeurt voor de sql wordt ooit naar de database verzonden. Dus als de invoer ongeldig is, verspil je geen database-aanroep. Als je het cfsqltype weglaat, of gewoon de standaard ie string gebruikt, dan verlies je die extra validatie. -
Nauwkeurigheid Door het juiste cfsqltype te selecteren, zorgt u ervoor dat u de juiste waarde naar de database stuurt. Zoals hierboven aangetoond, kan het gebruik van het verkeerde type ertoe leiden dat CF de verkeerde waarde naar de database stuurt.
Het
cfsqltype
zorgt er ook voor dat waarden naar de database worden verzonden in een niet-dubbelzinnig formaat dat de database zal interpreteren zoals u verwacht. Technisch gezien zou je alles een string naar de database kunnen sturen. Dat dwingt de database echter om impliciete conversie (meestal ongewenst).Bij impliciete conversie wordt de interpretatie van de strings geheel aan de database overgelaten - en het kan zijn dat deze niet altijd het antwoord geeft dat u zou verwachten. Het indienen van datums als strings, in plaats van datumobjecten, is daar een goed voorbeeld van. Hoe interpreteert de huidige database een datumreeks zoals "05/04/2014"? Als 5 april of 4 mei? Het hangt er van af. Wijzig de database of de database-instellingen en het resultaat kan compleet anders zijn.
De enige manier om consistente resultaten te garanderen, is door het juiste cfsqltype op te geven. Het moet overeenkomen met het gegevenstype van de vergelijkingskolom/-functie, of op zijn minst een equivalent type. In het geval van YEAR()
, het geeft een getal van vier cijfers terug. U moet dus cf_sql_integer
. gebruiken , aangezien Adrian de opmerkingen vermeldde
. Hetzelfde geldt voor uw MAAND() vergelijking.
WHERE Year(ColumnName) = <cfqueryparam value="2014" cfsqltye="CF_SQL_INTEGER">
AND Month(ColumnName) = <cfqueryparam value="11" cfsqltye="CF_SQL_INTEGER">
Dat gezegd hebbende, Dan's suggestie
is de betere manier om datumvergelijkingen uit te voeren. Dat paradigma
is indexvriendelijker en werkt ongeacht of uw doelkolom een datum (alleen) of een datum en tijd bevat. Let op het gebruik van cf_sql_date
in zijn voorbeeld.
cf_sql_timestamp
- stuurt zowel een datum als een tijdcf_sql_date
- stuurt alleen een datum. de tijdswaarde wordt afgekapt