Domanda

Ho uno script SQL che inserisce i dati (tramite istruzioni INSERT attualmente numerate a migliaia) Una delle colonne contiene un identificatore univoco (anche se non un tipo IDENTITY, solo un semplice int) che è in realtà univoco su alcune tabelle diverse.

Vorrei aggiungere una funzione scalare al mio script che ottiene il successivo ID disponibile (ad es.ultimo ID utilizzato + 1) ma non sono sicuro che sia possibile perché non sembra esserci un modo per utilizzare una variabile globale o statica dall'interno di una UDF, non posso utilizzare una tabella temporanea e posso' t aggiornare una tabella permanente dall'interno di una funzione.

Attualmente il mio script è simile a questo:

   declare @v_baseID int 
   exec dbo.getNextID @v_baseID out  --sproc to get the next available id
   --Lots of these - where n is a hardcoded value
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', @v_baseID + n ) 
   exec dbo.UpdateNextID @v_baseID + lastUsedn  --sproc to update the last used id

Ma vorrei che fosse così:

   --Lots of these
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', getNextID() ) 

L'hardcoding dell'offset è un rompicoglioni ed è soggetto a errori.Impacchettarlo in una semplice funzione scalare è molto allettante, ma comincio a pensare che non possa essere fatto in questo modo poiché non sembra esserci un modo per mantenere il contatore di offset tra le chiamate.È giusto o c'è qualcosa che mi sfugge?

Al momento utilizziamo SQL Server 2005.

modifiche per chiarimenti:

Non succederà che due utenti lo colpiscano.Si tratta di uno script di aggiornamento che verrà eseguito solo una volta e mai contemporaneamente.

L'effettivo sproc non ha il prefisso sp_, corretto il codice di esempio.

Nell'utilizzo normale, utilizziamo una tabella id e uno sproc per ottenere gli ID necessari, stavo solo cercando un modo più semplice per farlo in questo script, che essenzialmente scarica semplicemente un mucchio di dati nel db.

È stato utile?

Soluzione

Comincio a pensare che non sia possibile farlo in questo modo poiché non sembra esserci un modo per mantenere il contatore di offset tra le chiamate.È giusto o c'è qualcosa che mi sfugge?

Non ti manca nulla;SQL Server non supporta le variabili globali e non supporta la modifica dei dati all'interno delle UDF.E anche se volessi fare qualcosa di così complicato come usare CONTEXT_INFO (vedi http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), non è comunque possibile impostarlo dall'interno di una UDF.

Esiste un modo per aggirare l'"hardcoding" dell'offset rendendola una variabile e ripetendone l'iterazione, eseguendo gli inserimenti all'interno di quel ciclo?

Altri suggerimenti

Se 2 utenti lo utilizzano contemporaneamente, riceveranno lo stesso ID.Perché non hai invece utilizzato una tabella ID con un'identità, inserita in quella e utilizzata come ID univoco (che è garantito), anche questo funzionerà molto più velocemente

sp_getNextID

non prefissare mai procs con sp_, questo ha implicazioni sulle prestazioni perché l'ottimizzatore controlla prima il DB principale per vedere se quel proc esiste lì e poi il DB locale, anche se MS decide di creare uno sp_getNextID in un service pack il tuo non verrà mai eseguito

Probabilmente sarebbe più lavoro di quanto valga, ma puoi utilizzare variabili C#/VB statiche in una UDF SQL CLR, quindi penso che potresti fare quello che vuoi semplicemente incrementando questa variabile ogni volta che l'UDF è chiamato.Naturalmente, la variabile statica andrebbe persa ogni volta che il dominio app viene scaricato.Quindi, se hai bisogno di continuità del tuo ID da un giorno all'altro, avresti bisogno di un modo, al primo accesso di NextId, per interrogare tutte le tabelle che utilizzano questo ID, per trovare il valore più alto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top