SQL Server单表全列批量替换字符的简便方法及Cursor性能问询
全表批量替换双引号及相关问题解答
1. 批量替换全表所有列双引号的简便方案
无需手动逐列编写更新语句,也无需使用游标,直接通过动态SQL拼接单次UPDATE语句即可实现,仅扫描一次全表,执行效率更高:
-- 适配SQL Server 2016及以上版本 DECLARE @sql NVARCHAR(MAX) = N'UPDATE #example SET ' + STRING_AGG( QUOTENAME(name) + N' = REPLACE(' + QUOTENAME(name) + N', ''"'','''')', N', ' ) FROM tempdb.sys.columns WHERE object_id = OBJECT_ID('tempdb..#example') -- 仅筛选字符类型列,自动跳过数值、日期等无需处理的列类型 AND system_type_id IN (35, 99, 167, 175, 231, 239) EXEC sp_executesql @sql -- 查看结果 SELECT * FROM #example
如果使用SQL Server 2016以下版本,替换STRING_AGG部分为FOR XML PATH语法拼接动态SQL即可。
2. 游标性能阈值说明
你当前使用的是遍历列的游标,性能瓶颈并非游标本身的遍历开销,而是逐列执行全表UPDATE带来的多次全表扫描开销,对应的性能阈值如下:
- 列数<10、行数<10万:几乎感知不到性能差异
- 列数>20、行数>100万:逐列全表扫描的开销会随列数线性增长,20个列就需要扫描20次全表,比单次UPDATE全列的方案慢10~20倍
- 如果是遍历行的游标,通常行数超过1万就会出现明显性能下降
3. Excel导出无双引号制表符文件方法
调整Excel导出逻辑即可直接生成无多余双引号的文件,无需后续在SQL侧处理:
- 打开目标Excel文件,按下
Alt + F11唤出VBA编辑器 - 执行以下VBA代码即可导出:
Sub 导出无引号制表符分隔文件() Dim savePath As Variant Dim fNum As Integer Dim rowNum As Long, colNum As Long Dim lineContent As String savePath = Application.GetSaveAsFilename(FileFilter:="制表符文件 (*.txt), *.txt") If savePath = False Then Exit Sub fNum = FreeFile() Open savePath For Output As #fNum For rowNum = 1 To ActiveSheet.UsedRange.Rows.Count lineContent = "" For colNum = 1 To ActiveSheet.UsedRange.Columns.Count If colNum > 1 Then lineContent = lineContent & vbTab lineContent = lineContent & ActiveSheet.Cells(rowNum, colNum).Value Next Print #fNum, lineContent Next Close #fNum MsgBox "导出完成" End Sub
补充说明:SQL Server 2017及以上版本的BULK INSERT支持FORMAT = 'CSV'参数,可自动识别字段外层包裹的双引号,支持导入字段内含逗号的CSV文件,无需提前处理双引号。
内容的提问来源于stack exchange,提问作者lnicholsonmesm
相关产品推荐
相关产品推荐

