Newsgroup: it.comp.software.database
Titolo: [MSSQL 2008] Identity un po' particolare

Buongiorno a tutti.
 
Ho questo problema con Microsoft SQL Server 2008:
 
Ho una tabella PROJECT_INVESTMENT con chiave primaria quadrupla:
-ID_SCENARIO (int)
-ID_PROJECT (int)
-ID_PROJECT_VERSION (tinyint)
-ID_PRJ_INVESTMENT (int)
e poi altri campi
-VALUE (money) etc.
Rappresenta (tanto per capirci) una serie di investimenti riguardanti un
certo progetto in un certo scenario.
Ma lo stesso progetto (ID_PROJECT) può esistere in diverse versioni
(ID_PRJ_VERSION).
(Ometto le tabelle PROJECT_VERSION, PROJECT e SCENARIO collegate)
Il campo ID_PRJ_INVESTMENT vorrei che fosse un numero UNIVOCO (quindi
basterebbe fosse dichiarato IDENTITY).
 
MA
 
Dato che devo poter "clonare" un certo progetto creandone una nuova
versione quando un utente modificasse (Insert/update/delete) un
investimento,
voglio che i campi clonati nel caso di UPDATE mantengano il medesimo
ID_PRJ_INVESTMENT.
 
Esempio chiarificatore (spero):
Poniamo di avere;
ID_SCENARIO, ID_PROJECT, ID_PROJECT_VERSION, ID_PRJ_INVESTMENT, VALUE 
1, 2, 1, 1, €1000
1, 2, 1, 2, €2000
1, 2, 1, 3, €3000
 
Se l'utente AGGIUNGE un record, il sistema creerà una nuova PRJ_VERSION e
dovrà duplicare i record di cui sopra in modo da avere, alla fine:
1, 2, 1, 1, €1000
1, 2, 1, 2, €2000
1, 2, 1, 3, €3000  --> i record esistenti, versione 1
1, 2, 2, 1, €1000
1, 2, 2, 2, €2000
1, 2, 2, 3, €3000  --> i record clonati, versione 2 ma con medesimi
ID_PRJ_INVESTMENT
1, 2, 2, 4, €4000  --> il nuovo record, versione 2 con nuovo
ID_PRJ_INVESTMENT
 
Il mio problema NON è la duplicazione, il versioning ecc. (lo faccio già
con una Stored Procedure)
 
La domanda è:
Come posso avere un campo ID_PRJ_INVESTMENT autoincrementale, NOT NULL
(poiché parte della primary key) ma inputabile manualmente (poiché deve
poter essere ripreso uguale dalle versioni precedenti)?
 
Io ho pensato a questo:
 
1) Campo int semplice, trigger INSTEAD OF INSERT con dentro le logiche di
incremento (max+1) se il campo nella tab. Inserted è null. Una sorta di
"default value avanzato".
2) Campo Identity, nessun trigger, ma nella Stored Proc. in cui creo la
nuova versione dovrei usare SET IDENTITY_INSERT. Questo però creerebbe il
problema dei permessi, poiché l'utente che esegue la proc dovrebbe avere i
permessi di ALTER TABLE sulla tabella. E non è così. 
 
Avete qualche consiglio da darmi?
 
Grazie in anticipo, e scusate per la lungaggine...
 
-- 
yankee
 
-- 
 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it
 
 
 

yankee ha scritto:
 
Trovato!! ;-)
 
Alla fine ho adottato la soluzione 1)  (Trigger INSTEAD OF INSERT)
e mi trovavo con un secondo problema:
 
Se la tabella Inserted contiene più record, come posso generare i nuovi id
Max+1, max+2, ...max+n senza usare un Cursor (pratica sconsigliata nei
triggers)?
 
Ho trovato la funzione ROW_NUMBER() OVER (ORDER BY ...) che dà un indice
1..n alle righe risultanti da una select.
Quindi Max(<campo>) + ROW_NUMBER è la soluzione a tutti i miei problemi.
 
Spero di poter essere stato utile a qualcuno ;-)
 
Grazie comunqe.
 
-- 
yankee

