I'm using a Powershell script found at ((https://blog.netnerds.net/2015/01/powershell-high-performance-techniques-for-importing-csv-to-sql-server/) to load data from quotes delimited, comma separated .csv in to a SQL Server (2016) database.
I've (for now) changed the Powershell script to use this line (KeepNulls instead of TableLock):
`$bulkcopy = New-Object Data.SqlClient.SqlBulkCopy($connectionstring,([System.Data.SqlClient.SqlBulkCopyOptions]::KeepNulls))
`
I'm making an assumption that KeepNulls will populate a column in the SQL table with a NULL value if the corresponding field in the source .csv is empty:
FirstName,Lastname
"Bruce","Foxton"
"Paul",""
"Johnny","Marr"
So the copied, row (2) in the SQL table, if KeepNulls behaves as I anticipate, should have a NULL value in the Lastname column. It doesn't, it's an empty string.
Does KeepNulls behave in a different manner than I'm expecting it to?
Also, how do I correctly configure SqlBulkCopy to use both KeepNulls and TableLock?
Jeroen Mostert has provided the crucial pointers in comments on the question; let me build on them:
CSV data is inherently untyped, and PowerShell's
Import-Csvand its in-memory counterpart,ConvertFrom-Csv, treat all column values (fields) as strings, meaning that an empty field is represented as the empty string ('').If you want to treat empty field as database
NULLs, you'll need to test the input rows' properties for equaling''and replace their value with[DBNull]::ValueYou can do this with the help of the intrinsic
psobjectproperty property PowerShell exposes on all objects is a rich source of reflection, notably via its.Propertiescollection.See next section.
PowerShell's handling
System.Enum-derived types is very flexible in that it allows simple conversion of values to and from strings.For flag-based enumerations such as
SqlBulkCopyOptions, you can simply specify the symbolic names of the flags in a single string, with the names separated by,(whitespace is ignored:The following code (PSv5+) populates a
DataTableinstance from a CSV with matching column names, and replaces all empty CSV fields with[DBNull]::Value:You should then be able to use
$dtas the data source inSqlBulkCopy.WriteToServercalls.