none
Istruzioni di Alter table atomiche RRS feed

  • Domanda

  • Salve a tutti

    Dovrei eseguire da programma (c# VS 2008) una serie di istruzioni sql (su Sql 2005). La prima crea una tabella, le successive sono una serie di alter table che aggiungono vincoli. Vorrei però che la serie di istruzioni, vengano eseguite in modo atomico(come se fosse aperta una transazione).
    Se non sono in errore, le transazioni non hanno effetto sulle istruzioni di modifica della struttura no?
    Se è cosi, come posso ottenere l'atomicità dell'esecusiozi delle istruzioni?
    Se le concateno separandole da  ';' è una buona idea? Con il punto e virgola, vengono realmente eseguite in maniera atomica oppure semplicemente vengono eseguite in tempi "estremamanete" ravvicinati?

    Ciao e grazie

    venerdì 22 ottobre 2010 14:06

Risposte

  • Dovrei eseguire da programma (c# VS 2008) una serie di istruzioni sql (su Sql 2005). La prima crea una tabella, le successive sono una serie di alter table che aggiungono vincoli. Vorrei però che la serie di istruzioni, vengano eseguite in modo atomico(come se fosse aperta una transazione).
    Se non sono in errore, le transazioni non hanno effetto sulle istruzioni di modifica della struttura no?

    No :-)

    Osserva il seguente esempio:

    USE tempdb;
    
    BEGIN TRAN;
    
    CREATE TABLE dbo.foo(c int NOT NULL);
    
    ALTER TABLE dbo.foo
    ADD CONSTRAINT PK_foo PRIMARY KEY(c);
    
    ROLLBACK TRAN;
    
    SELECT *
    FROM dbo.foo;
    
    /* Output:
    
    Msg 208, Level 16, State 1, Line 1
    Invalid object name 'dbo.foo'.
    
    */
    

     

    Se è cosi, come posso ottenere l'atomicità dell'esecusiozi delle istruzioni?

    Puoi semplicemente definire i constraints direttamente nel comando di CREATE TABLE:

    CREATE TABLE dbo.foo(
    c int NOT NULL,
    CONSTRAINT PK_foo PRIMARY KEY(c)
    );
    
    

    Ciao! 


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.microsoft.com/Forums/it-IT/sqlserverit

    • Contrassegnato come risposta G Luca venerdì 22 ottobre 2010 15:04
    venerdì 22 ottobre 2010 14:40
    Moderatore

Tutte le risposte

  • Ciao

    la soluzione migliore è usare alcune "stored procedure" con l'utilizzo di istruzione GO alla fine del trattamento per garantire l'esecuzione o no di tutte istruzioni.


    Best regards
    venerdì 22 ottobre 2010 14:32
  • Ciao

    la soluzione migliore è usare alcune "stored procedure" con l'utilizzo di istruzione GO alla fine del trattamento per garantire l'esecuzione o no di tutte istruzioni.


    Best regards


    Ciao,

    Grazie mille per la tua risposta, purtroppo mi trovo nella situazione che la creazione della tabella dipende molto da strutture abbastanza corpose che ho in memoria(c#). Ad esempio ho classi c# che contengono la definizione delle colonne e via tutto il resto. Qundi, le istruzioni sql le devo creare da codice C#.

     

    venerdì 22 ottobre 2010 14:36
  • Dovrei eseguire da programma (c# VS 2008) una serie di istruzioni sql (su Sql 2005). La prima crea una tabella, le successive sono una serie di alter table che aggiungono vincoli. Vorrei però che la serie di istruzioni, vengano eseguite in modo atomico(come se fosse aperta una transazione).
    Se non sono in errore, le transazioni non hanno effetto sulle istruzioni di modifica della struttura no?

    No :-)

    Osserva il seguente esempio:

    USE tempdb;
    
    BEGIN TRAN;
    
    CREATE TABLE dbo.foo(c int NOT NULL);
    
    ALTER TABLE dbo.foo
    ADD CONSTRAINT PK_foo PRIMARY KEY(c);
    
    ROLLBACK TRAN;
    
    SELECT *
    FROM dbo.foo;
    
    /* Output:
    
    Msg 208, Level 16, State 1, Line 1
    Invalid object name 'dbo.foo'.
    
    */
    

     

    Se è cosi, come posso ottenere l'atomicità dell'esecusiozi delle istruzioni?

    Puoi semplicemente definire i constraints direttamente nel comando di CREATE TABLE:

    CREATE TABLE dbo.foo(
    c int NOT NULL,
    CONSTRAINT PK_foo PRIMARY KEY(c)
    );
    
    

    Ciao! 


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.microsoft.com/Forums/it-IT/sqlserverit

    • Contrassegnato come risposta G Luca venerdì 22 ottobre 2010 15:04
    venerdì 22 ottobre 2010 14:40
    Moderatore
  •  

    In questo caso, l'unica soluzione e mettere ; tra instruzioni al sorgente in C#.


    Best regards
    venerdì 22 ottobre 2010 14:43
  • In questo caso, l'unica soluzione e mettere ; tra instruzioni al sorgente in C#.

    Il ";" è utilizzato per separare i comandi SQL e non definisce alcuna transazione esplicita pertanto il fallimento nella definizione di un constraint non annullerà in alcun modo la creazione della tabella:

    USE tempdb;
    
    CREATE TABLE dbo.foo(
    c int NOT NULL,
    );
    
    /* La colonna z non esiste, quindi il comando andrà in errore */
    ALTER TABLE dbo.foo
    ADD CONSTRAINT PK_foo PRIMARY KEY(z);
    
    /* L'errore sulla creazione della PK non impedirà in alcun modo la creazione della tabella */
    SELECT *
    FROM dbo.foo;
    
    /* Output:
    
    c
    -----------
    (0 row(s) affected)
    
    */
    
    DROP TABLE dbo.foo;
    

    Ciao!


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.microsoft.com/Forums/it-IT/sqlserverit
    venerdì 22 ottobre 2010 14:49
    Moderatore
  • On 10/22/2010 4:06 PM, G Luca wrote:

    Salve a tutti

    Dovrei eseguire da programma (c# VS 2008) una serie di istruzioni sql (su Sql 2005). La prima crea una tabella, le successive sono una serie di alter table che aggiungono vincoli. Vorrei però che la serie di istruzioni, vengano eseguite in modo atomico(come se fosse aperta una transazione).
    Se non sono in errore, le transazioni non hanno effetto sulle istruzioni di modifica della struttura no?
    Se è cosi, come posso ottenere l'atomicità dell'esecusiozi delle istruzioni?
    Se le concateno separandole da  ';' è una buona idea? Con il punto e virgola, vengono realmente eseguite in maniera atomica oppure semplicemente vengono eseguite in tempi "estremamanete" ravvicinati?

    Per la tua stessa esigenza ho semplicemente creato degli statement sql rientranti, ovvero basati su check in modo da poter essere lanciati n volte.
    In questo modo anche se hai un errore, è sufficiente rilanciare tutto da capo.


    Tommaso Caldarola http://www.caldarola.net http://dotnetside.org/blogs/tcaldarola/
    venerdì 22 ottobre 2010 14:52
  • Ciao,

    Hai ragione e ti chiedo scusa, ero convinto di averlo già verificato in passato ma è evidente che mi sbagliavo.

    ho verificato di nuovo ed effettivamente, anche da codice C#, sotto transazione, qualunque istruzione di modifica della struttura, al rollback sparisce.

    Grazie mille

    venerdì 22 ottobre 2010 15:04
  • Ciao,

    Sarà una certa ignoranza :) ma.. cosa intendi per statement sql rientranti basati su check?

    Io non ho solo l'esigenza che se ottengo degli errori posso rifare tutto , ho bisogno ad esempio di evitare con assoluta certezza che "qualcuno" inserisca un record tra la creazione della tabella e l'aggiunta di un vincolo

    Ciao

    venerdì 22 ottobre 2010 15:10
  • On 10/22/2010 5:10 PM, G Luca wrote:

    Ciao,

    Sarà una certa ignoranza :) ma.. cosa intendi per statement sql rientranti basati su check?

    Ad esempio per ciascuna colonna della tua tabella uno statement sql che faccia ADD / ALTER COLUMN a seconda o meno della presenza (per la pk solo l'add), e cosi via per i constraint.


    Io non ho solo l'esigenza che se ottengo degli errori posso rifare tutto , ho bisogno ad esempio di evitare con assoluta certezza che "qualcuno" inserisca un record tra la creazione della tabella e l'aggiunta di un vincolo

    Beh questo tipo di operazioni non le puoi come dire averele nel normale flusso di lavoro... ma questa è un'altra questione. Io uso ad esempio questo modo di aggiornare i db durante l'auto aggiornamento del sistema e certe operazioni sono inibite.

    ciao


    Tommaso Caldarola http://www.caldarola.net http://dotnetside.org/blogs/tcaldarola/
    venerdì 22 ottobre 2010 15:21