T-SQL-SELECT SCOPE_IDENTITY在VBA代码中不起作用

时间:2019-02-23 08:23:43

标签: sql-server vba tsql

我正在一个项目中,该项目包括将数千个Excel行传输到SQL Server(如果我正确的话,它也称为T-SQL)数据库。我在VBA中整理了一些逻辑以整理数据。

首先让我给您一些背景信息。我要传输的数据是发票文件。在每一行上,都有库存项目,价格,发票编号,发票日期,客户名称等的代码。这些代码需要传输到专有ERP系统的数据库中。

我现在对数据库中的两个表感兴趣。第一个保存发票的抬头数据(客户数据,日期,发票编号,发票总数等)。第二张表中包含有关库存项目的信息(已售出多少,多少以及多少钱等)。

每次插入第一张表后,我必须获取插入行的主键,以便将行插入第二张表,这需要每行上第一张表的PK。

现在,我的方法是使用T-SQL的SCOPE_IDENTITY()函数。当我尝试直接通过SQL Server Management Studio在数据库上执行此操作时,它会顺利运行。

但是当我尝试在代码中使用它时,它将返回一个空的记录集。

我正在使用的代码如下:

Public Function Execute(query As String, Optional is_batch As Boolean = False) As ADODB.Recordset

    If conn.State = 0 Then
        OpenConnection
    End If

    Set rs = conn.Execute(query) 'this is the actual query to be executed

    Dim identity As ADODB.Recordset 'this rs supposed to hold the PK of inserted row, but returns an empty recordset

    Set identity = conn.Execute("SELECT SCOPE_IDENTITY();")

    If TypeName(identity.Fields(0).Value) = "Null" Then
        pInsertedId = -1
    Else
        pInsertedId = identity.Fields(0).Value 'I'm saving it in an object variable, to access it easily later on
    End If

    Set Execute = rs 'to be returned to the caller

    'closing the connection is handled outside this procedure

End Function

当我在VBA上运行此命令时,第二个查询SELECT SCOPE_IDENTITY();仅返回一个空的记录集。直接在数据库上运行时,相同的查询成功运行。

实际上,我可以通过其他方式实现这一目标。我应该将UUID列插入第一个表的行中。我可以简单地使用此UUID查询表并获取PK,但是我很好奇为什么这行不通。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您的代码不会插入任何数据,因此根据SCOPE_IDENTITY()的官方文档中的定义,当前范围内不会生成任何身份值:

  

返回插入到同一作用域的标识列中的最后一个标识值。范围是一个模块:存储过程,触发器,函数或批处理。因此,如果两个语句在同一存储过程,函数或批处理中,则它们在同一范围内。

您的代码实际上与在SSMS的一个查询窗口中插入数据并在另一查询窗口中查询SCOPE_IDENTITY()相同。好吧,这不是它的工作原理。您必须在同一范围内查询它,即存储过程,触发器,函数或批处理。否则,请使用您生成的ID值并将其与数据一起插入。