sql >> Databasteknik >  >> RDS >> Mysql

ColdFusion parametrerar en fråga

Ignorerar korrekt tillvägagångssätt för ett ögonblick är anledningen till att du använder den felaktiga cfsqltype för parametrarna. Så du skickar faktiskt andra värden till databasen (och gör följaktligen en annan jämförelse) än du tror. Som ett resultat kan frågan inte hitta några matchande poster. Det är därför ditt diagram är tomt.

Genom att använda cf_sql_timestamp du konverterar "värdet" till ett fullständigt datum/tidsobjekt. Men ÅR() returnerar endast ett fyrsiffrigt nummer. Så du jämför äpplen och apelsiner. Begreppsmässigt gör din fråga faktiskt detta:

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

Anledningen till att det inte ger ett fel är att datum/tid-värden lagras som siffror internt. Så du jämför faktiskt ett litet antal (dvs. år) med ett riktigt stort tal (dvs. datum/tid). Uppenbarligen kommer datumvärdet att vara mycket större, så det kommer nästan aldrig att matcha årstalet. Återigen, konceptuellt din fråga gör detta:

 WHERE 2014 = 1234567890

Eftersom cfsqltype är valfritt, tror många att det inte är särskilt viktigt - men det är det.

  • Verifiering: Utöver dess andra fördelar, validerar cfqueryparam det angivna "värdet", baserat på cfsqltype (datum, datum och tid, nummer, etcetera). Detta inträffar före sql skickas någonsin till databasen. Så om inmatningen är ogiltig slösar du inte bort ett databasanrop. Om du utelämnar cfsqltype, eller bara använder standard IE-strängen, förlorar du den extra valideringen.

  • Noggrannhet Att välja rätt cfsqltype säkerställer att du skickar rätt värde till databasen. Som visats ovan kan användning av fel typ göra att CF skickar fel värde till databasen.

    cfsqltype säkerställer också att värden skickas till databasen i ett icke-tvetydigt format som databasen kommer att tolka som du förväntar dig. Tekniskt sett kan du skicka allt till databasen en sträng. Det tvingar dock databasen att utföra implicit konvertering (vanligtvis oönskat).

    Med implicit konvertering lämnas tolkningen av strängarna helt upp till databasen - och den kanske inte alltid kommer fram till det svar du förväntar dig. Att skicka in datum som strängar, snarare än datumobjekt, är ett utmärkt exempel på det. Hur kommer den aktuella databasen att tolka en datumsträng som "05/04/2014"? Som 5 april eller 4 maj? Det beror på. Ändra databasen eller databasinställningarna så kan resultatet bli helt annorlunda.

Det enda sättet att säkerställa konsekventa resultat är att specificera lämplig cfsqltype. Den bör matcha datatypen för jämförelsekolumnen/funktionen, eller åtminstone en motsvarande typ. I fallet med YEAR() , returnerar det ett fyrsiffrigt nummer. Så du bör använda cf_sql_integer , eftersom Adrian nämnde kommentarerna . Detsamma gäller för din MONTH() jämförelse.

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

Nu när allt är sagt, Dans förslag är det bättre sättet att göra datumjämförelser. Det paradigmet är mer indexvänlig och fungerar oavsett om din målkolumn innehåller ett datum (endast) eller ett datum och tid. Notera användningen av cf_sql_date i hans exempel.

  • cf_sql_timestamp - skickar både datum och tid
  • cf_sql_date - skickar endast ett datum. tidsvärdet trunkeras


  1. PostgreSQL motsvarighet till Oracle bulk collect

  2. Strange MySQL Popup Mysql Installer körs community mode

  3. Mitt webbhotell säger att det är något fel med PHP-kod

  4. MySQL - ignorera infogningsfel:dubblettpost