none
Impostazioni chiave primaria e proprietà Identity RRS feed

  • Domanda

  • Buongiorno, non riesco in nessun modo a risolvere il problema che cercherò di descrivere e non trovo esempi simili nel forum.

    Ho un programma che lavora su una serie di tabelle in un database. Mancando alcune funzioni di interfaccia con il gestionale aziendale (che lavora su un altro database) ho deciso di creare delle sql per copiare i dati da un db all'altro.

    Devo effettuare un import su una tabella che ha in prima colonna ID e chiave primaria. Siccome ho bisogno che mi prenda in automatico il numero di tupla, ho impostato Identity su (1,1) nelle proprietà, ma facendo questo il programma non lavora più bene, nel senso che quando provo ad inserire valori, tramite apposita funzione, nella stessa tabella mi viene restituito l'errore "Cannot insert explicit value for Identity column in table 'nome_tabella' when IDENTITY_INSERT is set to OFF'. Questo errore mi sembra sia preso direttamente da sql e ricopiato nella finestra del programma. Non posso in nessun modo modificare il programma stesso.

    Allora sposto su NO "specifica Identity" e la funzione torna a viaggiare senza errori.

    Ora però provo ad inserire i valori in tabella via sql;

    CODICE ESEMPIO

    INSERT INTO nome_tabella(A,B,C)

    SELECT X,Y,Z

    FROM tabella_origine

    trascurando la prima colonna ID. Mi viene restituito ovviamente l'errore "Cannot insert the value NULL into column 'ID'; column does not allow nulls. INSERT fails." Come posso fare ad inserire i record con una numerazione sequenziale a seguire dall'ultimo record inserito?

    Grazie per un gentile aiuto


    giovedì 9 marzo 2017 15:06

Risposte

Tutte le risposte

  • Ciao,

    nel tuo caso, per poter utilizzare la proprietà auto-incrementale della identity devi temporaneamente disabilitare l'IDENTITY INSERT (che hai abilitato per permettere al tuo applicativo di specificare in modo esplicito il campo ID).

    SET IDENTITY_INSERT dbo.nome_tabella OFF;
    --in questo momento puoi eseguire il tuo statement,
    --ma se provi ad usare l'applicativo fallirà.   
    GO
    INSERT INTO nome_tabella(A,B,C)
    SELECT X,Y,Z
    FROM tabella_origine
    GO
    SET IDENTITY_INSERT dbo.nome_tabella ON;
    --da qui in poi potrai usare di nuovo il tuo applicativo

    Fai sapere,

    Luca


    • Modificato Luca Bruno venerdì 10 marzo 2017 08:57
    venerdì 10 marzo 2017 08:56
  • Provato ma mi restituisce il seguente errore:
    Table 'nome_tabella' does not have the identity property. Cannot perform SET operation.

    venerdì 10 marzo 2017 14:38
  • Probabilmente mi sono perso nella traduzione della versione italiana di SQL Server, mi scuso :)

    Dunque il comando che fai toglie proprio l'identity dalla tabella, forse si può evitare.

    Prova a rimettere l'IDENTITY ed esegui il comando SET IDENTITY_INSERT dbo.nome_tabella ON;

    In questa modalità puoi usare il tuo applicativo.

    Se devi far girare lo statement SQL, ricordati di disabilitare l'IDENTITY INSERT, e al termine del comando di abilitarlo di nuovo...ovvero:

    SET IDENTITY_INSERT dbo.nome_tabella OFF;
    GO
    INSERT INTO nome_tabella(A,B,C)
    SELECT X,Y,Z
    FROM tabella_origine
    GO
    SET IDENTITY_INSERT dbo.nome_tabella ON;

    Fai sapere,

    Luca

    venerdì 10 marzo 2017 15:44
  • Seleziono IDFaseProgrammata della tabella interessata che si chiama FasiProgrammate. Proprietà colonna → Specifica Identity → Identity deve essere impostata sù si affinchè la query funzioni (tralasciando le impostazioni di Incremento e  Valore di inizializzazione); deve invece essere impostata su no se voglio che la funzione del mio gestionale produzione non mi dia l'errore di cui sopra (la tabella non ha la proprietà identity).
    Se imposto su si, che io lanci il comando Set identity_insert con parametro ON oppure OFF non cambia nulla; la funzione del gestionale continua a darmi lo stesso errore.

    venerdì 10 marzo 2017 16:19
  • Giusto per capire...dopo che abiliti l'IDENTITY e metti l'INSERT a ON, che errore ti restituisce?

    Non credo possa essere ""Cannot insert explicit value for Identity column in table 'nome_tabella' when IDENTITY_INSERT is set to OFF'".

    Fai sapere,

    Luca

    venerdì 10 marzo 2017 16:22
  • Ciao Alessandro,

    puoi fare così:

    INSERT INTO nome_tabella(Id,A,B,C)
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))+
           ISNULL((SELECT MAX(Id) FROM nome_tabella),0)  AS Id
           ,X,Y,Z
    FROM tabella_origine
    

    Ciao
    Giorgio Rancati

    venerdì 10 marzo 2017 18:31
    Moderatore
  • E invece è proprio così... Nota però che l'errore me lo restituisce il mio gestionale produzione e chissà dove va a prenderlo. Rimane il fatto, al di là del messaggio in sé, che impostandolo su on il gestionale va in errore, impostandolo su off la query non va. Ora la provo la soluzione proposta sotto, poi vi dico

    • Contrassegnato come risposta BAlessandro lunedì 13 marzo 2017 08:56
    • Contrassegno come risposta annullato BAlessandro lunedì 13 marzo 2017 08:56
    lunedì 13 marzo 2017 08:54
  • Ci provo... la query che ho è moolto più complessa, vedo se riesco e poi vi faccio sapere. Grazie

    lunedì 13 marzo 2017 08:55
  • Ciao.

    Ho letto e riletto il tuo post: provo a riassumere, per vedere se ho capito bene.

    In produzione hai una tabella, sui cui è già attiva una colonna identity (che è anche chiave): questo significa che quando il gestionale fa una insert, NON specifica il valore di quella colonna perché già gestito da sql. (quindi, implicitamente, IDENTITY_INSERT è OFF).

    Quello che vuoi fare tu è importare (=aggiungere) altre righe a questa tabella, ma non puoi (giustamente) disabilitare la colonna identity altrimenti il tuo gestionale non funziona più.

    Analizzando l'errore da te segnalato, l'inserimento come da codice esempio lo stavi facendo con la tabella settata su 'specifica identity = SI' (IDENTITY_INSERT = ON): infatti NON stai fornendo il valore della colonna identity, che è anche chiave. L'errore infatti è relativo al fatto che la colonna è chiave e quindi non può essere NULL.

    La query da te scritta è corretta: io lascerei la tabella nella modalità che ti garantisce il funzionamento corretto dell'applicativo e lancerei di nuovo questa query.

    lunedì 13 marzo 2017 12:42
  • No, purtroppo non sono riuscito a farmi capire correttamente.

    Nella tabella le tuple vengono normalmente inserite dal gestionale. Essendo molto laborioso farlo manualmente (un centinaio di record al giorno) ho creato una query che lo fa automaticamente prendendo i dati da un altro gestionale.

    La tabella era impostata in origine con  'specifica identity = NO' e con questa impostazione l'inserimento da parte del gestionale funziona. Per comodità ho impostato la tabella con   'specifica identity = SI' in modo tale che con la query posso inserire i record direttamente senza specificare l'ID, se la prende in automatico. La query funziona.
    Con questa impostazione però il gestionale mi restituisce l'errore "
    Cannot insert explicit value for Identity column in table 'nome_tabella' when IDENTITY_INSERT is set to OFF"; il gestionale mi restituisce questo errore e non so dove lo prenda, quindi non mi soffermerei quello che dice che magari è fuorviante o erroneo. Fisserei solo il punto che il gestionale va in errore.

    Quello che vorrei fare quindi è di tenere l'impostazione 'specifica identity = NO' come in origine così il gestionale funziona, e modificare la query affinchè per ogni record che mi inserisce possa comunque dargli un numero di ID adatto.

    PS: devo ancora provare la soluzione proposta da Giorgio, tempi "aziendali"....

    mercoledì 15 marzo 2017 09:27