797 字
4 分钟
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. 进阶建议与注意事项
- 权限问题:执行
CREATE DATABASE需要账号拥有sysadmin或dbcreator角色权限。 - 路径权限:代码指定的
dbPath所在的文件夹,必须授予 SQL Server 服务账号(通常是NT Service\MSSQLSERVER)读写权限。 - 连接池管理:使用
using块是处理SqlConnection的最佳实践,它能确保即使发生异常,连接也能被及时关闭。 - SQL 注入防御:由于 DDL 语句(如 CREATE)不支持参数化对象名(表名/库名),请务必在传入参数前使用正则表达式检查输入的合法性。
总结
通过 C# 与 ADO.NET 的配合,我们可以将数据库的管理逻辑封装进应用程序中。这不仅提升了软件的自动化程度,也减少了部署时的手动操作成本。
C# 实战:动态创建 SQL Server 数据库与表
https://sw.rscclub.website/posts/sqlserverdtcjkhb/