Powershell and SQL parameters. If empty string, pass DBNull

后端 未结 4 455

I got this parameter:

$objDbCmd.Parameters.Add(\"@telephone\", [System.Data.SqlDbType]::VarChar, 18) | Out-Null;
$objDbCmd.Parameters[\"@telephone\"].Value =         


        
相关标签:
4条回答
  • 2021-01-18 07:57

    I don't know about powershell, but in C# I would do something like this:

    if ([string]::IsNullOrEmpty($objUser.Telephone))
    {
     $objDbCmd.Parameters["@telephone"].Value = [DBNull]::Value;
    }
    else
    {
     $objDbCmd.Parameters["@telephone"].Value = $objUser.Telephone;
    }
    
    0 讨论(0)
  • 2021-01-18 07:59

    Many years later, let me clarify:

    Josh's answer shows a helpful simplification for testing strings for emptiness (relying on PowerShell's implicit to-Boolean conversion[1]), but it is unrelated to Tommy's (the OP's) problem.

    Instead, the error message

    "Failed to convert parameter value from a ResultPropertyValueCollection to a String."

    implies that it is the non-null case that caused the problem, because $objDbCmd.Parameters["@telephone"].Value expects either a string value or [DBNull]::Value, whereas $objUser.Telephone is of type [ResultPropertyValueCollection], i.e. a collection of values.

    Thus, in the non-null case, a string value must be assigned, which must be derived from the collection; one option is to take the first collection element's value, another would be to join all values with a separator to form a single string, using, e.g., [string]::Join(';', $objUser.Telephone) or, if joining the elements with spaces is acceptable (not a good idea with multiple phone numbers), simply with "$($objUser.Telephone)".[2]

    Detecting an empty collection via [string]:IsNullOrEmpty() actually worked, despite the type mismatch, due to how PowerShell implicitly stringifies collections when passing a value to a [string] typed method parameter.[2]

    Similarly, using implicit to-Boolean conversion works as expected with collections too: an empty collection evaluates to $false, a non-empty one to $true (as long as there are either at least two elements or the only element by itself would be considered $true[1])

    Therefore, one solution is to use the first telephone number entry:

    $objDbCmd.Parameters["@telephone"].Value = if ($objUser.Telephone) {
        $objUser.Telephone[0].ToString()  # use first entry
      } else {
        [DBNull]::Value
      }
    

    Note: If $objUser.Telephone[0] directly returns a [string], you can omit the .ToString() call.

    In PowerShell v7+ you can alternatively shorten the statement via a ternary conditional:

    $objDbCmd.Parameters["@telephone"].Value =
      $objUser.Telephone ? $objUser.Telephone[0].ToString() : [DBNull]::Value
    

    [1] For a comprehensive summary of PowerShell's automatic to-Boolean conversions, see the bottom section of this answer.

    [2] When implicitly converting a collection to a string, PowerShell joins the stringified elements of a collection with a single space as the separator by default; you can override the separator with the automatic $OFS variable, but that is rarely done in practice; e.g., array 'foo', 'bar' is converted to 'foo bar'; note that this conversion does not apply when you call the collection's .ToString() method explicitly, but it does apply inside expandable (interpolating) strings, e.g., "$array".

    0 讨论(0)
  • 2021-01-18 08:07

    In PowerShell, you can treat null/empty strings as a boolean.

    $x = $null
    if ($x) { 'this wont print' }
    
    $x = ""
    if ($x) { 'this wont print' }
    
    $x = "blah"
    if ($x) { 'this will' }
    

    So.... having said that you can do:

    $Parameter.Value = $(if ($x) { $x } else { [DBNull]::Value })
    

    But I'd much rather wrap this up in a function like:

    function CatchNull([String]$x) {
       if ($x) { $x } else { [DBNull]::Value }
    }
    
    0 讨论(0)
  • 2021-01-18 08:08

    Always append +"" at the end of db values...

    $command.Parameters["@EmployeeType"].Value= $ADResult.EmployeeType + ""

    0 讨论(0)
提交回复
热议问题