英文:
Adding parameters to SQLCommand and adding value later
问题
我看到了关于使用 Parameters.Add
与 Parameters.AddWithValue
的不同讨论(一个是显式的,另一个不是),但这不是我的问题。
我正在定义一个命令,将用于对数据库进行多次插入操作。我想做以下类似的事情:
[定义命令]
[添加参数(包括此时未知的batchid)]
[进入循环]
[创建新的batchid]
[设置参数值]
[执行命令]
[下一步]
这意味着我的参数提前清晰地定义,而我在循环内设置它们的值。这段代码如下:
$SqlCmdAdd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmdAdd.CommandType = [System.Data.CommandType]::StoredProcedure
$SqlCmdAdd.CommandText = "AddBatch"
$SqlCmdAdd.Parameters.Add("@RunId", [Data.SQLDBType]::UniqueIdentifier)
$SqlCmdAdd.Parameters.Add("@RunType", [Data.SQLDBType]::NVarChar, 50)
$SqlCmdAdd.Connection = $SqlConnection
在循环内,我认为可以这样做:
# 生成用作BatchID的GUID
$batchID = [guid]::NewGuid()
# 我尝试使用参数名称和它们的数字顺序。都不起作用
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID | Out-Null
$SqlCmdAdd.Parameters["@RunType"].Value = "HDD" | Out-Null
# $SqlCmdAdd.Parameters[0].SqlValue = $batchID | Out-Null
# $SqlCmdAdd.Parameters[1].SqlValue = "HDD" | Out-Null
然而,如果我读取 $SqlCmdAdd.Parameters[0] 和 [1] 的值,我会看到正确的名称和数据类型,但它们的值为空。因此,我将会收到一个错误,指出没有为参数指定值。
有效的方法是:
$SqlCmdAdd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmdAdd.CommandType = [System.Data.CommandType]::StoredProcedure
$SqlCmdAdd.CommandText = "AddBatch"
$SqlCmdAdd.Connection = $SqlConnection
在循环中执行以下操作:
# 添加参数
$SqlCmdAdd.Parameters.AddWithValue("@RunId", $batchID) | Out-Null
$SqlCmdAdd.Parameters.AddWithValue("@RunType", "HDD") | Out-Null
$SqlCmdAdd.ExecuteNonQuery()
$SqlConnection.Close()
# 清除参数集合以供下一次运行使用
$SqlCmdAdd.Parameters.Clear()
让我困扰的是需要在下一次运行之前清除参数集合,然后重新创建它们。虽然这可以运行我的代码,但我有兴趣找出为什么尝试在第一个代码块中设置早期创建的参数的值没有任何效果。
我尝试过搜索并阅读了无数文章。
英文:
I've seen the different discussions of using Parameters.Add
vs Parameters.AddWithValue
(one is explicit, the other is not), but that isn't my issue.
I'm defining a command, which will be used to do multiple inserts into the database. I figured I'd do something like the following:
[define command]
[add parameters (including a batchid not known at this time)]
[enter loop]
[create new batchid]
[set parameter value]
[execute command]
[next]
This would mean my parameters are neatly defined in advance, and I set their values within the loop. The code for that looks like this:
$SqlCmdAdd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmdAdd.CommandType = [System.Data.CommandType]::StoredProcedure
$SqlCmdAdd.CommandText = "AddBatch"
$SqlCmdAdd.Parameters.Add("@RunId", [Data.SQLDBType]::UniqueIdentifier)
$SqlCmdAdd.Parameters.Add("@RunType", [Data.SQLDBType]::NVarChar, 50)
$SqlCmdAdd.Connection = $SqlConnection
Within the loop I figured I could do something like this:
# Generate GUID to be used as a BatchID
$batchID = [guid]::NewGuid()
# I tried both using the parameter name, as well as their numeric order. Neither worked
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID | Out-Null
$SqlCmdAdd.Parameters["@RunType"].Value = "HDD" | Out-Null
# $SqlCmdAdd.Parameters[0].SqlValue = $batchID | Out-Null
# $SqlCmdAdd.Parameters[1].SqlValue = "HDD" | Out-Null
However, if I read out the values of $SqlCmdAdd.Parameters[0] and [1], I see the proper names and data types, but their values are null. Thus, I'll get an error that no values were specified for the parameters.
What did work was:
$SqlCmdAdd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmdAdd.CommandType = [System.Data.CommandType]::StoredProcedure
$SqlCmdAdd.CommandText = "AddBatch"
$SqlCmdAdd.Connection = $SqlConnection
Within the loop doing this:
# Add parameters
$SqlCmdAdd.Parameters.AddWithValue("@RunId", $batchID) | Out-Null
$SqlCmdAdd.Parameters.AddWithValue("@RunType", "HDD") | Out-Null
$SqlCmdAdd.ExecuteNonQuery()
$SqlConnection.Close()
# Clear parameter collection for next run
$SqlCmdAdd.Parameters.Clear()
What irritates me about this is the need to clear the parameter collection for the next run, and then recreating them. While that runs my code, I'm interested in finding out why attempting to set the value of the earlier created parameters in the first code block doesn't have any effect.
I tried googling and read countless articles.
答案1
得分: 7
这是因为在赋值之前将变量传递给 Out-Null
,所以会发生这种情况。因此,
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID | Out-Null
将首先将 $batchID
传递给 Out-Null
,并将结果 $null
分配给 .Value
。
至于修复方法,只需删除 Out-Null
,像这样:
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID
英文:
This happens, as piping the variable to Out-Null
happens before assignment. Thus,
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID | Out-Null
Will first pass $batchID
to Out-Null
, and the result - $null
- is assigned into .Value
.
As for a fix, just remove Out-Null
like so,
$SqlCmdAdd.Parameters["@RunId"].Value = $batchID
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论