使用VB.Net访问数据库存储过程后返回True / False

时间:2018-07-23 20:17:36

标签: sql sql-server vb.net stored-procedures

我正在VB.Net中编写一个程序来与我正在创建的SQL Server数据库进行交互。在数据库中,我创建了以下存储过程,以便向数据库中的表之一添加新条目:

CREATE PROCEDURE CreatePurchaseOrder(
    @OrderNum VARCHAR(20),
    @JobNum   VARCHAR(10),
    @Supplier VARCHAR(75),
    @Contact  VARCHAR(100),
    @User     VARCHAR(100),
    @Notes    VARCHAR(MAX) = NULL
) AS
BEGIN
    DECLARE @JobID int, @SupplierID int, @ContactID int, @UserID int, @StatusID int

    SELECT @JobID = job_id
      FROM jobs
     WHERE job_number = @JobNum

    SELECT @SupplierID = supplier_id
      FROM suppliers
     WHERE supplier_name = @Supplier

    SELECT @ContactID = contact_id
      FROM supplier_contacts
     WHERE (first_name = SUBSTRING(@Contact, 1, CHARINDEX(' ', @Contact) - 1) AND
            last_name = SUBSTRING(@Contact, CHARINDEX(' ', @Contact) + 1, LEN(@Contact))) OR
           (first_name = SUBSTRING(@Contact, 1, CHARINDEX(' ', @Contact) - 1)) AND 
           supplier_id = @SupplierID

    SELECT @UserID = users_id
      FROM users
     WHERE first_name = SUBSTRING(@User, 1, CHARINDEX(' ', @User) - 1) AND
           last_name = SUBSTRING(@User, CHARINDEX(' ', @User), LEN(@User))

    SELECT @StatusID = status_id
      FROM purchase_statuses
     WHERE status_description = 'Ordered'

    IF(NOT EXISTS(SELECT order_id FROM purchase_orders WHERE order_number = @OrderNum))
        BEGIN
            INSERT INTO purchase_orders(order_number, job_id, supplier_id, contact_id, users_id, status_id, notes)
            VALUES (@OrderNum, @JobID, @SupplierID, @ContactID, @UserID, @StatusID, @Notes)
            RETURN 0
        END
    ELSE
        RETURN 1
END

该过程的目的是在数据库中创建一个新文件,如果文件插入成功,则返回0。如果失败,则返回1。我试图使布尔值与SQL,因为在正常的成功查询中,SQL返回0表示成功,返回1表示错误/失败iirc。

无论如何,当我使用VB.Net程序访问存储过程时,我遇到了获取布尔返回值的问题。这是调用过程的方法(这是用于调用任何SqlCommand的通用方法)

Public Function ExecuteCMD(ByRef CMD As SqlCommand) As DataSet
    Dim DS As New DataSet()
    Try
        OpenDBConnection()
        CMD.Connection = DB_CONNECTION
        If CMD.CommandText.Contains(" ") Then
            CMD.CommandType = CommandType.Text
        Else
            CMD.CommandType = CommandType.StoredProcedure
        EndIf
        Dim adapter As New SqlDataAdapter(CMD)
        adapter.SelectCommand.CommandTimeout = 300
        adapter.Fill(DS)
        CloseDBConnection()
    Catch ex As Exception
        Throw New Exception("Database Error: " & ex.Message)
    End Try
    Return DS
End Function

当我为ExecuteCMD()过程调用CreatePurchaseOrder函数时,它返回的数据集根本没有值。因此,我无法检测到表插入是否成功。我是否需要在SQL端进行一些更改才能获得所需的结果?还是需要更改.Net代码中的某些内容?

编辑:这是调用ExecuteCMD()函数的代码:

Public Function CreatePurchaseOrder(ByVal orderNum As String, ByVal jobNum As String, ByVal supplier As String, ByVal contact As String, ByVal user As String, Optional ByVal notes As String = "") As Boolean
    Dim CMD As New SqlCommand("CreatePurchaseOrder")
    CMD.Parameters.Add("@OrderNum", SqlDbType.VarChar).Value = orderNum ' L154-2002'
    CMD.Parameters.Add("@JobNum", SqlDbType.VarChar).Value = jobNum 'L154'
    CMD.Parameters.Add("@Supplier", SqlDbType.VarChar).Value = supplier 'A2A Systems'
    CMD.Parameters.Add("@Contact", SqlDbType.VarChar).Value = contact 'Ian '
    CMD.Parameters.Add("@User", SqlDbType.VarChar).Value = user 'John Doe'
    CMD.Parameters.Add("@Notes", SqlDbType.VarChar).Value = notes
    CreatePurchaseOrder = CBool(ExecuteCMD(CMD).ToString())
End Function

每个参数添加末尾的结尾注释是将要使用的数据集的示例。

1 个答案:

答案 0 :(得分:2)

当存储过程以RETURN x结尾时,您可以使用属性Direction设置为ParameterDirection.ReturnValue的参数来检索x的值。
而且您不需要DataSet和DataAdapter即可获得此值

您可以通过这种方式更改方法(请注意,我假设您已经准备好SP所需的6个参数

Public Function ExecuteCMDWithReturnValue(ByRef CMD As SqlCommand) As Boolean
    Try
        OpenDBConnection()
        CMD.Connection = DB_CONNECTION
        CMD.Parameters.Add("@ret", SqlDbType.Int).Direction = ParameterDirection.ReturnValue
        ' Well, this should be done when you create and prepare the command, not here.
        CMD.CommandType = CommandType.StoredProcedure
        CMD.ExecuteNonQuery()
        Dim result As Object = CMD.Parameters("@ret").Value
        Return If(Convert.ToInt32(result) = 1, False, True) 
    Catch ex As Exception
        Throw New Exception("Database Error:  " & ex.Message)
        Return False    
    Finally
        CloseDBConnection()
    End Try
End Function

请注意,尝试为每种可能的数据库交互情况创建一个通用的通用方法是一项非常复杂的任务。我建议您使用适当的ORM来处理数据库任务,或者至少编写一个特定于每个任务的数据库层,而不是通用的数据库层来提供所有服务。