我正在使用从SQL服务器收集数据的函数:
function Invoke-SQLCommand {
param(
[string] $dataSource = "myserver",
[string] $dbName = "mydatabase",
[string] $sqlCommand = $(throw "Please specify a query.")
)
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = `
"Server=$dataSource;Database=$dbName;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $sqlCommand
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]
}
效果很好,但只返回一个表。我传递了几个Select语句,因此数据集包含多个表。
我替换了
$DataSet.Tables[0]
带
for ($i=0;$i -lt $DataSet.tables.count;$i++){
$Dataset.Tables[$i]
}
但是控制台只显示第一个表的内容和每个应该是第二个表的记录的空行。查看结果的唯一方法是将代码更改为
$Dataset.Tables[$i] | out-string
但我不想要字符串,我想要使用表对象。
当我将Invoke-SQLCommand返回的内容分配给变量时,我可以看到我有一个datarow对象数组,但只有第一个表。第二张桌子怎么了?
非常感谢任何帮助。
由于
答案 0 :(得分:2)
我尝试了你的函数(返回$DataSet.Tables
),它对我来说效果很好。此命令从两个表中返回行:
$t = Invoke-sqlcommand '.\sql2005' 'AdventureWorksDW' `
"SELECT * FROM DimOrganization; SELECT * FROM DimSalesReason"
$t[0] #returns rows from first table
$t[1] #returns rows from second table
无论如何,我建议:
首先我会丢弃Fill
的输出:
$SqlAdapter.Fill($DataSet) > $null
也会返回,但这可能不太合适。
在你的情况Invoke-SqlCommand
不起作用的情况下,我会尝试像这样返回1个暗淡的数组:
function Invoke-SQLCommand {
...
,$DataSet.Tables
}
考虑PowerShell专门处理DataTable
,并在尝试格式化时,它会解开Rows
集合(信用到x0n)。这就是为什么从我的示例中执行$t
会显示从命令返回的所有行。
答案 1 :(得分:0)
感谢您的回答。
好吧,我无法解释为什么它适合你而不适合我。
如果我运行与你完全相同的命令(除了数据源,在我的情况下是mysqlserver \ sqlexpress),$ t [0]只返回第一个表的第一行,$ t [1]返回第二行
在我的案例中似乎发生的事情是所有表中的行都被合并,所以我最终得到了一大组数据行,而不是预期的单个表。
我结束了替换:
for ($i=0;$i -lt $DataSet.tables.count;$i++){
$Dataset.Tables[$i]
}
只是
$Dataset
然后我可以使用$ t.Tables [0]和$ t.Tables [1]从我的脚本中引用各个表。
再次感谢