跳转到主要内容
杨月昌的软件博客
返回

C# 实战:动态创建 SQL Server 数据库与表

引言

在常规开发中,我们通常手动创建数据库。但在某些场景下(如软件首次运行初始化、多租户 SaaS 系统的隔离部署),我们需要通过代码在运行时动态创建数据库和表结构。本文将展示如何利用 ADO.NET 高效、安全地完成这一操作。


1. 核心连接字符串配置

要创建数据库,必须先连接到 SQL Server 的系统库 master

// 注意:Initial Catalog 留空或设为 master,因为此时目标数据库尚未创建
public string connString = @"Data Source=.;Initial Catalog=master;Integrated Security=SSPI;TrustServerCertificate=True;";

2. 检查数据库是否存在

在创建之前执行检查,可以避免 SQL 报错。我们通过查询系统视图 sys.databases 来实现。

public bool IsDBExist(string dbName)
{
    // 使用参数化查询防止 SQL 注入(虽然此处是数据库名,但也应养成好习惯)
    string sql = "SELECT 1 FROM master.dbo.sysdatabases WHERE name = @dbName";
    
    using (SqlConnection conn = new SqlConnection(connString))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Parameters.AddWithValue("@dbName", dbName);
        conn.Open();
        object result = cmd.ExecuteScalar();
        return result != null;
    }
}

3. 动态创建数据库

创建数据库的操作必须在 master 连接下执行。我们可以指定文件存储路径(MDF/LDF)以及初始大小。

public void CreateDataBase(string dbName, string dbPath)
{
    if (IsDBExist(dbName)) return;

    // 格式化 SQL 语句(注意:数据库名不支持参数化,需严格过滤输入内容)
    string sql = $@"
        CREATE DATABASE [{dbName}] ON PRIMARY 
        (NAME = '{dbName}', FILENAME = '{dbPath}{dbName}.mdf', SIZE = 10MB, MAXSIZE = 100MB, FILEGROWTH = 10%)
        LOG ON 
        (NAME = '{dbName}_log', FILENAME = '{dbPath}{dbName}_log.ldf', SIZE = 5MB, MAXSIZE = 50MB, FILEGROWTH = 5MB)";

    using (SqlConnection conn = new SqlConnection(connString))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

4. 检查与动态创建表

数据库创建后,我们需要切换到目标数据库执行 CREATE TABLE

4.1 检查表是否存在

public bool IsTableExist(string dbName, string tableName)
{
    string sql = $"USE [{dbName}]; SELECT 1 FROM sysobjects WHERE id = object_id('{tableName}') AND type = 'U'";
    // ... 执行逻辑同 IsDBExist ...
}

4.2 动态定义字段并建表

我们可以利用 Dictionary<string, string> 灵活定义列名和类型。

public void CreateDataTable(string dbName, string tableName, Dictionary<string, string> columns)
{
    if (!IsDBExist(dbName)) throw new Exception("目标数据库不存在!");
    if (IsTableExist(dbName, tableName)) return;

    // 构建字段 SQL 字符串
    List<string> fieldDefs = new List<string> { "ID INT IDENTITY(1,1) PRIMARY KEY" };
    foreach (var column in columns)
    {
        fieldDefs.Add($"[{column.Key}] {column.Value}");
    }

    string sql = $"USE [{dbName}]; CREATE TABLE [{tableName}] ({string.Join(",", fieldDefs)})";

    using (SqlConnection conn = new SqlConnection(connString))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

5. 进阶建议与注意事项


总结

通过 C# 与 ADO.NET 的配合,我们可以将数据库的管理逻辑封装进应用程序中。这不仅提升了软件的自动化程度,也减少了部署时的手动操作成本。



上一篇
深入理解 C# 任务调度器 TaskScheduler 的原理与使用
下一篇
SQL Server 基础操作语句大全:从入门到实战