我正在尝试编写一个PowerShell脚本来查询MySQL数据库,存储结果,然后为每一行执行命令。在这种情况下,它最终将通过电子邮件发送报告,但在我到达之前就出现了这个问题。
该表似乎存储正常,并且一个非常简单的ForEach-Object循环返回我期望的内容,但是当我尝试使循环更复杂时,第一行是空的。虽然我可以在这种特殊情况下解决这个问题,但我正在努力理解为什么会发生这种情况并且做得很短。
以下是构建查询的函数(取自https://vwiki.co.uk/MySQL_and_PowerShell):
function Execute-MySQLQuery([string]$query) {
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $conn) # Create SQL command
$dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($cmd) # Create data adapter from query command
$dataSet = New-Object System.Data.DataSet # Create dataset
$dataAdapter.Fill($dataSet, "data") # Fill dataset from data adapter, with name "data"
$cmd.Dispose()
return $dataSet.Tables["data"] # Returns an array of results
}
这里称为:
# Connect to MySQL Database
$conn = Connect-MySQL $user $pass $MySQLHost $database $certfile $certpass
$query = "SELECT * FROM reports;"
$result = Execute-MySQLQuery $query
$result | Format-Table
并准确地返回:
PS C:\Users\redacted> C:\Users\redacted\Desktop\tmp\testsql.ps1
5
rep_id email_add1 user sent_success
------ ---------- ---- ------------
1 Jimbo@example.com Jim Johnson 1
2 John@example.com John Doe 1
3 Stacy@example.com Stacy Something 0
4 bgates@microsoft.com Willy Gates 1
5 pallen@microsoft.com Paul Allen 0
但是,当我尝试在ForEach-Object循环中只使用一列时,我得到一个空行。出于测试目的,我尝试了一个非常基本的方法:
$result | ForEach-Object {$_.user}
返回了预期的内容:
PS C:\Users\redacted> C:\Users\redacted\Desktop\tmp\testsql.ps1
Jim Johnson
John Doe
Stacy Something
Willy Gates
Paul Allen
但是一旦我变得比这更复杂:
$result | ForEach-Object {"Howdy $($_.user)!"}
我明白了:
PS C:\Users\redacted> C:\Users\redacted\Desktop\tmp\testsql.ps1
Howdy !
Howdy Jim Johnson!
Howdy John Doe!
Howdy Stacy Something!
Howdy Willy Gates!
Howdy Paul Allen!
我错过了一些明显的东西吗?我(显然)还在学习,但我发现这个问题比其他人更困难。也许我只是使用错误的条款,但我真的很感激能指出我正确方向的人。谢谢你。
答案 0 :(得分:1)
脚本块(如函数体)中生成的每个值都将成为函数结果的一部分,除非存储在变量中或显式丢弃。
此函数有三个输出值(试一试):
function foo {
1
2
3
}
foo | foreach { "I received $_" }
请注意,不需要使用return
。所有返回都是终止功能。另请注意,foreach
正文没有return
语句,但仍会生成三个值。
许多功能输出您并不真正关心的值。无论如何,必须在Powershell中处理这些值。如果您想从功能的输出中删除它们,请将它们存储或管道输入Out-Null
:
function Execute-MySQLQuery {
param(
[MySql.Data.MySqlClient.MySqlConnection]$connection,
[string]$query
)
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $conn)
$dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($cmd)
$dataSet = New-Object System.Data.DataSet
$dataAdapter.Fill($dataSet, "data") | Out-Null
$cmd.Dispose()
$dataSet.Tables["data"]
}
$conn = Connect-MySQL $user $pass $MySQLHost $database $certfile $certpass
$result = Execute-MySQLQuery -connection $conn -query "SELECT * FROM reports;"
$result | Format-Table
函数中最后一行产生的值不会存储在任何地方,也不会被丢弃。因此它成为函数返回的一部分。