Discussione:
Replace per sostituire i caratteri non numerici
(troppo vecchio per rispondere)
Diego
2009-05-12 12:35:04 UTC
Permalink
Salve a tutti,
In SQL SERVER 2005
ho una tabella in cui registro le fatture. Il campo NumeroFattura è di tipo
testo perchè si deve poter mettere anche un valore del tipo "100/A".

In questo modo però non riesco più a creare un progressivo del numero di
fattura.
Per farlo utilizzo questa query:

SELECT MAX(CONVERT(int,NFATT)) as nMax FROM Fatture
In questo caso l'esecuzione della query restituisce:
"Conversione non riuscita durante la conversione del valore nvarchar 100/A'
nel tipo di dati int."
Il che è logico!!!

Quindi mi chiedevo come raggirare il problema; sarebbe possibile utilizzare
la funzione REPLACE all'interno di CONVERT() per sostuire con "" i caratteri
non numerici???
Forse così si risolverebbe...

Se avete altre idee sono comunque bene accette.

Grazie a tutti.
DIEGO
Marcello
2009-05-12 18:48:53 UTC
Permalink
Post by Diego
Salve a tutti,
Ciao Diego,
Post by Diego
In SQL SERVER 2005
ho una tabella in cui registro le fatture. Il campo NumeroFattura è di tipo
testo perchè si deve poter mettere anche un valore del tipo "100/A".
...mmm.... non è una buona scelta.
Come garantisci l'unicità del numero assegnato? come gestisci le
differenze ta "100 / a" e "100/A"? Come controlli se ci sono buchi o meno?

prova a considerare invece una struttura del tipo:

use tempdb
go
create table Fatture(
/*Un surrogato, in questa sede non ci interessa.*/
Id_Fattura int identity primary key,
Data datetime not null,
/*Campo calcolato! Permetterà di aggiungere un vincolo univoco!*/
Anno as year(data),
/*Numero è intero! permette di gestire con disinvoltura tutti i
problemi legati alla protocollazione.*/
Numero int not null,
Protocollo char(1) not null,
/*Check a livello di db dei protocolli ridotti ad un insieme
predefinito!*/
check(Protocollo in('A', 'B', 'C')),
/*Unicità di protocollazione per anno*/
unique(Anno, Protocollo, Numero))
go
drop table Fatture
Post by Diego
In questo modo però non riesco più a creare un progressivo del numero di
fattura.
SELECT MAX(CONVERT(int,NFATT)) as nMax FROM Fatture
ehehe, infatti, ecco i problemi generati da un'architettura scorretta.
MAX(CONVERT(int,X)) è sempre sospetto se X è una stringa.
Ricorda Murphy, se qualcosa può andare male lo farà.
Post by Diego
"Conversione non riuscita durante la conversione del valore nvarchar 100/A'
nel tipo di dati int."
Il che è logico!!!
Già più che logico!
Con una struttura analoga a quella proposta potresti invece scrivere
tranquillamente:

Select max(Numero) from Fatture where Anno=year(getdate()) and
Protocollo = @Protocollo

Osserva, di passaggio, come la definizione strutturale corretta e, se
vuoi, pedante, della tabella, specificando tutte le opzioni
architetturali porta enormi vantaggi anche sul piano delle performances.
Il vincolo univoco su Anno, Protocollo, Numero infatti "riflette" la
richiesta "naturale" di "max(Numero) where Anno=year(getdate()) and
Protocollo = @Protocollo" e poichè il vincolo univoco è implementato
naturalmente con un albero b-tree quella query [ancora una volta]
"naturale" risulta massimamente performante, e assieme a quella saranno
"naturalmente" ottimizzate statistiche e verifiche. Dopo si che si parla
di fine tuning. :-)
Post by Diego
Quindi mi chiedevo come raggirare il problema; sarebbe possibile utilizzare
la funzione REPLACE all'interno di CONVERT() per sostuire con "" i caratteri
non numerici???
Si, puoi, e puoi arricchire di aggeggi e funzioni la tua query
accodandoti, quando in db ci saranno 10000 fatture, ai pessimi dba che
si ritrovano a consigliare di cambiare server perchè quello che c'è è
troppo lento, scoprendo poi sconsolato che anche con il processore più
spinto e costoso sul mercato quel gestionale continua a girare come
office 2007 su un 286. :-)
Post by Diego
Forse così si risolverebbe...
Se avete altre idee sono comunque bene accette.
Grazie a tutti.
DIEGO
marc.

Loading...