Powershell: implementazione di un wrapper IdataReader attorno al lettore di stream

idatareader powershell sqlbulkcopy streamreader

Domanda

Sto cercando di caricare file CSV estremamente grandi in SQL Server usando Powershell. Il codice deve anche applicarsi alle sostituzioni regex, tenere conto di diversi delimitatori, EOR e EOF. Per la manutenzione, mi piacerebbe che tutta questa logica esistesse in Powershell senza importare gli assembly.

Per essere efficiente, so che ho bisogno di usare il metodo SQLBulkCopy. Ma, tutti gli esempi di PowerShell che vedo riempiono un DataTable e lo passano, cosa che per me non è possibile a causa delle dimensioni del file.

Sono abbastanza sicuro di aver bisogno di racchiudere StreamReader in un Idatareader e poi passarlo a SQLBulkcopy. Ho trovato un paio di ottimi esempi di questo implementato in C #:
http://archive.msdn.microsoft.com/FlatFileDataReader
http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader

È possibile eseguire questa funzionalità utilizzando PowerShell nativo senza importare l'assembly C #? In particolare, ho difficoltà a convertire il wrapper astratto della classe.

Questo è il codice che ho finora che non passa un IdataReader e rompe i limiti di memoria.

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.')

Grazie mille per l'aiuto.

Risposta popolare

Se tutto ciò che si desidera è utilizzare un DataReader con SqlBulkCopy, è possibile utilizzare i driver ACE forniti con Office 2007/2010 ed è anche disponibile come download separato per aprire una connessione OLEDB al file CSV, aprire un lettore e chiamare 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
#)


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow