0

我有这个代码。我想获取插入语句的 id 并存储在一个变量中。我不能使用 SqlDataSource 所以我只能使用 DataTableReader 并且我不熟悉在 DataTableReader 中处理 SCOPE_IDENTITY ......

Dim sql As String = "insert into tbl_url (url) values ('" & Request.RawUrl & "')"
    'Helper is a class of mine, don't mind it
    Helper.execQuery(sql)
    sql = "select SCOPE_IDENTITY() as id"
    Dim dtr As Data.DataTableReader
    dtr = Helper.getDataTableReader(sql)
    Dim code As Decimal
    If dtr.Read Then
        code = dtr("id")
    End If
    dtr.Close()

dtr("id") 是 DBNull ......为什么?

编辑:

正如 Damien_The_Unbeliever 所说,在 Helper 中连接关闭,所以这是两个不同的范围......

有谁知道如何仅使用 DataTableReader 将 SCOPE_IDENTITY 存储在变量中?

4

1 回答 1

1

正如您在评论中已经确定的那样,Helper 正在关闭两个查询之间的连接,导致每个查询在其自己的范围内执行。这就是为什么SCOPE_IDENTITY找不到您的 ID。

有几个选项:

@@IDENTITY- 这将返回当前会话中任何表中插入的最后一个 ID。但是,这可能有同样的问题。

IDENT_CURRENT- 这将返回在任何会话中插入指定表中的最后一个 ID。但是,这不一定是您的ID(可能是另一个人在进行另一次插入。

然而,这两者都有问题。您最好直接从查询中返回 ID。在相关说明中 - 您不应将数据连接到 SQL 字符串中 - 这会使您面临 sql 注入攻击。相反,您应该使用 Sql 参数。

下面是一个大致是您需要做的示例。显然,我已将其直接编码为 ADO.Net - 您需要弄清楚它如何适合您的 Helper 类。

Dim sql As String = "insert into tbl_url (url) values (@url); Select @ID = SCOPE_IDENTITY()"
Dim id As String = String.Empty

Dim sqlcmd As New SqlClient.SqlCommand()
sqlcmd.Connection = New SqlClient.SqlConnection("Your Connection String here")
sqlcmd.Connection.Open()
sqlcmd.CommandText = sql
sqlcmd.Parameters.Add(New SqlClient.SqlParameter("url", Request.RawUrl))


Dim idParam = New SqlClient.SqlParameter("ID", id)
idParam.Direction = ParameterDirection.Output
sqlcmd.Parameters.Add(idParam)

sqlcmd.ExecuteNonQuery()

'Get the Value from the output parameter
id = idParam.Value
于 2014-05-22T12:35:51.533 回答