【问题标题】:Get output value in ADO.Net without stored procedure在没有存储过程的情况下在 ADO.Net 中获取输出值
【发布时间】:2014-04-11 09:06:22
【问题描述】:

我正在将 ADODB 应用程序转换为 ADO.Net,其中包含一个插入新行并返回自动增量值的命令,如下所示:-

INSERT INTO [MyDB].[dbo].[MyTable] (COLUMN1, COLUMN2) OUTPUT inserted.ID_PRIMARY
                      VALUES ('This', 'That')

然后可以获取 OUTPUT 值并离开。但是当我尝试使用 ADO.Net 时,就像这样:-

command_string = (as above)
Dim insert_command   As SqlCommand     = New SqlCommand(command_string, database_connection)
Dim output_parameter As SqlParameter   = New SqlParameter("@inserted.ID_PRIMARY", SqlDbType.Int)
Dim transaction      As SqlTransaction = database_connection.BeginTransaction(System.Data.IsolationLevel.Serializable)
insert_command.Transaction = transaction
output_parameter.Direction = ParameterDirection.Output
insert_command.Parameters.Add(output_parameter)
insert_command.ExecuteNonQuery()
transaction.Commit

返回错误:-

SqlException (0x80131904) '.' 附近的语法不正确

我很感激我可以使用存储过程来执行插入并检索返回值,正如here 所解释的那样,但我想知道是否有任何方法可以在没有存储过程的情况下完成?还是我忽略了一些微不足道的错误?

【问题讨论】:

    标签: sql-server vb.net ado.net adodb


    【解决方案1】:

    OUTPUT Inserted.ID_PRIMARY 中新插入的ID 将是语句返回的数据集。您需要使用 ExecuteReader 方法来读取返回的值:

    ' setup as above - except you don't need the "output_parameter"
    Dim reader As SqlDataReader = insert_command.ExecuteReader()
    
    While reader.Read()
        ' get your newly inserted ID's here as returned dataset
        Dim newlyInsertedID As Integer = reader.GetInt32(0)
    
        ' if you insert multiple rows at once, you might need store those ID's 
        ' that you fetch back one by one into a list or something
    End While
    

    【讨论】:

    • 感谢您的帮助;我已经添加了数据读取器,但是SQL语句中仍然存在语法错误;你知道在这里做什么吗?
    • @BrianHooper:您发布的 SQL 似乎还不错 - 不确定...到底是什么错误?它指向哪里?您是否将 VB.NET 中的 SQL 连接在一起?也许您在某处缺少空格或类似的东西....或者您正在针对 SQL Server 2000 (或“80级”兼容模式的数据库)运行? OUTPUT 子句是 SQL Server 2005 ... 中的新功能
    【解决方案2】:

    您可以利用 SQL Server 可以在一个批处理中发出两个 sql 命令这一事实。并使用 T-SQL 函数SELECT SCOPE_IDENTITY 查找添加到当前作用域的最新标识值

    Dim sqlText = "INSERT INTO [MyDB].[dbo].[MyTable] (COLUMN1, COLUMN2) " & _
                  "VALUES ('This', 'That'); SELECT SCOPE_IDENTITY()"
    Dim insert_command = New SqlCommand(sqlText, database_connection)
    insert_command.Transaction = transaction
    Dim result = Convert.ToInt32(insert_command.ExecuteScalar())
    transaction.Commit
    

    否则,如果您想使用您的语法,则删除输出参数

    Dim sqlText = "INSERT INTO [MyDB].[dbo].[MyTable] (COLUMN1, COLUMN2) " & _ 
                  "OUTPUT inserted.ID_PRIMARY  VALUES ('This', 'That')"
    Dim insert_command  = New SqlCommand(sqlText, database_connection)
    insert_command.Transaction = transaction
    Dim result = Convert.ToInt32(insert_command.ExecuteScalar())
    transaction.Commit
    

    但和以前一样,使用 ExecuteScalar 来检索查询返回的第一行/第一列的值

    【讨论】:

      【解决方案3】:

      语法错误已通过将 SQL 更改为:-

      INSERT INTO [MyDB].[dbo].[MyTable] (COLUMN1, COLUMN2)
          OUTPUT inserted.ID_PRIMARY As ID_PRIMARY
              VALUES ('This', 'That')
      

      并像这样设置参数:-

      Dim output_parameter As SqlParameter = New SqlParameter("@ID_PRIMARY", SqlDbType.Int)
      

      【讨论】:

        【解决方案4】:

        试试下面的代码:

        /****** Object:  Table [dbo].[Pedidos]    Script Date: 03/01/2015 16:48:17 ******/
        SET ANSI_NULLS ON
        GO
        
        
        SET QUOTED_IDENTIFIER ON
        GO
        
        CREATE TABLE [dbo].[Pedidos](
        [PedidoID] [int] IDENTITY(1,1) NOT NULL,
        [Data] [date] NOT NULL,
        [clienteID] [int] NOT NULL,
         CONSTRAINT [PK_Pedidos] PRIMARY KEY CLUSTERED 
        (
        [PedidoID] ASC
        )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY =     OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        ) ON [PRIMARY]
        
        GO
        
        ALTER TABLE [dbo].[Pedidos]  WITH CHECK ADD  CONSTRAINT     [FK_Pedidos_Clientes] FOREIGN KEY([clienteID])
        REFERENCES [dbo].[Clientes] ([clienteID])
        GO
        
        ALTER TABLE [dbo].[Pedidos] CHECK CONSTRAINT [FK_Pedidos_Clientes]
        GO
        

        使用 Dim Identity As Integer 或声明 PUBLIC 返回插入记录的标识自动递增字段PedidoID的值。

            Dim connection As SqlConnection = databaseDB.GetConnection
            Dim insertStatement As String _
                = "INSERT [dbo].[Pedidos] " _
                & "([Data], [clienteID]) " _
                & "VALUES (@Data, @clienteID) SELECT @PedidoID = SCOPE_IDENTITY()" 'SELECT SCOPE_IDENTITY() AS 'Identity
            Dim insertCommand As New SqlCommand(insertStatement, connection)
            insertCommand.CommandType = CommandType.Text
            insertCommand.Parameters.AddWithValue("@Data", dbo_pedidos.Data)
            insertCommand.Parameters.AddWithValue("@clienteID", dbo_pedidos.clienteID)
            ' Inclui o SqlParameter para retornar o novo valor identity
            ' Define o ParameterDirection como Output.(Saida)
            insertCommand.Parameters.Add("@PedidoID", SqlDbType.Int, 0, "PedidoID")
            insertCommand.Parameters("@PedidoID").Direction = ParameterDirection.Output
        
            Try
                connection.Open()
                Dim count As Integer = insertCommand.ExecuteNonQuery()
                If count > 0 Then
                    Identity = insertCommand.Parameters("@PedidoID").Value
                    Return True
                Else
                    Return False
                End If
            Catch ex As SqlException
                Throw ex
            Finally
                connection.Close()
            End Try
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-25
          • 1970-01-01
          • 2010-09-18
          • 1970-01-01
          相关资源
          最近更新 更多