none
Modificare la struttura delle tabelle RRS feed

  • Domanda

  • Ciao,

    oggi sto lavorando su uno schema già definito di sql server.

    Ho provato ad inserire una nuova colonna in una tabella e a cambiare il null in un' altra colonna, per poi salvare le modifiche, ma il programma mi blocca con:

    "Il salvataggio delle modifiche non è consentito. In base alle modifiche apportate p necessario eliminare e ricreare le tabelle seguenti. Sono state apportate modifiche a una tabella che non può essere ricreata oppure è stata abilitata l' opzione Impedisci il salvataggio delle modifiche per cui è necessario ricreare la tabella"

    Ho già provato a modificare l' impostazione "Impedisci il salvataggio.." ma vengo comunque bloccato.

    E' davvero impossibile modificare lo schema senza cancellare e ricreare lo schema?

     

    giovedì 16 giugno 2011 17:03

Risposte

  • Ecco lo script che mi viene generato con la modifica della struttura della tabella:

     

    /* Per evitare potenziali problemi di perdita di dati, si consiglia di esaminare dettagliatamente lo script prima di eseguirlo al di fuori del contesto di Progettazione database.*/
    BEGIN TRANSACTION
    SET QUOTED_IDENTIFIER ON
    SET ARITHABORT ON
    SET NUMERIC_ROUNDABORT OFF
    SET CONCAT_NULL_YIELDS_NULL ON
    SET ANSI_NULLS ON
    SET ANSI_PADDING ON
    SET ANSI_WARNINGS ON
    COMMIT
    BEGIN TRANSACTION
    GO
    CREATE TABLE dbo.Tmp_Contraenti
    	(
    	ID int NOT NULL,
    	Username nchar(15) NULL,
    	Nome nchar(30) NOT NULL,
    	Cognome nchar(30) NOT NULL,
    	RagioneSociale nchar(30) NULL,
    	Indirizzo nchar(50) NULL,
    	Cap nchar(5) NULL,
    	Citta nchar(30) NULL,
    	Provincia nchar(2) NULL,
    	Regione nchar(20) NULL,
    	Telefono nchar(25) NULL,
    	Cellulare nchar(25) NULL,
    	Email nchar(30) NULL,
    	CodiceFiscale nchar(16) NULL,
    	PartitaIva nchar(11) NULL,
    	Professione nchar(30) NULL,
    	Test nchar(10) NULL
    	) ON [PRIMARY]
    GO
    ALTER TABLE dbo.Tmp_Contraenti SET (LOCK_ESCALATION = TABLE)
    GO
    IF EXISTS(SELECT * FROM dbo.Contraenti)
    	 EXEC('INSERT INTO dbo.Tmp_Contraenti (ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione)
    		SELECT ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione FROM dbo.Contraenti WITH (HOLDLOCK TABLOCKX)')
    GO
    DROP TABLE dbo.Contraenti
    GO
    EXECUTE sp_rename N'dbo.Tmp_Contraenti', N'Contraenti', 'OBJECT' 
    GO
    ALTER TABLE dbo.Contraenti ADD CONSTRAINT
    	PK_Contraenti PRIMARY KEY CLUSTERED 
    	(
    	ID
    	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    
    GO
    COMMIT
    
    


    In pratica rispetto alla tabella contraenti presente adesso ho aggiunto la colonna test e cambiato un null.

     



    Ciao,

    Il codice proposto mi sembra estremamente chiaro: crea una tabella di appoggio avente la stessa struttura di quella di origine, la popola con tutti i dati, elimina la tabella di origine, la rinomina con il nome di origine ed aggiunge la PK.

    Ora, non è più semplice aggiungere direttamente la PK? :-)

    USE tempdb;
    
    CREATE TABLE dbo.Contraenti(
    ID int NOT NULL,
    Username nchar(15) NULL,
    Nome nchar(30) NOT NULL,
    Cognome nchar(30) NOT NULL,
    RagioneSociale nchar(30) NULL,
    Indirizzo nchar(50) NULL,
    Cap nchar(5) NULL,
    Citta nchar(30) NULL,
    Provincia nchar(2) NULL,
    Regione nchar(20) NULL,
    Telefono nchar(25) NULL,
    Cellulare nchar(25) NULL,
    Email nchar(30) NULL,
    CodiceFiscale nchar(16) NULL,
    PartitaIva nchar(11) NULL,
    Professione nchar(30) NULL,
    Test nchar(10) NULL
    );
    
    INSERT dbo.Contraenti(ID, Nome, Cognome)
    VALUES (1, 'Lorenzo', 'Benaglia')
       , (2, 'Andrea', 'Montanari');
    GO
       
    ALTER TABLE dbo.Contraenti
    ADD CONSTRAINT PK_Contraenti PRIMARY KEY (ID);
    GO
    
    /* Output:
    
    Command(s) completed successfully.
    
    */
    
    SELECT ID, Nome, Cognome
    FROM dbo.Contraenti;
    
    /* Output:
    
    ID     Nome              Cognome
    ----------- ------------------------------ ------------------------------
    1      Lorenzo            Benaglia           
    2      Andrea             Montanari           
    
    (2 row(s) affected)
    
    */
    
    EXEC sp_help [dbo.Contraenti];
    
    /* Output:
    ...
    
    index_name   index_description                 index_keys
    -------------- -------------------------------------------------- -----------
    PK_Contraenti clustered, unique, primary key located on PRIMARY ID
    
     
    constraint_type     constraint_name   constraint_keys
    ----------------------- ----------------... ----------------
    PRIMARY KEY (clustered) PK_Contraenti    ID
    
    */
    
    DROP TABLE dbo.Contraenti;
    

    Infine se accetti un consiglio ti invito a rivalutare attentamente il data type che hai utilizzato per le colonne stringa, dato che è in formato UNICODE (2 byte per carattere, ergo il doppio dello spazio occupato) ed è a lunghezza fissa per TUTTE le colonne!

    Per maggiori info leggi i seguenti paragrafi sui Books Online:

    Ciao!


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.technet.microsoft.com/Forums/it-IT/sqlserverit
    venerdì 17 giugno 2011 18:31
    Moderatore

Tutte le risposte

  • E' davvero impossibile modificare lo schema senza cancellare e ricreare lo schema? 


    Ciao,

    Per rispondere alla domanda bisognerebbe conoscere la struttura della tabella ed entrare nel dettaglio delle modifiche che hai cercato di apportare.

    Genera il comando di CREATE TABLE comprensivo di constraints ed il comando T-SQL relativo alle modifiche eseguite tramite designer (c'è l'apposito bottone Generate Change Script nella toolbar).

    Ciao!


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.technet.microsoft.com/Forums/it-IT/sqlserverit
    giovedì 16 giugno 2011 19:00
    Moderatore
  • Ecco lo script che mi viene generato con la modifica della struttura della tabella:

     

    /* Per evitare potenziali problemi di perdita di dati, si consiglia di esaminare dettagliatamente lo script prima di eseguirlo al di fuori del contesto di Progettazione database.*/
    BEGIN TRANSACTION
    SET QUOTED_IDENTIFIER ON
    SET ARITHABORT ON
    SET NUMERIC_ROUNDABORT OFF
    SET CONCAT_NULL_YIELDS_NULL ON
    SET ANSI_NULLS ON
    SET ANSI_PADDING ON
    SET ANSI_WARNINGS ON
    COMMIT
    BEGIN TRANSACTION
    GO
    CREATE TABLE dbo.Tmp_Contraenti
    	(
    	ID int NOT NULL,
    	Username nchar(15) NULL,
    	Nome nchar(30) NOT NULL,
    	Cognome nchar(30) NOT NULL,
    	RagioneSociale nchar(30) NULL,
    	Indirizzo nchar(50) NULL,
    	Cap nchar(5) NULL,
    	Citta nchar(30) NULL,
    	Provincia nchar(2) NULL,
    	Regione nchar(20) NULL,
    	Telefono nchar(25) NULL,
    	Cellulare nchar(25) NULL,
    	Email nchar(30) NULL,
    	CodiceFiscale nchar(16) NULL,
    	PartitaIva nchar(11) NULL,
    	Professione nchar(30) NULL,
    	Test nchar(10) NULL
    	) ON [PRIMARY]
    GO
    ALTER TABLE dbo.Tmp_Contraenti SET (LOCK_ESCALATION = TABLE)
    GO
    IF EXISTS(SELECT * FROM dbo.Contraenti)
    	 EXEC('INSERT INTO dbo.Tmp_Contraenti (ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione)
    		SELECT ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione FROM dbo.Contraenti WITH (HOLDLOCK TABLOCKX)')
    GO
    DROP TABLE dbo.Contraenti
    GO
    EXECUTE sp_rename N'dbo.Tmp_Contraenti', N'Contraenti', 'OBJECT' 
    GO
    ALTER TABLE dbo.Contraenti ADD CONSTRAINT
    	PK_Contraenti PRIMARY KEY CLUSTERED 
    	(
    	ID
    	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    
    GO
    COMMIT
    
    


    In pratica rispetto alla tabella contraenti presente adesso ho aggiunto la colonna test e cambiato un null.

     


    venerdì 17 giugno 2011 14:21
  • Ecco lo script che mi viene generato con la modifica della struttura della tabella:

     

    /* Per evitare potenziali problemi di perdita di dati, si consiglia di esaminare dettagliatamente lo script prima di eseguirlo al di fuori del contesto di Progettazione database.*/
    BEGIN TRANSACTION
    SET QUOTED_IDENTIFIER ON
    SET ARITHABORT ON
    SET NUMERIC_ROUNDABORT OFF
    SET CONCAT_NULL_YIELDS_NULL ON
    SET ANSI_NULLS ON
    SET ANSI_PADDING ON
    SET ANSI_WARNINGS ON
    COMMIT
    BEGIN TRANSACTION
    GO
    CREATE TABLE dbo.Tmp_Contraenti
    	(
    	ID int NOT NULL,
    	Username nchar(15) NULL,
    	Nome nchar(30) NOT NULL,
    	Cognome nchar(30) NOT NULL,
    	RagioneSociale nchar(30) NULL,
    	Indirizzo nchar(50) NULL,
    	Cap nchar(5) NULL,
    	Citta nchar(30) NULL,
    	Provincia nchar(2) NULL,
    	Regione nchar(20) NULL,
    	Telefono nchar(25) NULL,
    	Cellulare nchar(25) NULL,
    	Email nchar(30) NULL,
    	CodiceFiscale nchar(16) NULL,
    	PartitaIva nchar(11) NULL,
    	Professione nchar(30) NULL,
    	Test nchar(10) NULL
    	) ON [PRIMARY]
    GO
    ALTER TABLE dbo.Tmp_Contraenti SET (LOCK_ESCALATION = TABLE)
    GO
    IF EXISTS(SELECT * FROM dbo.Contraenti)
    	 EXEC('INSERT INTO dbo.Tmp_Contraenti (ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione)
    		SELECT ID, Username, Nome, Cognome, RagioneSociale, Indirizzo, Cap, Citta, Provincia, Regione, Telefono, Cellulare, Email, CodiceFiscale, PartitaIva, Professione FROM dbo.Contraenti WITH (HOLDLOCK TABLOCKX)')
    GO
    DROP TABLE dbo.Contraenti
    GO
    EXECUTE sp_rename N'dbo.Tmp_Contraenti', N'Contraenti', 'OBJECT' 
    GO
    ALTER TABLE dbo.Contraenti ADD CONSTRAINT
    	PK_Contraenti PRIMARY KEY CLUSTERED 
    	(
    	ID
    	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    
    GO
    COMMIT
    
    


    In pratica rispetto alla tabella contraenti presente adesso ho aggiunto la colonna test e cambiato un null.

     



    Ciao,

    Il codice proposto mi sembra estremamente chiaro: crea una tabella di appoggio avente la stessa struttura di quella di origine, la popola con tutti i dati, elimina la tabella di origine, la rinomina con il nome di origine ed aggiunge la PK.

    Ora, non è più semplice aggiungere direttamente la PK? :-)

    USE tempdb;
    
    CREATE TABLE dbo.Contraenti(
    ID int NOT NULL,
    Username nchar(15) NULL,
    Nome nchar(30) NOT NULL,
    Cognome nchar(30) NOT NULL,
    RagioneSociale nchar(30) NULL,
    Indirizzo nchar(50) NULL,
    Cap nchar(5) NULL,
    Citta nchar(30) NULL,
    Provincia nchar(2) NULL,
    Regione nchar(20) NULL,
    Telefono nchar(25) NULL,
    Cellulare nchar(25) NULL,
    Email nchar(30) NULL,
    CodiceFiscale nchar(16) NULL,
    PartitaIva nchar(11) NULL,
    Professione nchar(30) NULL,
    Test nchar(10) NULL
    );
    
    INSERT dbo.Contraenti(ID, Nome, Cognome)
    VALUES (1, 'Lorenzo', 'Benaglia')
       , (2, 'Andrea', 'Montanari');
    GO
       
    ALTER TABLE dbo.Contraenti
    ADD CONSTRAINT PK_Contraenti PRIMARY KEY (ID);
    GO
    
    /* Output:
    
    Command(s) completed successfully.
    
    */
    
    SELECT ID, Nome, Cognome
    FROM dbo.Contraenti;
    
    /* Output:
    
    ID     Nome              Cognome
    ----------- ------------------------------ ------------------------------
    1      Lorenzo            Benaglia           
    2      Andrea             Montanari           
    
    (2 row(s) affected)
    
    */
    
    EXEC sp_help [dbo.Contraenti];
    
    /* Output:
    ...
    
    index_name   index_description                 index_keys
    -------------- -------------------------------------------------- -----------
    PK_Contraenti clustered, unique, primary key located on PRIMARY ID
    
     
    constraint_type     constraint_name   constraint_keys
    ----------------------- ----------------... ----------------
    PRIMARY KEY (clustered) PK_Contraenti    ID
    
    */
    
    DROP TABLE dbo.Contraenti;
    

    Infine se accetti un consiglio ti invito a rivalutare attentamente il data type che hai utilizzato per le colonne stringa, dato che è in formato UNICODE (2 byte per carattere, ergo il doppio dello spazio occupato) ed è a lunghezza fissa per TUTTE le colonne!

    Per maggiori info leggi i seguenti paragrafi sui Books Online:

    Ciao!


    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.technet.microsoft.com/Forums/it-IT/sqlserverit
    venerdì 17 giugno 2011 18:31
    Moderatore
  • Il codice che ho pubblicato è quello generato da ssms dopo la modifica alla struttura della tabella tramite interfaccia grafica.

    Effettivamente in questo caso è più semplice lavorare direttamente sull' sql senza passare per l' editor grafico, andrò a ripescare qualche manuale di sql.

    Grazie per gli altri dettagli sul tipo dei dati, non ci avevo davvero pensato, lavoro da poco con sql server e tocca fare l' autodidatta.

     

     

    lunedì 20 giugno 2011 11:30