Newsgroup: it.comp.lang.visual-basic
Titolo: [Vb.2010 + SQL2008 Express] Chiave duplicata

Abbiate pazienza ma voglio eliminare access definitivamente.
Ho il seguente problema:
su una tabella ho diversi campi e l'ultimo è un ID chiave primaria, 
intero lungo ad incremento automatico casuale.
Voglio aggiungere nuovi record, quindi mi creo la mia bella query di 
insert (non sto usando gli adapter) e la mando in esecuzione con un 
DBComand.
         Try
             righeModificate = comandoSQL.ExecuteNonQuery()
             comandoSQL.Dispose()
             comandoSQL = Nothing
         Catch ex As Exception
         End Try
dopo varie aggiunte capita, senza una logica apparente, che mi venga 
restituito l'errore:
ex = {"Violazione del vincolo PRIMARY KEY 
'Corpo_Carico_Scarico$PrimaryKey'. Impossibile inserire la chiave 
duplicata nell'oggetto 'dbo.Corpo_Carico_Scarico'.
L'istruzione è stata interrotta."}
se però sposto manualmente il cursore e faccio rieseguire il comando con 
la stessa query, funziona e aggiunge il record!!!!
Vorrei eliminare questi problemi prima di passare definitivamente ad 
SQLSErver.

 
-- 
Paolo opg
BE AWARE that this post uses a fake reply-to address
to contact me write to:
janickg ( at ) hotmail ( dot ) com
--


ho eseguito la migrazione del db da access a sql usando il programma 
Microsoft.
Mi ha creato la tabella ma il campo ID non lo ha definito Identity ma 
semplicemente Int. Ti riporto parte dello script di generazione della 
tabella dove per il campo ID in fondo c'è una variazione:
/****** Object:  Table [dbo].[Corpo_Carico_Scarico]    Script Date: 
03/16/2011 15:22:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Corpo_Carico_Scarico](
	[CodEtichetta] [nvarchar](25) NULL,
	[Quantita] [int] NULL,
...... cut ......
	[ID] [int] NOT NULL,
	[SSMA_TimeStamp] [timestamp] NOT NULL,
  CONSTRAINT [Corpo_Carico_Scarico$PrimaryKey] PRIMARY KEY CLUSTERED
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = 
OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Corpo_Carico_Scarico]  WITH NOCHECK ADD  CONSTRAINT 
[SSMA_CC$Corpo_Carico_Scarico$CodEtichetta$disallow_zero_length] CHECK 
((len([CodEtichetta])>(0)))
GO
ALTER TABLE [dbo].[Corpo_Carico_Scarico] ADD  DEFAULT 
(CONVERT([int],CONVERT([varbinary](4000),newid(),0),0)) FOR [ID]
GO
La query di insert che faccio è assolutamente corretta dal punto di 
vista di sintassi. Ovviamente fra i campi l'id non lo passo perchè mi 
aspetto che lo calcoli in automatico il motore.
Sembra che in alcune circostanza venga calcolato un id non univoco, poi 
ripetendo la stessa istruzione viene calcolato un id corretto

 (CONVERT([int],CONVERT([varbinary](4000),newid(),0),0)) FOR [ID]
Non ho mai visto usare questa formula per creare un numero casuale.
La tua idea era quella di avere un numero casuale univoco?
Perchï¿œ secondo me INT ï¿œ meno capiente del UniqueIdentifier, per cui non 
vorrei che il convert portasse una conversione n a 1, rompendo 
l'univocitï¿œ della chiave.
Pura curiositï¿œ: perchï¿œ non usi un Identity per generare il numero 
univoco?
Ti serve proprio che siano casuali (o pseudo tali) i numeri?
Alberto


La formula che vedi non l'ho inventata io ma il convertitore della 
Microsoft (SQL Server Migration Assistant 2008 for Access).
Il fatto di avere id casuali mi serve perchè i clienti, piccoli 
artigiani che sbarcano il lunario (dicono loro...), di tanto in tanto 
fanno sparire delle righe per cui se c'è una numerazione consecutiva si 
vede chiaramente che mancano delle righe.
In access il contatore poteva essere casuale in SQL mi sembra di no.
Ok mi dite voi la logica comunque non va bene perchè anche se cancelli 
righe SQL tiene traccia nel log e sei sempre più o meno sgamabile.

Ho fatto delle prove con Id ad incremento normale e funziona, quindi mi 
sa che ï¿œ come dici tu e cioï¿œ la conversione di tanto in tanto genera dei 
valori doppi. A questo punto non ho molta scelta.
Domanda, si puoi operare una reindicizzazione sugli Id, oppure il fatto 
di averli dichiarati tali lo rende impossibile?

 righe SQL tiene traccia nel log e sei sempre pi o meno sgamabile.
Parliamoci fuori dai denti....il nero non si fà così!...solo un pirla
lo fà così! ...e per definizione un piccolo artigiano E' un pirla
grande evasore che si incazza con tutti quando lo beccano!
Quindi occhio a fare programmi con questi escamotage....che sei al
limite del penale!
le numerazioni contabili DEVONO essere progressive....quando le
stampi!
Non puoi tirare indietro una registrazione ma stornarla con un altro
movimento.
Rimane utile allora avere il controllo del progressivo....per
costruire un tool che rinumera i movimenti non ancora stampati....e
questo te la dice lunga del perchè moltissime aziende stampino i
registri proprio quando non possono più derogare!
Ti faccio notare che puoi avere due id diversi
un ID autonumber che serve solo per avere un accesso al
movimento ...lato programmatore...non lo mostri al cliente serve al
tuo programma per accedere velocemente al record
e un IDprogressivo...che invece è il numero del movimento
contabile...e deve essere continuo!
SE NON hai questa esigenza.....
non mostrare l'id...a che ti serve?...in genere l'id serve al
programmatore per costruire veloci query!...io non lo mostro mai!

ovvio, non è il mio caso. Gli id non vengono mai mostrati e servono a me 
(programmatore) per pescare il record agevolmente.