如何在C#中执行SQL Server的DDL命令并获取执行结果?
问题解决:C#执行SQL Server DDL命令并判断执行结果
为什么ExecuteNonQuery返回-1?
SQL Server的DDL命令(如CREATE TABLE、ALTER TABLE等)不会返回受影响的行数,所以ExecuteNonQuery()方法固定返回-1,这是正常行为,不能用这个返回值判断DDL是否执行成功。
表有时创建失败的可能原因
你的脚本只检查了表是否存在,但没有确保languages架构(schema)存在。如果目标架构不存在,执行CREATE TABLE [languages].[Cultures]会直接失败,这就是表有时创建不成功的常见原因。
正确的解决方案
1. 完善SQL脚本,确保依赖项存在
修改脚本,先检查并创建架构,再检查表并创建:
-- 先确保languages架构存在 if not exists (select * from sys.schemas where [name] = 'languages') begin exec('create schema languages') end -- 再检查并创建表 if not exists (select * from sys.tables where [name] = 'Cultures' and schema_name([schema_id]) = 'languages') begin create table [languages].[Cultures] ( Id bigint not null identity(1,1) primary key clustered ) print '表[languages].[Cultures]已创建' end else begin print '表[languages].[Cultures]已存在' end
2. 在C#中判断DDL执行结果
DDL命令执行成功的标志是没有抛出异常。如果执行过程中出现错误(比如架构不存在、语法错误等),会抛出SqlException,可以通过捕获异常来判断失败;如果正常执行完成,说明操作成功。
另外,还可以通过读取SQL脚本中的PRINT输出获取执行细节:
public static void Run(string connectionString, string sql) { using (var connection = new SqlConnection(connectionString)) using (var command = new SqlCommand(sql, connection)) { // 注册事件捕获SQL的PRINT消息 connection.InfoMessage += (sender, e) => { foreach (var msg in e.Errors) { Console.WriteLine($"SQL消息: {msg.Message}"); } }; try { connection.Open(); // 执行DDL,返回-1是正常的,无需关注 command.ExecuteNonQuery(); Console.WriteLine("DDL命令执行完成,无异常"); } catch (SqlException ex) { Console.WriteLine($"DDL执行失败,错误信息: {ex.Message}"); // 可根据业务逻辑选择是否抛出异常或进行重试、日志记录等操作 throw; } } }
额外优化:获取精确执行状态
如果需要更精细化的执行状态,可以在SQL脚本中用SELECT返回自定义状态码,再通过ExecuteScalar()获取:
declare @result int = 0 if not exists (select * from sys.schemas where [name] = 'languages') begin exec('create schema languages') set @result += 1 end if not exists (select * from sys.tables where [name] = 'Cultures' and schema_name([schema_id]) = 'languages') begin create table [languages].[Cultures] ( Id bigint not null identity(1,1) primary key clustered ) set @result += 2 end select @result -- 0=架构和表都已存在,1=仅创建了架构,2=仅创建了表,3=架构和表都新建
对应的C#代码片段:
var result = (int)command.ExecuteScalar(); switch(result) { case 0: Console.WriteLine("架构和表均已存在"); break; case 1: Console.WriteLine("仅创建了languages架构"); break; case 2: Console.WriteLine("仅创建了Cultures表"); break; case 3: Console.WriteLine("架构和表均已新建"); break; }
内容的提问来源于stack exchange,提问作者Alireza Hosseinitabar
相关产品推荐
相关产品推荐

