Forked from puttyq/ps-import-multiple-dynamic-csv-files-to-sqlserver.ps1
Created
March 28, 2020 12:26
-
-
Save Kikyo-chan/c832af16576ae4ece315996861b287eb to your computer and use it in GitHub Desktop.
Dynamic CSV file importer (many CSV's) to SQL Server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cls | |
# database Details | |
$dbServer = "xxxxxxx" | |
$dbDatabaseName = "xxxxxxxx" | |
$dbTable = "xxxxxxxx" | |
# loading modules | |
Import-Module SQLPs | |
# If not loaded, load SQL assemblies | |
try {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop} | |
catch {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo"} | |
try {add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=13.0.1601.5, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop} | |
catch {add-type -AssemblyName "Microsoft.SqlServer.Smo"} | |
####################### | |
function Get-Type | |
{ | |
param($type) | |
$types = @( | |
'System.Boolean', | |
'System.Byte[]', | |
'System.Byte', | |
'System.Char', | |
'System.Datetime', | |
'System.Decimal', | |
'System.Double', | |
'System.Guid', | |
'System.Int16', | |
'System.Int32', | |
'System.Int64', | |
'System.Single', | |
'System.UInt16', | |
'System.UInt32', | |
'System.UInt64') | |
if ( $types -contains $type ) { | |
Write-Output "$type" | |
} | |
else { | |
Write-Output 'System.String' | |
} | |
} #Get-Type | |
####################### | |
function Out-DataTable | |
{ | |
[CmdletBinding()] | |
param([Parameter(Position=0, Mandatory=$true, ValueFromPipeline = $true)] [PSObject[]]$InputObject) | |
Begin | |
{ | |
$dt = new-object Data.datatable | |
$First = $true | |
} | |
Process | |
{ | |
foreach ($object in $InputObject) | |
{ | |
$DR = $DT.NewRow() | |
foreach($property in $object.PsObject.get_properties()) | |
{ | |
if ($first) | |
{ | |
$Col = new-object Data.DataColumn | |
$Col.ColumnName = $property.Name.ToString() | |
if ($property.value) | |
{ | |
if ($property.value -isnot [System.DBNull]) { | |
$Col.DataType = [System.Type]::GetType("$(Get-Type $property.TypeNameOfValue)") | |
} | |
} | |
$DT.Columns.Add($Col) | |
} | |
if ($property.Gettype().IsArray) { | |
$DR.Item($property.Name) =$property.value | ConvertTo-XML -AS String -NoTypeInformation -Depth 1 | |
} | |
else { | |
$DR.Item($property.Name) = $property.value | |
} | |
} | |
$DT.Rows.Add($DR) | |
$First = $false | |
} | |
} | |
End | |
{ | |
Write-Output @(,($dt)) | |
} | |
} #Out-DataTable | |
####################### | |
function Get-SqlType | |
{ | |
param([string]$TypeName) | |
switch ($TypeName) | |
{ | |
'Boolean' {[Data.SqlDbType]::Bit} | |
'Byte[]' {[Data.SqlDbType]::VarBinary} | |
'Byte' {[Data.SQLDbType]::VarBinary} | |
'Datetime' {[Data.SQLDbType]::DateTime} | |
'Decimal' {[Data.SqlDbType]::Decimal} | |
'Double' {[Data.SqlDbType]::Float} | |
'Guid' {[Data.SqlDbType]::UniqueIdentifier} | |
'Int16' {[Data.SQLDbType]::SmallInt} | |
'Int32' {[Data.SQLDbType]::Int} | |
'Int64' {[Data.SqlDbType]::BigInt} | |
'UInt16' {[Data.SQLDbType]::SmallInt} | |
'UInt32' {[Data.SQLDbType]::Int} | |
'UInt64' {[Data.SqlDbType]::BigInt} | |
'Single' {[Data.SqlDbType]::Decimal} | |
default {[Data.SqlDbType]::VarChar} | |
} | |
} #Get-SqlType | |
####################### | |
function Add-SqlTable | |
{ | |
[CmdletBinding()] | |
param( | |
[Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance, | |
[Parameter(Position=1, Mandatory=$true)] [string]$Database, | |
[Parameter(Position=2, Mandatory=$true)] [String]$TableName, | |
[Parameter(Position=3, Mandatory=$true)] [System.Data.DataTable]$DataTable, | |
[Parameter(Position=4, Mandatory=$false)] [string]$Username, | |
[Parameter(Position=5, Mandatory=$false)] [string]$Password, | |
[ValidateRange(0,8000)] | |
[Parameter(Position=6, Mandatory=$false)] [Int32]$MaxLength=1000, | |
[Parameter(Position=7, Mandatory=$false)] [switch]$AsScript | |
) | |
try { | |
if($Username) | |
{ $con = new-object ("Microsoft.SqlServer.Management.Common.ServerConnection") $ServerInstance,$Username,$Password } | |
else | |
{ $con = new-object ("Microsoft.SqlServer.Management.Common.ServerConnection") $ServerInstance } | |
$con.Connect() | |
$server = new-object ("Microsoft.SqlServer.Management.Smo.Server") $con | |
$db = $server.Databases[$Database] | |
$table = new-object ("Microsoft.SqlServer.Management.Smo.Table") $db, $TableName | |
foreach ($column in $DataTable.Columns) | |
{ | |
$sqlDbType = [Microsoft.SqlServer.Management.Smo.SqlDataType]"$(Get-SqlType $column.DataType.Name)" | |
if ($sqlDbType -eq 'VarBinary' -or $sqlDbType -eq 'VarChar') | |
{ | |
if ($MaxLength -gt 0) | |
{$dataType = new-object ("Microsoft.SqlServer.Management.Smo.DataType") $sqlDbType, $MaxLength} | |
else | |
{ $sqlDbType = [Microsoft.SqlServer.Management.Smo.SqlDataType]"$(Get-SqlType $column.DataType.Name)Max" | |
$dataType = new-object ("Microsoft.SqlServer.Management.Smo.DataType") $sqlDbType | |
} | |
} | |
else | |
{ $dataType = new-object ("Microsoft.SqlServer.Management.Smo.DataType") $sqlDbType } | |
$col = new-object ("Microsoft.SqlServer.Management.Smo.Column") $table, $column.ColumnName, $dataType | |
$col.Nullable = $column.AllowDBNull | |
$table.Columns.Add($col) | |
} | |
if ($AsScript) { | |
$table.Script() | |
} | |
else { | |
$table.Create() | |
} | |
} | |
catch { | |
$message = $_.Exception.GetBaseException().Message | |
Write-Error $message | |
} | |
} #Add-SqlTable | |
####################### | |
function Write-DataTable | |
{ | |
[CmdletBinding()] | |
param( | |
[Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance, | |
[Parameter(Position=1, Mandatory=$true)] [string]$Database, | |
[Parameter(Position=2, Mandatory=$true)] [string]$TableName, | |
[Parameter(Position=3, Mandatory=$true)] $Data, | |
[Parameter(Position=4, Mandatory=$false)] [string]$Username, | |
[Parameter(Position=5, Mandatory=$false)] [string]$Password, | |
[Parameter(Position=6, Mandatory=$false)] [Int32]$BatchSize=50000, | |
[Parameter(Position=7, Mandatory=$false)] [Int32]$QueryTimeout=0, | |
[Parameter(Position=8, Mandatory=$false)] [Int32]$ConnectionTimeout=15 | |
) | |
$conn=new-object System.Data.SqlClient.SQLConnection | |
if ($Username) | |
{ $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout } | |
else | |
{ $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout } | |
$conn.ConnectionString=$ConnectionString | |
try | |
{ | |
$conn.Open() | |
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString | |
$bulkCopy.DestinationTableName = "[$TableName]" | |
$bulkCopy.BatchSize = $BatchSize | |
$bulkCopy.BulkCopyTimeout = $QueryTimeOut | |
$bulkCopy.WriteToServer($Data) | |
$conn.Close() | |
} | |
catch | |
{ | |
$ex = $_.Exception | |
Write-Error "$ex.Message" | |
continue | |
} | |
} #Write-DataTable | |
####################### | |
# listing stats files | |
write-host ("Reading files in Stats folder") -ForegroundColor Green | |
$files = GCI -Path C:\Hyper-VStatistics | |
# clear stats dataset | |
$dataset = $null | |
####################### | |
# itterate through all files and get the context from each CSV file | |
foreach ($file in $files) | |
{ | |
$data = Import-csv $file.FullName | |
write-host ("Importing file: " + $file.name + " - " + $data.count + " records") -ForegroundColor Yellow | |
#write-host ("Importing records " + $data.count) -ForegroundColor Yellow | |
#$data | |
$dataset = $dataset + $data | |
} | |
####################### - SQL Population | |
write-host ("Total records: " + $dataset.count) -ForegroundColor Green | |
$dtDataSet = $dataset | Out-DataTable | |
write-host ("`nConnecting to SQL Server") -ForegroundColor Green | |
write-host ("`nDropping SQL table $dbTable if present") -ForegroundColor Green | |
$dbQuery1 = "IF OBJECT_ID('dbo.$dbTable', 'U') IS NOT NULL DROP TABLE dbo.[$dbTable]" | |
Invoke-Sqlcmd -Query $dbQuery1 -Database $dbDatabaseName -ServerInstance $dbServer | |
# Add data to database table | |
write-host ("`nAdding data to table $dbTable") -ForegroundColor Green | |
Add-SqlTable -ServerInstance $dbServer -Database $dbDatabaseName -TableName $dbTable -DataTable $dtDataSet | |
# Write table to database | |
write-host ("`nWriting data to table $dbTable") -ForegroundColor Green | |
Write-DataTable -ServerInstance $dbServer -Database $dbDatabaseName -TableName $dbTable -Data $dtDataSet | |
# validate all data in table | |
write-host ("`nCounting SQL table $dbTable rows") -ForegroundColor Green | |
$dbQuery2 = "SELECT COUNT(*) as Count from dbo.[$dbTable]" | |
$dbCount = Invoke-Sqlcmd -Query $dbQuery2 -Database $dbDatabaseName -ServerInstance $dbServer | |
If ($dbCount.Count -eq $dataset.Count) | |
{ | |
write-host ("`nSTATUS - SQL table rows matches FILE import count") -ForegroundColor Green | |
} | |
else | |
{ | |
write-host ("`nSTATUS - SQL table rows DOES NOT matches FILE import count") -ForegroundColor Red | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment