2009-11-11 6 views
0

J'ai créé une application de base de données en utilisant C#, ADO.Net et un fichier de base de données MS SQL 2008 incorporé (qui s'attache à MS SQL 2008 Express) que j'ai créé dans Server Management Studio. Quelqu'un peut-il me diriger vers une ressource qui décrit comment je peux créer par programme le fichier de base de données s'il est manquant (comme juste après l'installation de mon application)?Comment créer un fichier de base de données SQL 2008 "incorporé" s'il n'existe pas?

+0

Qu'est-ce qu'une base de données "intégrée"? Voulez-vous dire une instance d'utilisateur? – leppie

+0

Oui, c'est ce que je veux dire. – ejwipp

Répondre

2

Si elle était moi (quand il est moi ...):

Vous n'avez pas Je veux particulièrement essayer de faire fonctionner les fichiers de base de données en les copiant et en les attachant - il y a des raisons pour lesquelles vous pourriez vouloir mais je crois que ce sont des exceptions plutôt que des règles.

Par conséquent, vous devez créer une base de données de script, c'est-à-dire utiliser DDL SQL pour créer la base de données, les tables et tous les autres éléments de votre schéma. Pratiquement tout ce dont vous avez besoin pour cela est les droits appropriés sur l'instance du serveur, puis une chaîne de connexion (que vous pouvez probablement construire en dehors du nom du serveur/de l'instance).

D'ici:

  1. Y at-il une base de données? Si ce n'est pas le cas, créez le.
  2. S'il existe une base de données, est-ce la bonne version de schéma? Si elle est trop faible, mettez-la à jour ou conseillez l'utilisateur et remettez-la en place en fonction de la façon dont vous voulez que les choses fonctionnent aussi. Si elle est trop élevée, revenez en arrière et indiquez qu'une version mise à jour de l'application est requise.
  3. Tout est comme il se doit, continuez.

Du point de vue du code: méthode pour déterminer si une base de données existe; méthode pour créer une base de données "vide" standard avec une table de version et un numéro de version de 0; méthodes pour amener le schéma à la version actuelle en exécutant le DDL approprié (nous codons les nôtres en C# car il offre plus de flexibilité mais vous pouvez également exécuter des scripts DDL en séquence).

-t-il 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; 
    } 

Créer une nouvelle base de données:

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(); 
     } 
    } 

Le code de mise à jour est un peu plus complexe, mais fonctionne essentiellement des trucs comme ça:

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 
    ); 

Tous enveloppé dans une transaction par mise à jour - de sorte que si la mise à jour échoue, vous devez quitter la base de données est une bonne st connue a mangé.

Pourquoi le faire de cette façon (dans le code, ce qui n'est pas sans essais?) Le résultat final est un haut degré de confiance que le schéma auquel votre application parle est le schéma que votre application s'attend à parler. les tables de droite, les colonnes de droite (dans le bon ordre, qui sont du bon type et de la bonne longueur), etc, etc. et que cela continuera à être le cas au fil du temps. Excuses si c'est un peu long - mais c'est quelque chose que je suis tout à fait d'accord ...

+0

Juste curieux, pourquoi créez-vous la contrainte en utilisant alter au lieu de la table? – Kakira

+0

@Kakira surtout parce que c'est ce que génère SQL Server Management Studio si vous lui demandez de scripter des choses. Cela signifie également que vous avez explicitement nommé les contraintes qu'il est plus facile d'oublier si vous le faites avec le code et qui peuvent être importantes si vous devez les supprimer ou les modifier ultérieurement. Donc en partie "c'est ce qu'on m'a donné" et en partie "habitude" – Murph

0

Si le "MS SQL embarqué" est un "Microsoft SQL Server Compact 3.5":

using (SqlCeEngine sqlCeEngine = new SqlCeEngine(connectionString)) 
    sqlCeEngine.CreateDatabase(); 
+0

Je n'utilise pas le serveur compact. J'utilise 2008 Express. – ejwipp