【问题标题】:Return SCOPE_IDENTITY() and OUTPUT with Classic ASP in SQL Server 2012 - Error Obj Closed在 SQL Server 2012 中使用经典 ASP 返回 SCOPE_IDENTITY() 和 OUTPUT - 错误对象已关闭
【发布时间】:2015-10-29 18:06:19
【问题描述】:

我正在使用需要从 SQL Server 2012 表中获取插入标识的经典 ASP (VB) 应用程序。

在开发中,我比较的是SCOPE_IDENTITY()OUTPUT,但是代码:

  1. 返回比预期更多的结果。结果始终是插入表中的 4 行,最后一个 Identity 在应用程序中返回。以前,我尝试过没有“Set NOCOUNT ON”的 SQL,但收到错误:

    ADODB.Recordset 错误“800a0e78”
    对象关闭时不允许操作。

  2. 显示Incorrect syntax near 'OUTPUT' 的错误消息。

如何纠正多行插入场景,以及在 VB 中使用这两种语法的最佳方法是什么? RecordSet 是否需要在插入后、选择之前关闭?

谢谢

首先,表格:

CREATE TABLE [dbo].[table_a]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [col1] [int] NULL,
    [col2] [int] NULL,
    [col3] [int] NULL
) ON [PRIMARY]
GO

接下来,经典的 ASP (VB) 代码:

<%
'---- CursorTypeEnum Values ----
Const adOpenForwardOnly = 0
Const adOpenKeyset = 1
Const adOpenDynamic = 2
Const adOpenStatic = 3

'---- LockTypeEnum Values ----
Const adLockReadOnly = 1
Const adLockPessimistic = 2
Const adLockOptimistic = 3
Const adLockBatchOptimistic = 4


strSQL = "SET NOCOUNT ON;INSERT INTO [table_a] ([col1],[col2],[col3]) VALUES (1,2,3) SELECT Scope_Identity() as ID;"


Set rsResults_a = Server.CreateObject("ADODB.Recordset")

rsResults_a.Open strSQL, objConnection, adOpenDynamic,adLockOptimistic

if not rsResults_a.eof then
    Do until rsResults_a.EOF
    ResultID_a = rsResults_a("ID")
    response.write("<BR>"&ResultID_a&"<BR>")
    rsResults_a.MoveNext
    Loop
end if
rsResults_a.close
Set rsResults_a=nothing

'/////


strSQL = "INSERT INTO [table_a] ([col1],[col2],[col3]) VALUES (1,2,3) OUTPUT inserted.ID;"


Set rsResults_b = Server.CreateObject("ADODB.Recordset")

rsResults_b.Open strSQL, objConnection, adOpenDynamic,adLockOptimistic


if not rsResults_b.eof then
    Do until rsResults_b.EOF
    ResultID_b = rsResults_b("ID")
    response.write("<BR>"&ResultID_b&"<BR>")
    rsResults_b.MoveNext
    Loop
end if
rsResults_b.close
Set rsResults_b =nothing

If objConnection.State = adStateOpen Then
    objConnection.Close
End If
%>

【问题讨论】:

  • 这两种方法都不是很好,当我靠近电脑时会发布答案。
  • 您应该使用存储过程和参数化查询。

标签: sql sql-server asp-classic adodb


【解决方案1】:

您的第一个strSQLVALUES (1,2,3) 之后需要一个分号。

第二个是无效的语法,应该和第一个一样(加上缺少的分号)。

【讨论】:

  • “应该像第一个”是指只添加缺少的分号,还是另外添加其他内容,例如“set nocount on”?我已经进行了分号编辑,但多个插入仍然存在。
  • 不,我错过了目的是将第一个查询与使用 OUTPUT 的查询进行比较,因此您应该按照@JensBorrisholt 的描述进行第二个查询。我看不出您的代码可能会导致多次插入,因此我怀疑正在发生您不知道的其他事情,因此不包括在您的问题中。
  • 我已将第一个 strSQL 更改为没有 SET NOCOUNT ON,并且多个插入停止;但是,我收到上述错误。此外,当我删除 SELECT SCOPE_IDENTITY() 时,多次插入停止,出现相同的错误。
  • 如果你做的一切都和你描述的完全一样,那我就没有解释了。我不知道为什么SET NOCOUNT ON; 会导致多次插入。
【解决方案2】:

您需要在strSQL 中的 VALUES (1,2,3) 之后添加分号

strSQL = "SET NOCOUNT ON; INSERT INTO [table_a] ([col1],[col2],[col3]) VALUES (1,2,3); SELECT Scope_Identity() as ID;"

如果你真的想使用输出 keyworh 获得相同的结果,那么你需要这样的 SQL:

Declare @InsertOutput table
(
  ID int
);


INSERT INTO [table_a]  ([col1],[col2],[col3]) 
  OUTPUT INSERTED.ID into @InsertOutput
VALUES (1,2,3); 

select * from @InsertOutput;

【讨论】:

  • 为了在 VB 中创建一个 SQL 字符串,使用您提供的变量声明,是否可以在一个字符串中“在线”完成?
  • 是的。它应该在一行中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多