我正在开发一个项目,其中包括将数千个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();
just返回一个空记录集。直接在db上运行时,相同的查询可以成功运行。
实际上我可以通过其他方式解决这个问题。有一个UUID列,我应该插入第一个表中的行。我可以简单地用这个UUID查询表并得到PK,但我只是好奇为什么这不起作用。
有任何想法吗?
您的代码不会插入任何数据,因此在当前范围内不会生成任何标识值,如SCOPE_IDENTITY()的官方文档中所定义:
返回插入同一范围内的标识列的最后一个标识值。范围是一个模块:存储过程,触发器,函数或批处理。因此,如果两个语句在同一存储过程,函数或批处理中,则它们在同一范围内。
您的代码有效与在SSMS中的一个查询窗口中插入数据并在另一个查询窗口中查询SCOPE_IDENTITY()相同。嗯,这不是它的工作原理。您必须在相同的范围内查询它,即存储过程,触发器,函数或批处理。否则,使用您生成的ID值并将其与数据一起插入。