我正在尝试使用Powershell将极大的CSV文件加载到SQL Server中。该代码还必须应用于正则表达式替换,允许各种分隔符,EOR和EOF标记。对于维护,我真的希望所有这些逻辑都存在于Powershell中,而无需导入程序集。
为了提高效率,我知道我需要使用SQLBulkCopy方法。但是,我看到的所有Powershell示例都填充了DataTable并传递了它,由于文件大小,这对我来说是不可能的。
我很确定我需要将StreamReader包装在Idatareader中,然后将其传递给SQLBulkcopy。我在C#中找到了几个很好的例子:
http://archive.msdn.microsoft.com/FlatFileDataReader
http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
是否可以使用本机PowerShell完成此功能而无需导入C#程序集?我特别难以转换抽象类包装器。
这是我到目前为止没有通过IdataReader并打破内存限制的代码。
function Get-CSVDataReader()
{
param (
[string]$path
)
$parsedData = New-Object 'System.Collections.Generic.List[string]'
#List<string[]> parsedData = new List<string[]>()
$sr = new-object IO.StreamReader($path)
while ($line = $sr.ReadLine())
{
#regex replace and other logic here
$parsedData.Add($line.Split(','))
}
,$parsedData #if this was an idatareader, the comma keeps it from exploding
}
$MyReader = Get-CSVDataReader('This should not fill immediately. It needs a Read Method.')
非常感谢帮助。
答案 0 :(得分:1)
如果您只想使用带有SqlBulkCopy的DataReader,您可以使用Office 2007/2010附带的ACE驱动程序,也可以单独下载打开OLEDB连接到CSV文件,打开阅读器和调用WriteToServer
$ServerInstance = "$env:computername\sql1"
$Database = "tempdb"
$tableName = "psdrive"
$ConnectionString = "Server={0};Database={1};Integrated Security=True;" -f $ServerInstance,$Database
$filepath = "C:\Users\Public\bin\"
get-psdrive | export-csv ./psdrive.csv -NoTypeInformation -Force
$connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=`"$filepath`";Extended Properties=`"text;HDR=yes;FMT=Delimited`";"
$qry = 'select * from [psdrive.csv]'
$conn = new-object System.Data.OleDb.OleDbConnection($connString)
$conn.open()
$cmd = new-object System.Data.OleDb.OleDbCommand($qry,$conn)
$dr = $cmd.ExecuteReader()
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString
$bulkCopy.DestinationTableName = $tableName
$bulkCopy.WriteToServer($dr)
$dr.Close()
$conn.Close()
#CREATE TABLE [dbo].[psdrive](
# [Used] [varchar](1000) NULL,
# [Free] [varchar](1000) NULL,
# [CurrentLocation] [varchar](1000) NULL,
# [Name] [varchar](1000) NULL,
# [Provider] [varchar](1000) NULL,
# [Root] [varchar](1000) NULL,
# [Description] [varchar](1000) NULL,
# [Credential] [varchar](1000) NULL,
# [DisplayRoot] [varchar](1000) NULL
#)
答案 1 :(得分:1)
我正在通过数据表导入大型CSV并在100万行后执行批量更新。
if ($dt.rows.count -eq 1000000) {
$bulkCopy.WriteToServer($dt)
$dt.Clear()
}
Here is the link where I detail my own script on my blog,但上面的代码概述了基本概念。我的PowerShell脚本花了4.x分钟从1.1 GB CSV导入900万行。该脚本依赖于SqlBulkCopy,[System.IO.File] :: OpenText和数据表。