我正在一个项目中,该项目包括将数千个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,但是我很好奇为什么这行不通。
有什么想法吗?
答案 0 :(得分:2)
您的代码不会插入任何数据,因此根据SCOPE_IDENTITY()的官方文档中的定义,当前范围内不会生成任何身份值:
返回插入到同一作用域的标识列中的最后一个标识值。范围是一个模块:存储过程,触发器,函数或批处理。因此,如果两个语句在同一存储过程,函数或批处理中,则它们在同一范围内。
您的代码实际上与在SSMS的一个查询窗口中插入数据并在另一查询窗口中查询SCOPE_IDENTITY()相同。好吧,这不是它的工作原理。您必须在同一范围内查询它,即存储过程,触发器,函数或批处理。否则,请使用您生成的ID值并将其与数据一起插入。