Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Roborock Qrevo Curv 2 Flow: ora lava con un rullo
Roborock Qrevo Curv 2 Flow: ora lava con un rullo
Qrevo Curv 2 Flow è l'ultima novità di casa Roborock per la pulizia di casa: un robot completo, forte di un sistema di lavaggio dei pavimenti basato su rullo che si estende a seguire il profilo delle pareti abbinato ad un potente motore di aspirazione con doppia spazzola laterale
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Abbiamo guidato per diversi giorni la Alpine A290, la prima elettrica del nuovo corso della marca. Non è solo una Renault 5 sotto steroidi, ha una sua identità e vuole farsi guidare
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Abbiamo provato a fondo il nuovo Magic 8 Lite di HONOR, e per farlo siamo volati fino a Marrakech , dove abbiamo testato la resistenza di questo smartphone in ogni condizione possibile ed immaginabile. Il risultato? Uno smartphone praticamente indistruttibile e con un'autonomia davvero ottima. Ma c'è molto altro da sapere su Magic 8 Lite, ve lo raccontiamo in questa recensione completa.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 20-05-2009, 14:52   #1
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
[SQL] UNIQUE...

Ciao, a tutti.
sto convertendo alcune tabelle da FoxPro a SQL utilizzando SQL Server. In FoxPro ho un campo che se non è vuoto deve essere univoco*, c'è un modo in SQL per ricreare la stessa situazione?
So che utilizzando la clausola UNIQUE non posso avere valori doppi ma questo vale anche se è vuoto.
Qualcuno ha qualche idea?

Grazie in anticipo.


* In foxpro il campo è reso univoco dall'indice, che ha come filtro la condizione !EMPTY(...) per cui è univoco solo se non è vuoto.
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 20-05-2009, 17:17   #2
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quello che chiedi in SqlServer non si puo' fare in modo naturale perche' NULL e' un valore come un altro, e quindi non si possono inserire piu' NULL nella stessa colonna con vincolo unique.
(PS: Ritengo che il comportamento di altri engine, come ORACLE o appunto FoxPro sia quello corretto).

Pero' esiste un workaround:

Innanzitutto la tabella deve disporre di una colonna univoca a singola colonna.
Quindi o c'e' gia' una chiave primaria/colonna univoca oppure occorre metterla con una IDENTITY(1,1)

Chiamiamo COLONNA1 la colonna target, ovvero quella per la quale si vorrebbe il vincolo di univocita' come sotto Oracle, FoxPro, etc.
Occorre inserire una nuova colonna calcolata, chiamiamola SURRUK, che varra' COLONNA1 quando COLONNA1 non e' NULL, altrimenti varra' il valore della colonna univoca.

Il calcolo e' quindi
CASE WHEN COLONNA1 != NULL THEN COLONNA1 ELSE **UK** END

Per costruzione, quando si inserira' una riga con null, allora SURRUK conterra' un valore sicuramente univoco.
Quando invece si inserira' qualcosa in Colonna1, allora SURRUK varra' tale valore.
Su SURRUK si potra' aggiungere un constraint di univocita' che si comportera' proprio come desiderato.

Esempio con chiave primaria gia' esistete di tipo numerico, e con colonna target "Colonna1" di tipo testuale

Codice:
create table prpr
(
    veraPK int identity(1,1),
    Colonna1 varchar(30),    
    SURRUK as CASE WHEN Colonna1 IS NOT NULL THEN Colonna1 ELSE CAST( veraPK AS VARCHAR(30)) END,
)

CREATE UNIQUE INDEX IU_PRPR_SURRUK ON prpr(SURRUK);

insert into prpr(Colonna1) values('abc');
insert into prpr(Colonna1) values('def');
insert into prpr(Colonna1) values(NULL);
insert into prpr(Colonna1) values(NULL);
-- fin qui tutto OK!!!

insert into prpr(Colonna1) values('abc');
-- Qui si schianta.
-- Schiantare e' il verbo tecnico usato in questi casi.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.

Ultima modifica di gugoXX : 20-05-2009 alle 17:20.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 08:43   #3
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
Ok, sembra ottimo adesso provo
Dovrebbe funzionare anche per stringhe vuote che non sono null, vero? Basta cambiare la condizione in
Codice:
SURRUK as CASE WHEN Colonna1 IS NOT NULL AND Colonna1 <> '' THEN Colonna1 ELSE CAST( veraPK AS VARCHAR(30)) END,
Quando ho scritto vuoto intendevo '' e non NULL. Teoricamente anche FoxPro si dovrebbe comportare come SQL, il fatto è che gli indici posso avere un filtro sui dati a cui devono essere applicati e l'indice che utilizziamo è di tipo candidate (non ammette valori duplicati) però è filtrato per valori non vuoti.

Cmq dire che il foxpro si comporti in modo corretto è bella grossa

Ti ringrazio, ciao!
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 08:49   #4
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Si', funziona anche per il nuovo comportamento da te descritto.

Che SQLServer (e altri) si comporti in modo errato e invece Oracle (e FoxPro e altri) invece in modo giusto e' arbitrario, nel senso che l'unica direttiva del SQL e' stata che NULL deve essere trattato come "Assenza di valore".

La domanda se su una colonna univoca possano essere presenti piu' record con "Assenza di valore" resta ambigua, e non chiaramente definita dallo stadard.

Comunque, per la cronaca, in SQL Server 2008 e' stato aggiunto il concetto di indici e constraint filtrati.
Per esempio potrei voler aggiungere un constraint di univocita' su una colonna, valente pero' solo per i valori tra 1000 e 2000.
Con questi nuovi oggetti e' quindi possibile descrivere esattamente il comportamento da te desiderato.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 09:02   #5
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
Quote:
Cmq dire che il foxpro si comporti in modo corretto è bella grossa
Scusa forse, mi sono espresso male in quanto non era una critica riferita a te ma al FoxPro, che ha molti pregi, ma ha anche tanti difetti...

Interessante questa nuova caratteristica di SQL Server 2008, purtroppo abbiamo già rimpianto il fatto di non averlo messo come requisito minimo per il nostro programma... ci faciliterebbe di molto il passaggio da Fox a SQL

Ti ringrazio ancora per la disponibilità e l'aiuto,
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 09:11   #6
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Mantis-89 Guarda i messaggi
Scusa forse, mi sono espresso male in quanto non era una critica riferita a te ma al FoxPro, che ha molti pregi, ma ha anche tanti difetti...
Avevo capito bene, non mi era neppure passata l'idea che fosse una critica rivolta "a me".
Peraltro FoxPro non lo conosco neppure tanto bene, l'ho usato solo una volta per lavoro, e non mi sbilancerei con opinioni sul motore.

PS: La migrazione da SqlServer2005 a SqlServer2008 e' abbastanza indolore. Rischia addirittura di essere trasparente, a differenza di quella dal 2000 al 2005.

Buon lavoro.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 15:16   #7
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
Premettoc he non ho ancora provato, però ci ho pensato un attimo e la cosa ha la limitazione che se inserisco dei numeri la cosa potrebbe non funzionare, o sbaglio?

Per ovviare a questo credo sia:
Codice:
 SURRUK as CASE WHEN Colonna1 IS NOT NULL THEN CAST( veraPK AS VARCHAR(30)) + Colonna1 ELSE CAST( veraPK AS VARCHAR(60)) END
giusto?
Grazie, Andrea.
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 15:22   #8
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Mantis-89 Guarda i messaggi
Premettoc he non ho ancora provato, però ci ho pensato un attimo e la cosa ha la limitazione che se inserisco dei numeri la cosa potrebbe non funzionare, o sbaglio?

Per ovviare a questo credo sia:
Codice:
 SURRUK as CASE WHEN Colonna1 IS NOT NULL THEN CAST( veraPK AS VARCHAR(30)) + Colonna1 ELSE CAST( veraPK AS VARCHAR(60)) END
giusto?
Grazie, Andrea.
Se la colonna originale e' una stringa, allora non potrai inserirci un numero nemmeno volendo.

Se invece la colonna originale e' un numero, allora bastera' che anche surruk sia un numero, senza quindi dover castare piu' nulla, e lo statement sarebbe

Codice:
SURRUK as CASE WHEN Colonna1 IS NOT NULL THEN Colonna1 ELSE ChiaveUnivoca END
Ovviamente ChiaveUnivoca deve essere un numero univoco.
Quindi o la chiave primaria e' un numero univoco, e quindi usi quella, oppure aggiungi una colonna di sola lettura
ChiaveUnivoca int IDENTITY(1,1)
e la usi per questo scopo.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 15:35   #9
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
ma se io inserisco '12' come valore di colonna1 ed è il 13 record, e il 12 record ha colonna1 a NULL il cast di veraPK non è sempre '12'? Non mi vede in questo modo un valore già inserito quando non lo è?
Se poi Colonna1 fose un numero la cosa sarebbe anche peggio no?
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 15:47   #10
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Mantis-89 Guarda i messaggi
ma se io inserisco '12' come valore di colonna1 ed è il 13 record, e il 12 record ha colonna1 a NULL il cast di veraPK non è sempre '12'? Non mi vede in questo modo un valore già inserito quando non lo è?
Se poi Colonna1 fose un numero la cosa sarebbe anche peggio no?
Si' giusto.
Propongo, se il dominio di colonna1 fosse solo tra valori positivi, puoi usare -veraPK come valore nel case.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 16:27   #11
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
Quote:
Propongo, se il dominio di colonna1 fosse solo tra valori positivi, puoi usare -veraPK come valore nel case.
Però io sono un tipo molto pessimistico... E cmq (nel mio caso) nella colonna ci deve finire un codice inserito dall'utente. Può contenere caratteri, numeri e anche alcuni simboli(anche '-' ).
E ora che ci penso quanto ho scritto poco fa non funzionerebbe nel senso che farebbe più quello che noi ci proponiamo....
Si fa interessante come problema che dici..?
Cmq forse ho capito come fare:
Quote:
SURRUK as CASE WHEN Colonna1 IS NOT NULL AND Colonna1 <> '' THEN 'X' + Colonna1 ELSE CAST( veraPK AS VARCHAR(31)) END
Se quando aggiungo una lettera fissa davanti alla mia colonna so per certo che non avrò mai un un valore che possa essere restituito dall'operazione di CAST.
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 17:18   #12
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1255
Provato e sembra funzionare perfettamente!!
Ti ringrazio!

Volevo chiederti solo un unica cosa: nel tuo esempio creavi un indice univoco, che differenza c'è tra creare un indice univoco come hai fatto tu e specificare UNIQUE quando dichiaro il campo SURRUK? (mi sembra che venga creato lo stesso, cambia solo che non sono io a decidere il nome dell'indice?)

PS: SURRUK ha qualche significato particolare?

Ancora grazie
__________________
Desktop: AMD FX-8350 @4,2Ghz + A.C. FREEZER XTREME rev.2 - ASUS M5A99X EVO - 32GB DDR3 (4x8GB) @1866Mhz - Sapphire NITRO+ RX 580 8GB - SSD Crucial MX500 1TB - Antec Two Hundred - Seasonic Focus+ Platinum 650W
Always remember to K.I.S.S.
Mantis-89 è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 17:30   #13
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Mantis-89 Guarda i messaggi
Provato e sembra funzionare perfettamente!!
Ti ringrazio!

Volevo chiederti solo un unica cosa: nel tuo esempio creavi un indice univoco, che differenza c'è tra creare un indice univoco come hai fatto tu e specificare UNIQUE quando dichiaro il campo SURRUK? (mi sembra che venga creato lo stesso, cambia solo che non sono io a decidere il nome dell'indice?)
Esatto, funzionalmente non cambia niente.
E' bene pero' avere il nome a disposizione, nel caso in cui volessero alterare o cancellare (e ci si riferisce per nome)

Quote:
PS: SURRUK ha qualche significato particolare?

Ancora grazie
Surrogate Unique Key.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Roborock Qrevo Curv 2 Flow: ora lava con un rullo Roborock Qrevo Curv 2 Flow: ora lava con un rull...
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite Alpine A290 alla prova: un'auto bella che ti fa ...
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile Recensione HONOR Magic 8 Lite: lo smartphone ind...
Sony WF-1000X M6: le cuffie in-ear di riferimento migliorano ancora Sony WF-1000X M6: le cuffie in-ear di riferiment...
Snowflake porta l'IA dove sono i dati, anche grazie a un accordo con OpenAI Snowflake porta l'IA dove sono i dati, anche gra...
L'intelligenza artificiale ha reso pi&ug...
L'intelligenza artificiale per lo svilup...
Il sistema di verifica dell'identit&agra...
Ora è ufficiale: Samsung sta per ...
Motorola Edge 70 Fusion: ecco le specifi...
8TB a meno di 170€: il richiestissimo Ha...
Il nuovo MacBook 'low cost' arriver&agra...
Pokémon Rosso Fuoco e Verde Fogli...
Risparmiare con le offerte Amazon: weeke...
Gli Xiaomi 17 arrivano a fine febbraio, ...
48.000 Pa a poco più di 100€: la ...
PC più potente, meno spesa: su Amazon to...
Con 2 acquisti si ottiene il 40% di scon...
Blocco VPN in Spagna durante le partite ...
ECOVACS DEEBOT T30C OMNI GEN2 torna a 34...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 06:42.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v