忽略带有PowerShell的SQL查询的循环的空结果
我有一张这样的桌子:忽略带有PowerShell的SQL查询的循环的空结果,powershell,csv,Powershell,Csv,我有一张这样的桌子: avis,client,image_client,client_do 123,carrefour,,23 45,leclerc,,12 56,auchan,,69 89,casino,,96 如您所见,列image\u client为空。我已经在这个csv文件中添加了这个列 我的SQL datatable就是这种数据 client_do | image_client 12 12.png 90
avis,client,image_client,client_do
123,carrefour,,23
45,leclerc,,12
56,auchan,,69
89,casino,,96
如您所见,列image\u client
为空。我已经在这个csv文件中添加了这个列
我的SQL datatable就是这种数据
client_do | image_client
12 12.png
90 90.png
96 96.png
我想将所有SQL数据image\u client
添加到csv列image\u client
中,其中的行具有相同的client\u do
目前,我有以下代码:
$Csv = Import-Csv "$treatmentfolder\4_1_traitement.csv"
$i=0
function GenericSqlQuery ($Server, $Database, $SQLQuery) {
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $SQLQuery
$Reader = $Command.ExecuteReader()
while ($Reader.Read()) {
$Reader.GetValue(0)
}
$Connection.Close()
}
ForEach ($Row in $Csv) {
$query= $query = "IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = {0}) BEGIN SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = {0} END" -f $Row.client_do
$imagefile=GenericSqlQuery($sqlserver,$DB,$query)
$i += 1
}
问题是忽略查询的空结果,我有一个错误,即没有为行$Reader=$Command.ExecuteReader()
初始化CommandText,并且在($Reader.Read())期间,无法为行调用空表达式
编辑:BaconBits更正的代码我看到了几个问题
首先,您的SQL查询有一个END
,但没有BEGIN
。如果需要如果存在
,则应为:
IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do) BEGIN SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do END
或者,如果只执行一条语句,则可以完全省略BEGIN…END
块:
IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do) SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do
但是,严格来说,如果存在,则根本不需要。您只是让查询引擎做更多的工作,唯一的区别是您根本不会得到结果集,而不是空的结果集,就SqlDataReader而言,空的结果集没有太大的不同。你可能应该打电话:
SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do
如果结果集为空,则在脚本中处理它。但是,我不确定它是否需要任何编码更改
接下来,您不能像现在这样调用嵌入变量的属性。如果$Row.client\u do
为12,则“$Row.client\u do”
将返回类似于[DataRow].client\u do的内容。PowerShell解析器无法将嵌入的句点识别为点运算符。您需要使用子表达式,如“$($Row.client\u-do)”
。因此,您的查询应该是:
$query = "IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $($Row.client_do)) BEGIN SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $($Row.client_do) END"
或:
第三,在您的功能中,这一行没有意义:
$Reader.GetValue($1)
$1
是一个没有值的变量。您实际上是在调用$Reader.GetValue($null)
,这意味着系统实际上是在调用$Reader.GetValue(([int]$null))
。它之所以有效,是因为[int]$null
是0
,但这似乎完全是偶然的。应该是:
$Reader.GetValue(0)
最后,这里的整个方法使用字符串连接来构建查询字符串。这意味着您容易受到SQL注入的攻击。如果这是一个一次性脚本就可以了,但是如果您要重复使用这个脚本,那么我强烈建议您使用参数化查询
编辑:事实上,我注意到了一些其他的东西。您的循环没有意义,并且您错误地调用了函数
ForEach ($Row in $Csv) {
$query = ...
$imagefile = GenericSqlQuery($sqlserver,$DB,$query)
$i += 1
}
您在每次迭代中都会覆盖$imagefile
。然后什么也不做
另外,GenericSqlQuery($sqlserver,$DB,$query)
的工作方式与您想象的不一样。如前所述,这是调用GenericSqlQuery-Server($sqlserver,$DB,$query)-Database$null
-SQLQuery$null
。这是一个最大的PowerShell陷阱。它必须是GenericSqlQuery$sqlserver$DB$query
或GenericSqlQuery-Server$sqlserver-Database$DB-SQLQuery$query
您的循环和脚本结尾类似于:
ForEach ($Row in $Csv) {
$query = ...
$imagefile = GenericSqlQuery -Server $sqlserver -Database $DB -SQLQuery $query
$row.image_client = $imagefile -join ','
$i += 1
}
$Csv | Export-Csv -Path "exportfilename.csv" -NoTypeInformation
我看到了几个问题
首先,您的SQL查询有一个END
,但没有BEGIN
。如果需要如果存在
,则应为:
IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do) BEGIN SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do END
或者,如果只执行一条语句,则可以完全省略BEGIN…END
块:
IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do) SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do
但是,严格来说,如果存在,则根本不需要。您只是让查询引擎做更多的工作,唯一的区别是您根本不会得到结果集,而不是空的结果集,就SqlDataReader而言,空的结果集没有太大的不同。你可能应该打电话:
SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $Row.client_do
如果结果集为空,则在脚本中处理它。但是,我不确定它是否需要任何编码更改
接下来,您不能像现在这样调用嵌入变量的属性。如果$Row.client\u do
为12,则“$Row.client\u do”
将返回类似于[DataRow].client\u do的内容。PowerShell解析器无法将嵌入的句点识别为点运算符。您需要使用子表达式,如“$($Row.client\u-do)”
。因此,您的查询应该是:
$query = "IF EXISTS (SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $($Row.client_do)) BEGIN SELECT [image_client] FROM [dbo].[clients] WHERE [client_do] = $($Row.client_do) END"
或:
第三,在您的功能中,这一行没有意义:
$Reader.GetValue($1)
$1
是一个没有值的变量。您实际上是在调用$Reader.GetValue($null)
,这意味着系统实际上是在调用$Reader.GetValue(([int]$null))
。它之所以有效,是因为[int]$null
是0
,但这似乎完全是偶然的。应该是:
$Reader.GetValue(0)
最后,这里的整个方法使用字符串连接来构建查询字符串。这意味着您容易受到SQL注入的攻击。如果这是一个一次性脚本就可以了,但是如果您要重复使用这个脚本,那么我强烈建议您使用参数化查询
编辑:事实上,我注意到了一些其他的东西。您的循环没有意义,并且您错误地调用了函数
ForEach ($Row in $Csv) {
$query = ...
$imagefile = GenericSqlQuery($sqlserver,$DB,$query)
$i += 1
}
您在每次迭代中都会覆盖$imagefile
。然后什么也不做
另外,GenericSqlQuery($sqlserver,$DB,$query)
的工作方式与您想象的不一样。如前所述,这是调用GenericSqlQuery-Server($sqlserver,$DB,$query)-Database$null
-SQLQuery$null
。这是一个最大的PowerShell陷阱。它必须是GenericSqlQuery$sqlserver$DB$query
或GenericSqlQuery-Server$sqlserver-Database$DB-SQLQuery$query
您的循环和脚本结尾类似于:
ForEach ($Row in $Csv) {
$query = ...
$imagefile = GenericSqlQuery -Server $sqlserver -Database $DB -SQLQuery $query
$row.image_client = $imagefile -join ','
$i += 1
}
$Csv | Export-Csv -Path "exportfilename.csv" -NoTypeInformation
只需指出:在GetV之后,您的代码示例中似乎有一个额外的花括号