You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PowerShell向SQL Server插入日期及导入CSV数据至数据库问询

嘿,我看你现在用PowerShell逐行插入CSV数据到SQL Server,先不说性能问题,这种直接拼接SQL语句的方式非常容易触发SQL注入,而且大批量数据的话速度会慢到离谱。给你几个更靠谱的方案:

1. 使用SqlBulkCopy(最推荐,性能拉满)

这是批量插入的神器,直接把CSV数据转成DataTable后一次性批量写入,比逐行插入快N倍,还能避免SQL注入风险。代码示例如下:

# 加载必要的.NET程序集
Add-Type -AssemblyName System.Data.SqlClient
Add-Type -AssemblyName System.Data

# 读取CSV文件到DataTable
$csvPath = "你的CSV文件路径.csv"
$dt = New-Object System.Data.DataTable
$reader = New-Object System.IO.StreamReader($csvPath)

# 处理表头
$headers = $reader.ReadLine().Split(',') | ForEach-Object { $_.Trim() }
foreach ($header in $headers) {
    $dt.Columns.Add($header) | Out-Null
}

# 处理每行数据
while (($line = $reader.ReadLine()) -ne $null) {
    $row = $dt.NewRow()
    $values = $line.Split(',')
    for ($i=0; $i -lt $headers.Count; $i++) {
        $row[$headers[$i]] = $values[$i].Trim()
    }
    $dt.Rows.Add($row)
}
$reader.Close()

# 批量写入SQL Server
$connectionString = "Server=你的服务器名;Database=你的数据库名;Integrated Security=True;"
$bulkCopy = New-Object System.Data.SqlClient.SqlBulkCopy($connectionString)
$bulkCopy.DestinationTableName = "Offerings"

# 如果CSV列名和数据库列名不完全匹配,需要手动映射列(列名一致的话可以跳过这步)
# foreach ($col in $dt.Columns) {
#     $bulkCopy.ColumnMappings.Add($col.ColumnName, $col.ColumnName) | Out-Null
# }

$bulkCopy.WriteToServer($dt)
$bulkCopy.Close()

2. 使用参数化查询(如果必须逐行插入的话)

要是因为某些限制不能用批量插入,那绝对要改用参数化查询,绝对不能直接拼接SQL字符串。示例代码:

Add-Type -AssemblyName System.Data.SqlClient

$connectionString = "Server=你的服务器名;Database=你的数据库名;Integrated Security=True;"
$csvPath = "你的CSV文件路径.csv"
$data = Import-Csv -Path $csvPath

# 建立数据库连接
$conn = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$conn.Open()

# 定义带参数的SQL语句
$sql = @"
INSERT INTO Offerings (RATING, PARVALUE, DESCRIPTION, COUPON, MATURITY, DATEDDATE, CALLDATE, FIRSTCOUPON, CUSIP, PRICEYIELD, COM)
VALUES (@Rating, @ParValue, @Description, @Coupon, @Maturity, @DatedDate, @CallDate, @FirstCoupon, @Cusip, @PriceYield, @Com)
"@

$cmd = New-Object System.Data.SqlClient.SqlCommand($sql, $conn)
# 提前定义参数(根据数据库字段类型调整SqlDbType)
$cmd.Parameters.Add("@Rating", [System.Data.SqlDbType]VarChar, 50)
$cmd.Parameters.Add("@ParValue", [System.Data.SqlDbType]Decimal)
$cmd.Parameters.Add("@Description", [System.Data.SqlDbType]VarChar, 255)
$cmd.Parameters.Add("@Coupon", [System.Data.SqlDbType]Decimal)
$cmd.Parameters.Add("@Maturity", [System.Data.SqlDbType]Date)
$cmd.Parameters.Add("@DatedDate", [System.Data.SqlDbType]Date)
$cmd.Parameters.Add("@CallDate", [System.Data.SqlDbType]Date)
$cmd.Parameters.Add("@FirstCoupon", [System.Data.SqlDbType]Date)
$cmd.Parameters.Add("@Cusip", [System.Data.SqlDbType]VarChar, 20)
$cmd.Parameters.Add("@PriceYield", [System.Data.SqlDbType]Decimal)
$cmd.Parameters.Add("@Com", [System.Data.SqlDbType]VarChar, 50)

# 逐行赋值并执行
foreach ($row in $data) {
    $cmd.Parameters["@Rating"].Value = $row.rating.Trim()
    $cmd.Parameters["@ParValue"].Value = $row."PAR VALUE".Trim()
    $cmd.Parameters["@Description"].Value = $row.DESCRIPTION.Trim()
    $cmd.Parameters["@Coupon"].Value = $row.COUPON.Trim()
    $cmd.Parameters["@Maturity"].Value = $row.MATURITY.Trim()
    $cmd.Parameters["@DatedDate"].Value = $row.DATEDDATE.Trim()
    $cmd.Parameters["@CallDate"].Value = $row.CALLDATE.Trim()
    $cmd.Parameters["@FirstCoupon"].Value = $row.FIRSTCOUPON.Trim()
    $cmd.Parameters["@Cusip"].Value = $row.CUSIP.Trim()
    $cmd.Parameters["@PriceYield"].Value = $row.PRICEYIELD.Trim()
    $cmd.Parameters["@Com"].Value = $row.COM.Trim()

    $cmd.ExecuteNonQuery() | Out-Null
}

$conn.Close()

额外小提示

  • 注意CSV里的日期格式要和SQL Server兼容,必要时可以用[DateTime]::ParseExact()手动转换格式
  • 如果CSV字段里包含逗号(比如描述字段),Import-Csv可能解析出错,建议用第一种DataTable+StreamReader的方式处理,或者指定正确的分隔符
  • 批量插入前可以临时禁用表上的非聚集索引,插入完成后再重建,能进一步提升写入速度

内容的提问来源于stack exchange,提问作者ertuu85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:20:59