【问题标题】:Why doesn't powershell keep native types?为什么 powershell 不保留本机类型?
【发布时间】:2014-02-11 21:29:06
【问题描述】:

在名为 NewDB.ps1 的 powershell 脚本中考虑以下代码:

param ($i, $d)

Function New-Database 
{
    param ($instance, $name)
    $db = New-Object Microsoft.SqlServer.Management.Smo.Database ($instance, $name) 
    try { $db.Create() }
    catch [Exception] { $_.Exception | Format-list | Out-String ; exit }
    $db.CreateDate.DateTime
    $db.DatabaseOptions.RecoveryModel
    return $db
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
$sqlServer = new-Object Microsoft.SqlServer.Management.Smo.Server($i)
[Microsoft.SqlServer.Management.Smo.Database]$myDB = New-Database $sqlServer $d

我收到类型转换错误:

PS C:\Users\moomin\Documents> .\NewDB.ps1 "(local)" "testDB"
Cannot convert the "System.Object[]" value of type "System.Object[]" to type
"Microsoft.SqlServer.Management.Smo.Database".
At C:\Users\moomin\Documents\NewDB.ps1:21 char:1
+ [Microsoft.SqlServer.Management.Smo.Database]$myDB = New-Database $sqlServer $d
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

如何将对象作为Microsoft.SqlServer.Management.Smo.Database 对象从我的函数返回?我需要在函数之外用它做更多的事情。

更新 当然,感谢@mjolinor,这完全符合我现在的要求。顺便说一句,它也可以在单独的模块中与 New-Database 一起正常工作(我实际上是如何实现它的)。

param ($i, $d)

Function New-Database 
{
    param ($instance, $name)
    $db = New-Object Microsoft.SqlServer.Management.Smo.Database ($instance, $name) 
    try { $db.Create() }
    catch [Exception] { $_.Exception | Format-list | Out-String ; exit }
    $db
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
$sqlServer = new-Object Microsoft.SqlServer.Management.Smo.Server($i)
$myDB = New-Database $sqlServer $d
$myDB.CreateDate.DateTime
$myDB.DatabaseOptions.RecoveryModel

【问题讨论】:

    标签: powershell powershell-3.0 smo


    【解决方案1】:

    一个函数应该只返回一种类型的对象,它输出的任何东西都是返回的一部分,而不仅仅是 Return 关键字后面的内容,所以你的返回将是这 3 个对象的数组(这就是它说的原因你的返回类型是 Object[])

     $db.CreateDate.DateTime
     $db.DatabaseOptions.RecoveryModel
     $db
    

    如果你只想要$db,只返回$db。

    【讨论】:

    • 如果我返回了一个对象数组,我可以检查对象数组并使用 Smo.Database 对象吗?在问题的更新中添加了我的完整解决方案。
    【解决方案2】:

    return 关键字实际上仅用于语法用途。如果在 return 关键字之前调用任何对象,它们也将被返回。所以本质上你返回的是一个对象列表,这正是错误告诉你的。

    让我们以这个为例。此代码将返回一个包含 $y 值的数组,但绝不会返回 $x。

    function return-test {
        $x = 1
        $y = 2
    
        write-host $x  # Console output only
        $x | out-null  # Goes to null
        $x > $null     # Goes to null
        [void] $x      # Goes to null
    
        $y             # is returned
        return $y      # is returned, but now the return value is an array.
    }
    

    所以你需要做的是决定你想用$db.CreateDate.DateTime和$db.DatabaseOptions.RecoveryModel做什么。如果您只想在控制台上显示它们,请像这样使用write-host...

    function New-Database {
        ...
        write-host $db.CreateDate.DateTime
        write-host $db.DatabaseOptions.RecoveryModel
    
        # You can use return if you prefer to see it.
        # Either way, you want to return one value.
        #return $db
        $db
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 2015-03-18
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      相关资源
      最近更新 更多