我尝试从CSV文件读取值,将它们嵌入INSERT T-SQL语句并使用Invoke-Sqlcmd运行该语句。
这是我的代码:
Push-Location; Import-Module SQLPS -DisableNameChecking; Pop-Location
$InsertQry = "insert into $ImportTable VALUES ('`$(Col1)','`$(Col2)','`$(Col3)','`$(Col4)') "
Import-CSV $ImportFile | ForEach-Object { `
$RowData = "Col1=$($_.{My Ref})","Col2=$($_.{General satisfaction})","Col3=$($_.Helpfulness)","Col4=$($_.Effort)"
Invoke-Sqlcmd `
-Database $DBName -ServerInstance $SQLServer `
-Query $InsertQry `
-Variable $RowData
}
该脚本适用于CSV文件中包含每列值的行。不幸的是,CSV文件中的某些行包含空值(因此可能只有前两列包含值)。这些行无法插入表中,并生成以下错误:
Invoke-Sqlcmd:用于定义新变量的格式 Invoke-Sqlcmd cmdlet无效。请使用' var = value'格式 定义一个新变量。
可能为空的列都是空的列或包含1到5的单个数字。
我已经尝试了各种方法来转义值,将其转换为不同的数据类型,向其添加零或空字符串,null将其合并,但我无法获得有效的解决方案。
我可以控制目标表,所以我很乐意传递零,空字符串,null或任何其他值作为空值的占位符。
答案 0 :(得分:2)
编辑 - 全新答案
我在ForEach-Object
吮吸。这是一个foreach
循环,用于检查CSV中每行的“常规满意度”值,并在完成$RowData
变量之前将其替换为占位符字符串。不幸的是我不能在这里测试它;请告诉我你是怎么过的。
Push-Location; Import-Module SQLPS -DisableNameChecking; Pop-Location
$InsertQry = "insert into $ImportTable VALUES ('`$(Col1)','`$(Col2)','`$(Col3)','`$(Col4)') "
$myCSVFile = Import-CSV $ImportFile
foreach($line in $myCSVFile){
if($line."General staisfaction" -eq $null -or $line."General staisfaction" -eq ""){
$line."General staisfaction" = "placeholder"
}
$RowData = "Col1=$($line.{My Ref})","Col2=$($line.{General satisfaction})","Col3=$($line.Helpfulness)","Col4=$($line.Effort)"
Invoke-Sqlcmd -Database $DBName -ServerInstance $SQLServer -Query $InsertQry -Variable $RowData
}
答案 1 :(得分:2)
根据文档,您要在字符串数组中传递变量,其中每个元素都具有“key = value”格式。你正在构建正确的。 Invoke-SQLCMD
似乎对传递的null值有所冒犯。当然,空值来自CSV中的空白条目。假设您在这些列中允许空值,那么您可以在每个循环传递时调整查询。
Push-Location; Import-Module SQLPS -DisableNameChecking; Pop-Location
$InsertQry = "insert into $ImportTable VALUES ('{0}','{1}','{2}','{3}')"
$propertiesToSplat = @{
Database = $DBName
ServerInstance = $SQLServer
}
Import-CSV $ImportFile | ForEach-Object {
$propertiesToSplat.Query = $InsertQry -f $_."My Ref", $_."General satisfaction", $_.Helpfulness, $_.Effort
Invoke-Sqlcmd @propertiesToSplat
}
因此,在每个循环传递中,我们使用format运算符将列值插入到insert语句中。当属性包含特殊字符时,在属性名称中使用花括号非常有用。因为你只需处理一个空间;报价同样有效。
我还想向您展示splatting这是一种将属性作为哈希表传递给cmdlet的方法。这使您可以动态编辑道具并保持线条更短,而无需担心任何地方的反推。