Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como criar um arquivo de banco de dados SQL 2008 incorporado se ele não existir?


Se fosse eu (quando sou eu...):

Você não quer tentar fazer com que os arquivos de banco de dados funcionem copiando-os e anexando-os - há razões pelas quais você pode querer, mas acredito que sejam exceções e não regras.

Assim, o que você precisa fazer é criar um script do banco de dados, ou seja, usar SQL DDL para criar o banco de dados e as tabelas e todas as outras coisas em seu esquema.

Praticamente tudo o que você precisa para permitir que você faça isso são direitos apropriados para a instância do servidor e, em seguida, uma string de conexão (que você provavelmente pode criar além do nome do servidor/instância).

Daqui:
  1. Existe um banco de dados? Caso contrário, crie-o.
  2. Se houver um banco de dados, é a versão correta do esquema? Se estiver muito baixo, atualize-o ou aconselhe o usuário e volte normalmente, dependendo de como você deseja que as coisas funcionem. Se estiver muito alto, volte e avise que é necessária uma versão atualizada do aplicativo
  3. Tudo está como deveria, continue.

Do ponto de vista do código:método para determinar se existe um banco de dados; método para criar um banco de dados "vazio" padrão com uma tabela de versão e um número de versão 0; métodos para trazer o esquema para a versão atual executando o DDL apropriado (codificamos o nosso em C# porque ele fornece mais flexibilidade, mas você também pode executar scripts DDL em sequência).

Isto existe:
    public virtual bool Exists()
    {
        bool exists = false;

        string masterConnectionString = this.CreateConnectionString(this.Server, this.FailoverServer, "master");

        this.DBConnection.ConnectionString = masterConnectionString;
        this.DBConnection.Open();
        try
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = this.DBConnection;
            cmd.CommandText = "SELECT COUNT(name) FROM sysdatabases WHERE name = @DBName";
            cmd.Parameters.AddWithValue("@DBName", this.DBName);

            exists = (Convert.ToInt32(cmd.ExecuteScalar()) == 1);
        }
        finally
        {
            this.DBConnection.Close();
        }

        return exists;
    }

Crie um novo banco de dados:
    public virtual void CreateNew()
    {
        string createDDL = @"CREATE DATABASE [" + this.DBName + "]";

        this.BuildMasterConnectionString();

        this.DBConnection.Open();
        try
        {
            this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
        }
        finally
        {
            this.DBConnection.Close();
        }

        createDDL = @"
                CREATE TABLE AAASchemaVersion 
                (
                    Version         int             NOT NULL,
                    DateCreated     datetime        NOT NULL,
                    Author          nvarchar(30)    NOT NULL,
                    Notes           nvarchar(MAX)   NULL 
                );

                ALTER TABLE AAASchemaVersion ADD CONSTRAINT PK_Version PRIMARY KEY CLUSTERED
                (
                    Version
                );

                INSERT INTO AAASchemaVersion
                    (Version, DateCreated, Author, Notes)
                VALUES
                    (0, GETDATE(), 'James Murphy', 'Empty Database')
            ";

        this.BuildConnectionString();
        this.ConnectionString += ";pooling=false";

        this.DBConnection.Open();
        try
        {
            this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
        }
        catch (Exception ex)
        {
            throw new Exception("Exception while creating / initialising AAASchemaVersion", ex);
        }
        finally
        {
            this.DBConnection.Close();
        }
    }

O código de atualização é um pouco mais complexo, mas basicamente executa coisas assim:
CREATE TABLE AuditUser
(    
    ID                  int IDENTITY(1,1)   NOT NULL,
    UserSourceTypeID    tinyint             NOT NULL,
    DateCreated         smalldatetime       NOT NULL,
    UserName            nvarchar(100)       NOT NULL        
);
ALTER TABLE AuditUser
ADD CONSTRAINT
    PK_AuditUser PRIMARY KEY CLUSTERED
    (
        ID
    ),
    CONSTRAINT [FK_AuditUser_UserSourceType] FOREIGN KEY
    (
        UserSourceTypeID
    ) REFERENCES UserSourceType (
        ID
    );

Tudo embrulhado em uma transação por atualização - de modo que, se a atualização falhar, você deve deixar o banco de dados em um estado bom conhecido.

Por que fazer dessa maneira (no código, que não é sem seus testes?) bem, o resultado final é um alto grau de confiança de que o esquema com o qual seu aplicativo está falando é o esquema com o qual seu aplicativo espera conversar... tabelas corretas, colunas certas (na ordem certa, que são do tipo certo e do comprimento certo), etc, etc. e que este continuará a ser o caso ao longo do tempo.

Peço desculpas se isso é um pouco longo - mas isso é algo que eu estou bastante interessado ...