将 csv 文件中的多个变量传递给 invoke-sqlcmd
Passing multiple variables from csv file to invoke-sqlcmd
我正在尝试从 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 文件中的某些行包含空值(因此可能只有前两列包含值)。这些行无法插入 table,并生成以下错误:
Invoke-Sqlcmd : The format used to define the new variable for
Invoke-Sqlcmd cmdlet is invalid. Please use the 'var=value' format for
defining a new variable.
可能为空的列是所有为空或包含单个数字 1 到 5 的列。
我尝试了各种方法来转义值、将其转换为不同的数据类型、向其添加零或空字符串、空合并它,但我无法找到有效的解决方案。
我可以控制目标 table,所以我很乐意传递零、空字符串、null 或任何其他值作为空值的占位符。
编辑 - 全新的答案
我很烂 ForEach-Object
。这是一个 foreach
循环,它检查 CSV 中每一行的 "General staisfaction" 的值,并在完成 $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
}
根据文档,您将在字符串数组中传递变量,其中每个元素都具有 "key=value" 格式。您正在正确构建它。 Invoke-SQLCMD
似乎对传递的空值不以为然。空值当然来自 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
}
因此,在每次循环中,我们使用格式运算符将列值插入到您的插入语句中。当您的属性包含特殊字符时,在 属性 名称中使用花括号很有用。因为你只需要处理 space;报价也一样。
我还想向您展示 splatting 这是一种将属性作为哈希表传递给 cmdlet 的方法。这使您可以即时编辑道具并缩短行数,而不必担心到处都是反引号。
我正在尝试从 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 文件中的某些行包含空值(因此可能只有前两列包含值)。这些行无法插入 table,并生成以下错误:
Invoke-Sqlcmd : The format used to define the new variable for Invoke-Sqlcmd cmdlet is invalid. Please use the 'var=value' format for defining a new variable.
可能为空的列是所有为空或包含单个数字 1 到 5 的列。
我尝试了各种方法来转义值、将其转换为不同的数据类型、向其添加零或空字符串、空合并它,但我无法找到有效的解决方案。
我可以控制目标 table,所以我很乐意传递零、空字符串、null 或任何其他值作为空值的占位符。
编辑 - 全新的答案
我很烂 ForEach-Object
。这是一个 foreach
循环,它检查 CSV 中每一行的 "General staisfaction" 的值,并在完成 $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
}
根据文档,您将在字符串数组中传递变量,其中每个元素都具有 "key=value" 格式。您正在正确构建它。 Invoke-SQLCMD
似乎对传递的空值不以为然。空值当然来自 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
}
因此,在每次循环中,我们使用格式运算符将列值插入到您的插入语句中。当您的属性包含特殊字符时,在 属性 名称中使用花括号很有用。因为你只需要处理 space;报价也一样。
我还想向您展示 splatting 这是一种将属性作为哈希表传递给 cmdlet 的方法。这使您可以即时编辑道具并缩短行数,而不必担心到处都是反引号。