Credo proprio di aver trovato uno strano baco di sql server, ho una tabella che in un campo di testo "dovrebbe" avere un data e orario in questo formato: gg/mm/aaaa oo.mm.ss

Però fra varia gente che ha messo mano al codice delle varie applicazioni che pastrugnano con questa tabella ne viene che a volte il campo sia vuoto, a volte sia nel formato gg/m/aaaa oo.mm.ss o addirittura mm/gg/aaaa oo.mm.ss...

Insomma, un macello

Mi sono scervellato per riuscire a fare una select quanto più snella possibile ma che coprisse tutte le possibilità senza cacciare un errore inopportuno.

Tale select deve tirar fuori dei dati solo delle tuple che, in base alla 'data maldestra', hanno una data inferiore ai 30 giorni.

Vi faccio vedere la select che ho creato (nb, tira fuori tuple >=30 perché di inferiori non ce n'erano! mi serviva da provare ):
codice:
select  iddbcontact as idcontact,t1.szvalue
from (
select iddbcontact,case when cast(substring(szvalue,4,2) as integer)>12 then substring(szvalue,4,3)+substring(szvalue,1,3)+substring(szvalue,7,4) else szvalue end [szvalue]
from (select iddbcontact, case when substring(szvalue,6,1)='/' then substring(szvalue,1,10) else substring(szvalue,1,3)+'0'+substring(szvalue,4,6) end [szvalue]
from tbextfields with(nolock) 
where idtype =213 and szvalue<>'') as t0
) as t1
where datediff(d,convert(datetime,cast(t1.szvalue as varchar(10)),103),getdate()) >= 30
Questa select da il seguente errore:
Conversion failed when converting datetime from character string

Allora ho iniziato ad utilizzare TOP 1 nella select interna prima intermedia, per riuscire a capire se dava sempre errore o c'era una riga incasinata.

Liscio come l'olio.

Allora inizio con la tecnica di ricerca, un top 1000 poi 2000 etc, fino all'uscita dell'errore, poi raffino fino a beccare la riga giusta.

Ma arrivato a TOP 5000:

codice:
select  iddbcontact as idcontact,t1.szvalue
from (
select TOP 5000 iddbcontact,case when cast(substring(szvalue,4,2) as integer)>12 then substring(szvalue,4,3)+substring(szvalue,1,3)+substring(szvalue,7,4) else szvalue end [szvalue]
from (select iddbcontact, case when substring(szvalue,6,1)='/' then substring(szvalue,1,10) else substring(szvalue,1,3)+'0'+substring(szvalue,4,6) end [szvalue]
from tbextfields with(nolock) 
where idtype =213 and szvalue<>'') as t0
) as t1
where datediff(d,convert(datetime,cast(t1.szvalue as varchar(10)),103),getdate()) >= 30
Ancora andava tutto liscio e mi sono chiesto "Ma quante cacchio di tuple ha?!?"

Vado a controllare: 2403.

Allora, la select interna produce 2403 tuple che vengono passate alla select esterna, la quale le mostra tutte perché tutte soddisfano la richiesta, ma la cosa allucinante è che se io metto TOP 5000 (o comunque pari o superiore a 2403) la select nel suo complesso mi stampa correttamente tutti i risultati.
Se levo il TOP mi esce l'errore di conversione....

Baco o non baco, questo è il problema :master: