Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
REDMI Note 17 Pro porta in fascia media una batteria da 8.340 mAh con ricarica HyperCharge a 67W, un display AMOLED da 6,83 pollici capace di picchi di luminosità molto elevati e una struttura certificata TÜV SÜD contro cadute e infiltrazioni d'acqua, il tutto racchiuso in una scocca da 223 grammi. Lo abbiamo provato per diversi giorni tra fotocamera, prestazioni, autonomia e prezzo sul mercato italiano
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 20-05-2009, 13:52   #1
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
[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, 16: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 16:20.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2009, 07:43   #3
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 07: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, 08:02   #5
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 08: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, 14:16   #7
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 14: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, 14:35   #9
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 14: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, 15:27   #11
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 16:18   #12
Mantis-89
Senior Member
 
L'Avatar di Mantis-89
 
Iscritto dal: Jul 2008
Città: Solesino (PD)
Messaggi: 1256
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, 16: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


Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Microsoft Defender: falso allarme sull'a...
Aerei in volo e truppe pronte all'assalt...
Usano Claude per hackerare OpenAI: ricer...
RatHat: il nuovo malware Android usa il ...
Domanda di petrolio in calo di 2,5 milio...
Il meglio delle offerte weekend Amazon a...
Dopo oltre 100 anni di tentativi, l'IA d...
Speciale robot aspirapolvere in offerta ...
L'IA sta cancellando i lavori junior? Il...
Debutta Chery Italia: non più sol...
Addio ai dischi? Xbox ci aveva già...
Speciale TV Amazon: 4 modelli, da 139€ f...
Il nuovo iPhone 18 Pro Max ha una ricari...
Speciale smartphone Android: 7 modelli i...
La Camera USA presenta il conto: i data ...
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: 12:17.


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