Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

errore durante la conversione di varchar in float

Significa che hai almeno una riga nella tabella che non può essere convertita in float . Facendo il CASE è sicuro, ma combinare il CTE e aggiungere una clausola WHERE cade in un errore comune dei programmatori quando scrivono T-SQL:quell'ordine di dichiarazione implica un ordine di esecuzione . I programmatori sono abituati allo stile procedurale imperativo dei linguaggi simili al C e non riescono a comprendere la natura dichiarativa basata su insiemi di SQL. Ho già scritto su questo problema e fornito esempi quando l'errore causa errori:

Una volta pubblicato il codice completo, possiamo vedere dove hai commesso l'errore nel tuo caso e assunto un certo ordine di esecuzione.

dopo l'aggiornamento

OK, quindi devo amministrare che nel tuo caso il codice è corretto nell'ordine di esecuzione, il result la colonna non può essere proiettata senza prima valutare il CASE . Se il CASE fosse stato in una clausola WHERE le cose sarebbero andate diversamente.

Il tuo problema è diverso:ISNUMERIC . Questa funzione ha una comprensione molto generosa di cosa NUMERIC significa e ha morso molti sviluppatori prima. Vale a dire, accetta valori che CAST e CONVERT rifiuteranno. Come quelli che contengono una virgola:

declare @n varchar(8000) = '1,000';
select isnumeric(@n);
select cast(@n as float);
select case when isnumeric(@n)=1 then cast(@n as float) else null end;

Quindi hai valori che superano il ISNUMERIC prova ma non riesci a convertire. Solo un avvertimento, più scaverai in questo approccio, più porte chiuse troverai. Non è un modo sicuro per eseguire il cast di cui hai bisogno sul lato server. Idealmente, correggere il modello di dati (rendere il campo un float se memorizza float). A parte ciò, valuta i dati e rimuovi tutti i valori che non sono un float corretto e correggi il front-end/l'applicazione per non introdurne più di nuovi, quindi aggiungi un vincolo che attiverà l'errore se vengono visualizzati nuovi valori errati. Non sarai in grado di risolvere questo problema in una query, quella strada è disseminata di corpi.

Con la prossima versione di SQL Server avrai una nuova funzione, TRY_CONVERT , questo risolverebbe il tuo problema.