如何用C#的SqlCommand将SQL查询结果追加至Google Sheet?
如何将SQL查询结果批量追加到Google Sheet
看起来你已经搞定了基础的Google Sheets API授权和写入操作,现在卡在了动态收集SQL查询结果并批量追加这一步。我帮你梳理下代码里的问题,然后给出修正后的完整实现:
你的代码核心问题:
- 数据收集逻辑错误:在读取SQL数据时,你没有正确构建每行的列数据集合,反而反复创建空的
values列表,导致最终dataList没有存储有效的多行多列数据。 - API调用方式错误:你在循环里逐行调用
AppendRequest,这不仅效率极低(最多2000次API请求),而且逻辑上也不对——应该把所有数据收集好后,一次性批量追加。
修正后的完整代码
namespace CS_Gsheet1 { class Program { static string[] Scopes = { SheetsService.Scope.Spreadsheets }; static string ApplicationName = "Test3"; static void Main(string[] args) { var service = AuthorizeGoogleApp(); String spreadsheetId = "sheetIDstring"; String writeRange = "Sheet1!A1:K"; // 这里的范围可以简化为"Sheet1",API会自动找到最后一行开始追加 // 用来存储所有行的数据:每行是一个IList<object>,整个是IList<IList<object>> IList<IList<object>> allRows = new List<IList<object>>(); using(SqlConnection myConnection = new SqlConnection("connectionstring")) { myConnection.Open(); using(SqlCommand cmd = new SqlCommand("storedproc-selectsmultiplecolumnsandrows", myConnection)) { cmd.CommandType = CommandType.StoredProcedure; using(SqlDataReader reader = cmd.ExecuteReader()) { // 遍历每一行数据 while (reader.Read()) { // 创建当前行的列数据集合 IList<object> currentRow = new List<object>(); // 遍历当前行的所有列,把值添加到currentRow for(int i = 0; i < reader.FieldCount; i++) { currentRow.Add(reader.GetValue(i)); } // 将当前行添加到总的行集合中 allRows.Add(currentRow); } } } } // 构建要写入的ValueRange对象 ValueRange valueDataRange = new ValueRange() { MajorDimension = "ROWS", // 表示数据按行组织 Values = allRows // 把收集好的所有行数据赋值进去 }; Console.WriteLine("总共要追加的行数: {0}", allRows.Count); // 执行批量追加请求 SpreadsheetsResource.ValuesResource.AppendRequest appendRequest = service.Spreadsheets.Values.Append(valueDataRange, spreadsheetId, writeRange); appendRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.RAW; appendRequest.InsertDataOption = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.INSERTROWS; AppendValuesResponse appendValueResponse = appendRequest.Execute(); Console.WriteLine("追加完成,影响行数: {0}", appendValueResponse.Updates.UpdatedRows); } private static SheetsService AuthorizeGoogleApp() { UserCredential credential; using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read)) { string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json"); credential = GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, new FileDataStore(credPath, true)).Result; Console.WriteLine("Credential file saved to: " + credPath); } // 创建Google Sheets API服务实例 var service = new SheetsService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = ApplicationName, }); return service; } } }
关键修改点说明:
- 数据收集逻辑重构:用
allRows(IList<IList<object>>)存储所有行数据,每行对应一个IList<object>;读取SQL每行时,遍历所有列并将值加入当前行集合,再把当前行添加到总集合中。 - 批量API调用:收集完所有数据后仅调用一次
AppendRequest,既符合API最佳实践,又大幅提升效率。 - 简化写入范围:可以把
writeRange简化为"Sheet1",API会自动定位到Sheet1的最后空白行开始追加,无需指定精确列范围(若需限定列,保留"Sheet1!A1:K"也可)。 - 额外建议:实际使用时建议添加
try-catch块,处理SQL连接、API调用时的异常(如网络问题、权限不足等)。
这样修改后,就能轻松把SQL存储过程返回的任意行数(不超过2000行)的结果批量追加到Google Sheet里了。
内容的提问来源于stack exchange,提问作者bop-a-nator
相关产品推荐
相关产品推荐

