如何获取Snowflake Merge语句的插入/更新计数?C#库相关疑问
解决Snowflake Merge插入/更新计数问题(含C#实现)
一、Snowflake端获取Merge计数的核心方法
Snowflake内置了RESULT_SCAN函数,可以捕获最近执行语句的详细执行统计,完美适配Merge场景的插入、更新行数统计。具体操作如下:
- 先执行你的Merge逻辑;
- 紧接着执行以下查询,就能拿到拆分后的计数:
SELECT ROWS_INSERTED, ROWS_UPDATED, ROWS_DELETED -- 如果Merge包含删除逻辑的话 FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
这个查询会返回一行数据,其中ROWS_INSERTED是插入的行数,ROWS_UPDATED是更新的行数,非常直观。
二、C# snowflake-data库的实现思路
你遇到的ExecuteReaderAsync返回空结果集的问题,本质是Merge语句本身默认不会返回结果集。调整执行逻辑就能解决,给你两个实用方案:
方案1:合并Merge与统计查询为单命令
把Merge语句和RESULT_SCAN查询放在同一个命令里执行,注意要开启多语句支持:
using Snowflake.Data.Client; using System.Data; var connectionString = "你的Snowflake连接字符串"; using var conn = new SnowflakeDbConnection(); conn.ConnectionString = connectionString; conn.Open(); // 开启多语句执行支持(默认是关闭的) conn.AllowMultiStatement = true; var mergeAndStatsSql = @" MERGE INTO target_table t USING source_table s ON t.id = s.id WHEN MATCHED THEN UPDATE SET t.col = s.col WHEN NOT MATCHED THEN INSERT (id, col) VALUES (s.id, s.col); SELECT ROWS_INSERTED, ROWS_UPDATED FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())); "; using var cmd = conn.CreateCommand(); cmd.CommandText = mergeAndStatsSql; // 执行并读取统计结果 using var reader = await cmd.ExecuteReaderAsync(); if (reader.Read()) { var insertedCount = reader.GetInt64(0); var updatedCount = reader.GetInt64(1); Console.WriteLine($"插入行数:{insertedCount},更新行数:{updatedCount}"); } conn.Close();
方案2:分两次执行命令(更直观)
如果不想开启多语句支持,可以拆分步骤:先执行Merge,再单独查询统计数据:
using Snowflake.Data.Client; using System.Data; var connectionString = "你的Snowflake连接字符串"; using var conn = new SnowflakeDbConnection(); conn.ConnectionString = connectionString; conn.Open(); // 第一步:执行Merge语句 var mergeSql = @" MERGE INTO target_table t USING source_table s ON t.id = s.id WHEN MATCHED THEN UPDATE SET t.col = s.col WHEN NOT MATCHED THEN INSERT (id, col) VALUES (s.id, s.col); "; using var mergeCmd = conn.CreateCommand(); mergeCmd.CommandText = mergeSql; // ExecuteNonQueryAsync会返回Merge影响的总行数(插入+更新),但无法区分两者 await mergeCmd.ExecuteNonQueryAsync(); // 第二步:执行统计查询(必须紧跟Merge执行,否则LAST_QUERY_ID会指向其他语句) var statsSql = "SELECT ROWS_INSERTED, ROWS_UPDATED FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))"; using var statsCmd = conn.CreateCommand(); statsCmd.CommandText = statsSql; using var reader = await statsCmd.ExecuteReaderAsync(); if (reader.Read()) { var insertedCount = reader.GetInt64(0); var updatedCount = reader.GetInt64(1); Console.WriteLine($"插入行数:{insertedCount},更新行数:{updatedCount}"); } conn.Close();
注意事项
- 务必保证
LAST_QUERY_ID()是在Merge执行后立即调用,中间不要插入其他SQL语句,否则会拿到错误的统计结果; - 如果你的Merge包含
WHEN MATCHED THEN DELETE逻辑,可以在统计查询中加入ROWS_DELETED字段; - 开启多语句支持时,要注意SQL注入风险,确保所有SQL语句都是安全可信的。
内容的提问来源于stack exchange,提问作者morganics
相关产品推荐
相关产品推荐

