kpr*_*bst 20 database powershell
这真让我抓狂.我有一个来自多个脚本的库,它包含以下功能:
function lib_open_dataset([string] $sql) {
$ds = new-object "System.Data.DataSet"
$da = new-object "System.Data.SqlClient.SqlDataAdapter" ($sql, $_conn_string)
$record_count = $da.Fill($ds)
return $ds
}
Run Code Online (Sandbox Code Playgroud)
这几乎被称为无处不在,它工作得很好,除了我通常必须这样做:
$ds = lib_open_dataset($some_sql)
$table = $ds.Tables[0]
foreach ($row in $table.Rows) {
# etc
}
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个新的简单包装函数,以避免解除引用第一个表的额外步骤:
function lib_open_table([string] $sql) {
$ds = lib_open_dataset $sql
return $ds.Tables[0]
}
Run Code Online (Sandbox Code Playgroud)
问题是,从这里返回的是由于某种原因而不是表本身的表的Rows集合.这会导致上面写的行循环失败并显示"无法索引到空数组".例外.经过多次试验和错误,我发现这是有效的:foreach
foreach ($row in $table) {
# etc
}
Run Code Online (Sandbox Code Playgroud)
需要注意的区别$table.Rows
,只是$table
在foreach
声明.这有效.因为$table
实际上指向Rows集合.如果声明
return $ds.Tables[0]
Run Code Online (Sandbox Code Playgroud)
假设是正确的,为什么函数返回表对象的子集合而不是表本身?
我猜测Powershell功能的工作原理显然会引起这种情况,但我无法弄清楚是什么.
Kei*_*ill 23
您可以使用逗号运算符将行集合包装在数组中,以便在展开数组时最终使用原始行集合,例如:
function lib_open_table([string] $sql) {
$ds = lib_open_dataset $sql
return ,$ds.Tables[0]
}
Run Code Online (Sandbox Code Playgroud)
实际上,您无法阻止PowerShell展开数组/集合.您可以做的最好的事情是通过将数组/集合包装在另一个单个元素数组中来解决该问题.
x0n*_*x0n 12
PowerShell特殊情况下在内部使用DataTable.它没有实现任何常见的可疑接口,如ICollection,IList或IEnumerable,它们通常会触发展开.您可以通过以下方式深入研究:
PS> $dt = new-object data.datatable
PS> $dt -is [collections.ienumerable]
False
Run Code Online (Sandbox Code Playgroud)
然而:
PS> $e = [management.automation.languageprimitives]::GetEnumerator($dt)
PS> $e.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
False False RBTreeEnumerator System.ValueType
Run Code Online (Sandbox Code Playgroud)
-Oisin
归档时间: |
|
查看次数: |
15928 次 |
最近记录: |