sql >> Database teknologi >  >> RDS >> Mysql

ColdFusion Parametrisering af en forespørgsel

Ignorerer den korrekte tilgang et øjeblik er årsagen til det, at du bruger den forkerte cfsqltype for parametrene. Så du sender faktisk andre værdier til databasen (og udfører følgelig en anden sammenligning), end du tror. Som et resultat kan forespørgslen ikke finde nogen matchende poster. Det er derfor dit diagram er tomt.

Ved at bruge cf_sql_timestamp du konverterer "værdien" til et fuldt dato/tidsobjekt. Men ÅR() returnerer kun et firecifret tal. Så du sammenligner æbler og appelsiner. Konceptuelt gør din forespørgsel faktisk dette:

  WHERE  2014 = {ts '2009-02-13 23:31:30'}

Grunden til at det ikke giver en fejl er, at dato/tidsværdier gemmes som tal internt. Så du sammenligner faktisk et lille tal (dvs. år) med et rigtig stort tal (dvs. dato/klokkeslæt). Det er klart, at datoværdien vil være meget større, så den vil næsten aldrig matche årstallet. Igen, konceptuelt din forespørgsel gør dette:

 WHERE 2014 = 1234567890

Da cfsqltype er valgfri, tror mange mennesker, at det ikke er særlig vigtigt - men det er det.

  • Validering: Ud over dets andre fordele validerer cfqueryparam den leverede "værdi" baseret på cfsqltype (dato, dato og klokkeslæt, nummer osv.). Dette sker før sql bliver nogensinde sendt til databasen. Så hvis input er ugyldigt, spilder du ikke et databasekald. Hvis du udelader cfsqltype, eller bare bruger standard dvs. strengen, så mister du den ekstra validering.

  • Nøjagtighed Valg af den korrekte cfsqltype sikrer, at du sender den korrekte værdi til databasen. Som vist ovenfor kan brug af den forkerte type få CF til at sende den forkerte værdi til databasen.

    cfsqltype sikrer også, at værdier sendes til databasen i et ikke-tvetydigt format, databasen vil fortolke, som du forventer. Teknisk kunne du sende alt til databasen en streng. Det tvinger dog databasen til at udføre implicit konvertering (normalt uønsket).

    Med implicit konvertering overlades fortolkningen af ​​strengene helt op til databasen - og den kommer måske ikke altid med det svar, du ville forvente. At indsende datoer som strenge i stedet for datoobjekter er et godt eksempel på det. Hvordan vil den aktuelle database fortolke en datostreng som "05/04/2014"? Som 5. april eller en 4. maj? Det kommer an på. Ændre databasen eller databaseindstillingerne, og resultatet kan blive helt anderledes.

Den eneste måde at sikre ensartede resultater på er at angive den passende cfsqltype. Det skal matche datatypen for sammenligningskolonnen/-funktionen eller i det mindste en tilsvarende type. I tilfælde af YEAR() , returnerer det et firecifret tal. Så du bør bruge cf_sql_integer , da Adrian nævnte kommentarerne . Det samme gælder for din MONTH() sammenligning.

 WHERE Year(ColumnName) = <cfqueryparam value="2014" cfsqltye="CF_SQL_INTEGER">
 AND   Month(ColumnName) = <cfqueryparam value="11" cfsqltye="CF_SQL_INTEGER"> 

Når alt det er sagt, Dans forslag er den bedre måde at udføre datosammenligninger på. Det paradigme er mere indeksvenlig og virker uanset om din målkolonne indeholder en dato (kun) eller en dato og et klokkeslæt. Bemærk brugen af ​​cf_sql_date i hans eksempel.

  • cf_sql_timestamp - sender både dato og klokkeslæt
  • cf_sql_date - sender kun en dato. tidsværdien afkortes


  1. får fejl HTTP Status 405 - HTTP-metoden GET understøttes ikke af denne URL, men bruges aldrig 'get'?

  2. Sådan indlæses og administreres data i Microsoft Power BI

  3. Ret "FEJL 1054 (42S22):Ukendt kolonne "..." i "ordre clause", når du bruger UNION i MySQL

  4. SQLDeveloper viser ingen tabeller under forbindelser, hvor der står tabeller