VB.net 使用存储过程插入多个相关表。只有第一个表接收插入的行

Posted

技术标签:

【中文标题】VB.net 使用存储过程插入多个相关表。只有第一个表接收插入的行【英文标题】:VB.net insert into multiple related tables using a stored procedure. Only first table receives an inserted row 【发布时间】:2012-08-31 12:31:09 【问题描述】:

如果单独使用存储过程 ins_address 可以正常工作,不会出错。 使用 VB 代码(如下所示)时,不会将行插入到 tbl_AddressEntity 中。 tbl_Address 可以,没关系。我绞尽脑汁将近两天,准备跳崖了。谁能告诉为什么该行不会插入到第二个表中?谢谢。

`

ALTER PROCEDURE [dbo].[ins_address]
@AddressLine1 AS VARCHAR(60),
@AddressLine2 AS VARCHAR(60),
@AddressLine3 AS VARCHAR(60),
@TownText AS VARCHAR(30),
@CountyText AS VARCHAR(30),
@PostcodeTownDistrictID AS INT,
@PostcodeOutwardCode AS VARCHAR(4),
@PostcodeInwardCode AS VARCHAR(3),
@SiteID AS INT,
@CompanyBranchID AS INT,
@PersonID AS INT,
@AddressTypeID AS INT,
@AddressID AS INT = -1 OUTPUT

AS 

BEGIN TRY
INSERT INTO tbl_Address 
(
AddressLine1, 
AddressLine2, 
AddressLine3, 
TownText, 
CountyText,
PostcodeTownDistrictID,
PostcodeOutwardCode,
PostcodeInwardCode
)
VALUES 
(
@AddressLine1, 
@AddressLine2, 
@AddressLine3, 
@TownText, 
@CountyText,
@PostcodeTownDistrictID,
@PostcodeOutwardCode,
@PostcodeInwardCode
);

RETURN SCOPE_IDENTITY();

SELECT @AddressID = SCOPE_IDENTITY();

INSERT INTO tbl_AddressEntity
(
AddressID,
SiteID,
CompanyBranchID,
PersonID,
AddressTypeID
)
VALUES
(
@AddressID,
@SiteID,
@CompanyBranchID,
@PersonID,
@AddressTypeID
);

END TRY

BEGIN CATCH
 DECLARE
        @ErrorMessage nvarchar(2048)
        ,@ErrorSeverity int
        ,@ErrorState int

    SELECT
        @ErrorMessage = ERROR_MESSAGE()
        ,@ErrorSeverity = ERROR_SEVERITY()
        ,@ErrorState = ERROR_STATE();

IF @@TRANCOUNT > 0

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);

END CATCH

`


`

Private Sub UBSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UBSave.Click
          Try

                    If Not formOptions(0).Contains("Company Customer") Then
                        'Force commit of data changes to DS
                        **Me.UGAddresses.UpdateData()**
                        Me.UGContactInformation.UpdateData()

                        'Merge text boxes into DS
                        getNonCompanyCustomerFields()

                        'Save the contact first!
                        kernel.updateContact(Me.DsContact1)

                        'Now assuming we have the PKID from the contact insert, update associations to match!
                        If formOptions(0).Contains("New") Then
                            For Each row As DataRow In DsAddress1.Tables(0).Rows
                                If row.RowState = DataRowState.Added Then
                                    If row.Item("PersonID") Is System.DBNull.Value Then
                                        row.Item("PersonID") = DsContact1.Tables(0).Rows(0).Item("PersonID")
                                    End If
                                End If
                            Next
                            For Each row As DataRow In DsContactInfo1.Tables(0).Rows
                                If row.RowState = DataRowState.Added Then
                                    If row.Item("PersonID") Is System.DBNull.Value Then
                                        row.Item("PersonID") = DsContact1.Tables(0).Rows(0).Item("PersonID")
                                    End If
                                End If
                            Next
                            If Me.UTCMain.Tabs("Customer").Visible Then
                                Me.DsCustomers1.Tables(0).Rows(0).Item("PersonID") = DsContact1.Tables(0).Rows(0).Item("PersonID")
                            End If
                        End If

                        **kernel.updateAddresses(Me.DsAddress1)**
                        kernel.updateContactInfo(Me.DsContactInfo1)
                        If Me.UTCMain.Tabs("PersonCustomer").Visible Then
                            kernel.updateCustomer(Me.DsCustomers1)
                        End If
                        Me.Text = Me.Text.Replace(" *", "")

                        'Company Customer
                    Else
                        getCompanyCustomerFields()
                        kernel.updateCustomer(Me.DsCustomers1)
                        Me.Text = Me.Text.Replace(" *", "")
                    End If
                Catch ex As Exception
                    MsgBox("Exception thrown during save : " & ex.Message, MsgBoxStyle.Exclamation)
                    mySharedFunctions.LogProgress("frmContact.UBSave_Click - Error : " & ex.Message & vbCrLf & ex.StackTrace)
                    If Not ex.InnerException Is Nothing Then
                        mySharedFunctions.LogProgress("Inner exception : " & ex.InnerException.Message)
                    End If
                End Try
        End Sub

`


