23. september 2005 - 16:08Der er
14 kommentarer og 1 løsning
Mærkelig SQL-fejl
Hejhej,
Jeg har en Access DB med et varchar-felt, der udover tekst indeholder en dato. Denne dato vil jeg godt bruge i min WHERE-klausul, men jeg får en mærkelig fejl...
SELECT c_Text, Count(c_Text) as n_Count FROM ([Her er en subquery...]) AS tmp WHERE DATEDIFF('d', RIGHT(c_Text, 8), Now()) < 15 GROUP BY c_Text ORDER BY n_Count DESC
Fejlen jeg får er:
Microsoft JET Database Engine error '80040e10' No value given for one or more required parameters.
Hvis jeg fjerner WHERE-klausulen får jeg ingen fejl. Hvis jeg istedet for RIGHT(c_Text, 8) skriver RIGHT('asd as d asd 05/05/05', 8) får jeg heller ingen fejl - meget mystisk! Jeg tror "required parameters" den hentyder til er i DATEDIFF-funktionen, men der burde ikke være noget galt med den - min subquery har en klausul der hedder WHERE ISDATE(RIGHT(c_Text, 8)), så jeg ved, det er en dato der kommer ind.
Den samlede streng bliver ret lang, så jeg har mistanke om, at jeg måske støder i en længde-begrænsning eller et andet mærkeligt Access-problem...
Tak for inputtet... jeg har prøvet med CDate, Cast, Convert, # rundt om datoen osv., no dice... :(
Jeg prøvede lige at fyre samme statement af på SQL Server 2000 - det resulterer i en "Syntax error converting datetime from character string." Hvis jeg laver WHERE-klausulen om til en HAVING-klausul, virker det til gengæld fint - bare ikke i Access'en...
Har du efterstillede blanktegn i c_Text, så der skal bruges Trim()? Hvorfor bruger du Now() og ikke Date()? I stedet for Datediff() kan du prøve : Date()-CLng(CDate(Right(c_Text,8)))<15 Hvis det er i en Access forespørgsel er du opmærksom på at du skal bruge ";" i stedet for "," - DATEDIFF('d'; RIGHT(c_Text; 8);Now()) - synes bare lige jeg ville tjekke :o)
Prøv at konvertere dine datoer til heltal - CLng(Date()) og CLng(CDate(Right(c_Text,8))) - og træk dem fra hinanden, i stedet for at bruge DateDiff(). I sidste ende kan du prøve at konvertere de sidste 8 tegn i c_Text til hhv. dag, måned og år, og stoppe dem ind i en DateSerial() - besværligt, men DateSerial() slår næsten aldrig fejl.
can we just make sure where we are? You say you have tried cast/convert and also that you have tried the same SQL in SQL Server!! Are we talking Access data or SQL Server?
Sorry about the confusion - we are talking about an Access DB, but since I usually develop for SQL Server (thank God!) I tried the same SQL in SQL Server with the results as described above. As for Cast/Convert I'm not really sure what functions are supported in Access, so I was just trying different stuff out.
Claes: Tak for tippet, jeg prøver at konvertere lidt rundt når jeg får fingre i koden igen.
Why dont you convert to a date field in the sub select, get this working first and then go on to the final query. And it amy also be an idea to have a date/time field for storing your date, save all the problems your having now
Okay, det bliver mere og mere mærkeligt... Jeg har skrevet min subquery om, så den returnerer min dato i DateTime-datatypen. I min SELECT linie kan jeg bruge alle de datofunktioner på den, det skal være uden problemer - men lige så snart jeg rører ved den i WHERE-linien, siger den "Data type mismatch". Det er altså ikke et konverteringsproblem jeg har, men en eller anden form for strukturerings-problematik...
Har jeg ramt en eller anden obskur SQL- eller ODBC-regel jeg aldrig har hørt om, eller hvad er det der sker?
Hmm, nu har jeg fået det følgende til at virke på SQL Server:
SELECT c_Text FROM ( SELECT c_Text, RIGHT(c_Text, CHARINDEX(' ', REVERSE(c_Text))) as theDate FROM tLog WHERE ISDATE(RIGHT(c_Text, CHARINDEX(' ', REVERSE(c_Text)))) = 1 ) AS tmp WHERE DATEDIFF(d, theDate, GetDate()) < 12 GROUP BY c_Text
- egentlig bare en ny måde at pille datoen ud af tekstfeltet på, men det virker efter hensigten. Tilsvarende i Access-sprog er noget á la:
SELECT c_Text FROM ( SELECT c_Sti, RIGHT(c_Text, INSTRREV(' ', c_Text)) as theDate FROM tLog WHERE ISDATE(RIGHT(c_Text, INSTRREV(' ', c_Text))) = 1 ) AS tmp WHERE DATEDIFF('d', theDate, Date()) < 12 GROUP BY c_Text
- men det virker selvfølgelig ikke... (Det lugter lidt af en skjult begrænsning i tekstfunktionerne?)
SELECT TMP.c_Sti FROM [SELECT tLog.c_Sti, CDate(Right([c_sti],8)) AS theDate FROM tLog]. AS TMP WHERE (((DateDiff("d",[TMP].[theDate],Date()))<20)) GROUP BY TMP.c_Sti;
Tak for hjælpen Terry. Dit bud virker fint på den DB jeg sendte dig... jeg glemte desværre at nævne, at det ikke er alle felterne der har en dato i enden - derfor den oprindelige WHERE ISDATE(RIGHT(c_Text, 8)) - og når jeg tilføjer det, er der fejl igen... Jeg har givet op og konkluderet, at jeg er stødt i en eller anden form for uforklarlig bug / quirk, der ikke lader sig løse praktisk.
SELECT TMP.c_Sti FROM (SELECT tLog.c_Sti, CDate(IIf(IsDate(Right([c_sti],8)),Right([c_sti],8),DateAdd("yyyy",-100,Date()))) AS theDate FROM tLog) AS TMP WHERE (((DateDiff("d",[TMP].[theDate],Date()))<25));
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.