Coo*_*ter 10 sql powershell dbnull
花费更多时间在PowerShell中提取SQL数据.遇到[System.DBNull] :: Value以及PowerShell在比较期间如何处理这些问题.
以下是我看到的行为示例以及变通方法
#DBNull values don't evaluate like Null...
if([System.DBNull]::Value){"I would not expect this to display"}
# The text displays.
if([string][System.DBNull]::Value){"This won't display, but is not intuitive"}
# The text does not display.
#DBNull does not let you use certain comparison operators
10 -gt [System.DBNull]::Value
# Could not compare "10" to "". Error: "Cannot convert value "" to type "System.Int32". Error: "Object cannot be cast from DBNull to other types.""
[System.DBNull]::Value -gt 10
# Cannot compare "" because it is not IComparable.
#No real workaround. Must use test for null workaround in conjunction to avoid comparison altogether:
[string][System.DBNull]::Value -and [System.DBNull]::Value -gt 10
#Example scenario with a function that uses Invoke-Sqlcmd2 to pull data
Get-XXXXServer | Where-Object{$_.VCNumCPUs -gt 8}
#Error for every line where VCNumCPU has DBNull value
#workaround
Get-XXXXServer | Where-Object{[string]$_.VCNumCPUs -and $_.VCNumCPUs -gt 8}
Run Code Online (Sandbox Code Playgroud)
我是否遗漏了任何内容,或者没有"简单"的解决方法可以让那些经验不足的人按预期使用PowerShell比较?
我提交了一个关于Connect的建议,并有一个Dave Wyatt的临时解决方法,它将数据行转换为psobjects,并将dbnulls转换为null,但这会增加一些开销.考虑到PowerShell现有的"松散"行为,似乎应该在封面下处理一些事情?
任何提示,或者我现在已经用尽了我的选择?
谢谢!
Ans*_*ers 18
我想你在这里采取了错误的做法.如文档所述,DBNull该类表示不存在的值,因此比较喜欢-gt或-lt没有任何意义.不存在的值既不大于也不小于任何给定值.但是,该Value字段有一个Equals()方法,允许您检查值是否为DBNull:
PS C:> ([DBNull]::Value).Equals(23)
False
PS C:> ([DBNull]::Value).Equals([DBNull]::Value)
TrueRun Code Online (Sandbox Code Playgroud)
我通常最终做的是这样的:
[String]::IsNullOrWhiteSpace($Val.ToString())
Run Code Online (Sandbox Code Playgroud)
或这个:
[String]::IsNullOrEmpty($Val.ToString())
Run Code Online (Sandbox Code Playgroud)
或这个:
$Val.ToString() -eq [String]::Empty
Run Code Online (Sandbox Code Playgroud)
这往往工作得很好,因为[System.DBNull]::Value.ToString()返回一个空字符串,这样既[String]::IsNullOrWhiteSpace([System.DBNull]::Value)和[System.DBNull]::Value.ToString() -eq [String]::Empty评估为True。
显然,这些在逻辑上是不等价的,因为您的数据可能合法地具有空字符串,或者可能是作为空字符串(例如整数)没有意义的数据类型。但是,由于您通常希望以与空字符串和仅包含空格的字符串完全相同的方式对待 DBNull,因此如果您对数据足够了解,它会很有用。
如果您确实想知道该值是否为 DBNull,当然,请使用[DBNull]::Value.Equals($Value).