我得到了这个参数:
$objDbCmd.Parameters.Add("@telephone", [System.Data.SqlDbType]::VarChar, 18) | Out-Null;
$objDbCmd.Parameters["@telephone"].Value = $objUser.Telephone;
字符串$objUser.Telephone
可以为空。如果它为空,我该如何将其转换为[DBNull]::Value
?
我试过了:
if ([string]:IsNullOrEmpty($objUser.Telephone)) { $objUser.Telephone = [DBNull]::Value };
但这给了我错误:
使用“0”参数调用“ExecuteNonQuery”的异常:“无法将参数值从ResultPropertyValueCollection转换为String。”
如果我将其转换为字符串,则会插入空字符串""
,而不是DBNull
。
如何实现这一目标?
感谢。
答案 0 :(得分:16)
在PowerShell中,您可以将null / empty字符串视为布尔值。
$x = $null
if ($x) { 'this wont print' }
$x = ""
if ($x) { 'this wont print' }
$x = "blah"
if ($x) { 'this will' }
所以......说过你能说:
$Parameter.Value = $(if ($x) { $x } else { [DBNull]::Value })
但我宁愿把它包装在像以下这样的函数中:
function CatchNull([String]$x) {
if ($x) { $x } else { [DBNull]::Value }
}
答案 1 :(得分:6)
我不知道powershell,但在C#中我会做这样的事情:
if ([string]::IsNullOrEmpty($objUser.Telephone))
{
$objDbCmd.Parameters["@telephone"].Value = [DBNull]::Value;
}
else
{
$objDbCmd.Parameters["@telephone"].Value = $objUser.Telephone;
}
答案 2 :(得分:1)
始终在数据库值的末尾附加+“”...
$ command.Parameters [“@ EmployeeType”]。Value = $ ADResult.EmployeeType +“”
答案 3 :(得分:0)
很多年后,让我澄清一下:
Josh's answer显示了一个有用的简化,用于测试字符串是否为空(依靠PowerShell的隐式到布尔转换 [1] ),但是与汤米(OP)的问题。
相反,错误消息
“无法将参数值从ResultPropertyValueCollection转换为字符串。”
暗示是导致问题的 non -null情况,因为$objDbCmd.Parameters["@telephone"].Value
期望 string 值或[DBNull]::Value
,而$objUser.Telephone
的类型为[ResultPropertyValueCollection]
,即值的集合。
因此,在非null的情况下,必须分配一个 string 值,该值必须从集合中派生;一种选择是获取 first 集合元素的值,另一种方法是使用[string]::Join(';', $objUser.Telephone)
将所有值与分隔符连接起来以形成单个字符串,或者使用只需使用"$($objUser.Telephone)"
,空格是可以接受的(对于多个电话号码来说不是一个好主意)。 [2]
尽管类型不匹配,但通过[string]:IsNullOrEmpty()
检测空集合实际上是可行的,这是由于PowerShell在将值传递给[string]
类型的方法参数时如何隐式对集合进行字符串化。 [2] < / sup>
类似地,使用隐式到布尔值的转换对集合也同样起作用:空集合的值为$false
,非空集合的值为$true
(只要因为至少有两个元素或唯一的元素本身会被视为$true
[1] )
因此,一种解决方案是使用 first 电话号码条目:
$objDbCmd.Parameters["@telephone"].Value = if ($objUser.Telephone) {
$objUser.Telephone[0].ToString() # use first entry
} else {
[DBNull]::Value
}
注意:如果$objUser.Telephone[0]
直接返回一个[string]
,则可以省略.ToString()
调用。
在 PowerShell v7 + 中,您也可以通过三元条件来缩短语句:
$objDbCmd.Parameters["@telephone"].Value =
$objUser.Telephone ? $objUser.Telephone[0].ToString() : [DBNull]::Value
[1]有关PowerShell的自动布尔转换的全面摘要,请参见this answer的底部。
[2]在隐式将集合转换为字符串时,默认情况下,PowerShell以单个空格作为分隔符将集合的字符串化元素连接在一起;您可以使用自动$OFS
变量覆盖分隔符,但实际上很少这样做;例如,数组'foo', 'bar'
转换为'foo bar'
;请注意,当您显式调用集合的.ToString()
方法 时,此转换不不适用,但是它确实适用于可扩展(插值)字符串内部,例如{{1 }}。