数据适配器更新过程: `

Public Sub updateAddresses(ByRef dsTemp As dsAddress)

            'For inserts we're passing back the new PKID amd syncing with the dataset via the source column mapping on the insert command. 
            'So we should be able to update by ref.
            Me.SqlDaAddress.Update(dsTemp)
        End Sub

`


DsAddress1 数据集包含一个表,其中包含相关存储过程中此 select 语句的结果: `

ALTER PROCEDURE [dbo].[get_address_by_companybranch_or_person]
/*@SiteID AS INT = -1,*/
@CompanyBranchID AS INT = -1,
@PersonID AS INT = -1

AS

IF @CompanyBranchID != -1
BEGIN

    SELECT     dbo.tbl_Address.AddressID, dbo.tbl_Address.AddressLine1, dbo.tbl_Address.AddressLine2, dbo.tbl_Address.AddressLine3, 
                      dbo.tbl_Address.TownText, dbo.tbl_Address.CountyText, dbo.tbl_Address.PostcodeTownDistrictID, dbo.tbl_Address.PostcodeOutwardCode, 
                      dbo.tbl_Address.PostcodeInwardCode, dbo.tbl_AddressEntity.SiteID, dbo.tbl_AddressEntity.CompanyBranchID, dbo.tbl_AddressEntity.PersonID, 
                      dbo.tbl_AddressEntity.AddressTypeID
    FROM         dbo.tbl_Address INNER JOIN
                      dbo.tbl_AddressEntity ON dbo.tbl_Address.AddressID = dbo.tbl_AddressEntity.AddressID
    WHERE     CompanyBranchID = @CompanyBranchID

END
ELSE

BEGIN

    SELECT     dbo.tbl_Address.AddressID, dbo.tbl_Address.AddressLine1, dbo.tbl_Address.AddressLine2, dbo.tbl_Address.AddressLine3, 
                      dbo.tbl_Address.TownText, dbo.tbl_Address.CountyText, dbo.tbl_Address.PostcodeTownDistrictID, dbo.tbl_Address.PostcodeOutwardCode, 
                      dbo.tbl_Address.PostcodeInwardCode, dbo.tbl_AddressEntity.SiteID, dbo.tbl_AddressEntity.CompanyBranchID, dbo.tbl_AddressEntity.PersonID, 
                      dbo.tbl_AddressEntity.AddressTypeID
    FROM         dbo.tbl_Address INNER JOIN
                      dbo.tbl_AddressEntity ON dbo.tbl_Address.AddressID = dbo.tbl_AddressEntity.AddressID 
    WHERE   PersonID = @PersonID


END

`

【问题讨论】:

【参考方案1】:

为什么是这条线?

RETURN SCOPE_IDENTITY(); 

此时您退出存储过程而不执行剩余代码。

MSDN 说

Exits unconditionally from a query or procedure. RETURN is immediate and complete 
and can be used at any point to exit from a procedure, batch, or statement block. 
Statements that follow RETURN are not executed. 

...请不要跳... :-)

【讨论】:

啊!我不知道!我从别人那里接手了数据库,不得不调整很多存储过程和代码。感谢您的帮助。我想这解释了为什么 tbl_AddressEntity 没有收到任何行! :-) 很高兴能提供帮助。如果我的回答帮助您解决了问题,请花点时间阅读常见问题解答How to accept answers

以上是关于VB.net 使用存储过程插入多个相关表。只有第一个表接收插入的行的主要内容,如果未能解决你的问题,请参考以下文章

VB.NET是如何使用ADO让存储过程返回数据表中的值呢?求解!

在 vb.net 中插入 INTO

如何使用 VB.NET 向两个表中插入数据?

ASPX VB.Net OleDb 将参数插入查询

VB.NET - 一个查询中的多个结果集?

错误:表插入在 vb.net 和 msacess 中返回错误