0

Background:

I have a series of stored procedures that inserts one new record into 5 tables (all have a one-to-one relationship). Each stored procedure creates a unique ID for the related table. The last stored procedure adds all of those unique IDs into the last table (to allow for an INNER JOIN to retrieve all information across the individual tables).

I have created an additional stored procedure (let's call it spWrapper) that calls the 4 individual stored procedures (mentioned above). I would like to use the spWrapper to both insert and update a record. The current (insert) spWrapper only inserts a record; the 5 unique IDs are declared as OUTPUT parameters. My T-SQL knowledge is still basic and I am not sure how OUTPUT parameters affect stored procedures.

The current spWrapper code (shortened example):

ALTER PROCEDURE [dbo].[spWrapper] 

-- Return values
@idAddress                                      INT = NULL OUTPUT,
@idDetermination                                INT = NULL OUTPUT,
@idLegalDescription                             INT = NULL OUTPUT,
@idAddresses_LegalDescriptions_Determinations   INT = NULL OUTPUT,
@idLOMC                                         INT = NULL OUTPUT,

-- [Table#1] parameters
@Street     VARCHAR(50) = NULL,
@City       VARCHAR(50) = NULL,
@State      VARCHAR(2)  = NULL,
@ZipCode5   VARCHAR(5)  = NULL,
@ZipCode4   VARCHAR(4)  = NULL,
@GISCode    VARCHAR(15) = NULL

AS
SET NOCOUNT OFF
SET ROWCOUNT 0

-- =================================
-- Declare and initialize variables
-- =================================

DECLARE @Error      INT,
    @RC         INT,
    @Trancount  INT,
    @Message    VARCHAR(255)

SELECT  @Error      = 0,
    @RC         = 0,
    @Trancount  = @@TRANCOUNT,
    @Message    = NULL

-- ==========================================
-- Insert record into [Table#1]
-- ==========================================

IF @idAddress IS NULL
    BEGIN

    IF @Trancount = 0 BEGIN TRANSACTION

        EXEC    @RC = [spTable#1]
                @idLogin        = @idLogin,
                @idAddress      = @idAddress,
                @Street         = @Street,  
                @State          = @State,
                @City           = @City,
                @ZipCode5       = @ZipCode5,
                @ZipCode4       = @ZipCode4,
                @GISCode        = @GISCode

        SELECT  @Error = @@ERROR

            IF @RC <> 0 OR @Error <> 0
                BEGIN
                    IF @Trancount = 0 ROLLBACK TRANSACTION
                    SELECT @Message = 'dbo.spWrapper: Error inserting record into [Table#1]'
                GOTO lbl_abort
                END
    END

IF @Trancount = 0 COMMIT TRANSACTION

The current spTable#1 code

ALTER PROCEDURE [spTable#1]
@idLogin    INT,
@idAddress  INT = NULL OUTPUT,
@Street     VARCHAR(50),
@State      CHAR(2),
@City       VARCHAR(50),
@ZipCode5   CHAR(5),
@ZipCode4   CHAR(4),
@GisCode    VARCHAR(15)

IF @TranCount = 0 BEGIN TRANSACTION

IF @idAddress IS NULL
BEGIN 
    INSERT [dbo].[Table#1]
        (Street,
        [State],
        City,
        ZipCode5,
        ZipCode4,
        GisCode,
        InsertedidLogin,
        InsertedDate)
    VALUES
        (@Street,
        @State,
        @City,
        @ZipCode5,
        @ZipCode4,
        @GisCode,
        @idLogin,
        GETDATE())

SELECT  @Error  = @@ERROR,
        @RC     = @@ROWCOUNT,
        @idAddress = SCOPE_IDENTITY()

IF @Error <> 0 OR @RC <> 1
    BEGIN
        IF @TranCount = 0 ROLLBACK TRANSACTION
        SELECT @Message = 'spTable#1: Error inserting record into [Table#1]'
    GOTO lbl_abort
    END
END

My main question:

With the unique ID set as an OUTPUT parameter, can I insert an existing ID to call an UPDATE portion of spTable#1 (and subsequently spWrapper)? OR can I declare those unique IDs (ie: not as an OUTPUT parameter)?

Proposed change

CREATE PROCEDURE [dbo].[spWrapper]
@idLOMC     INT = NULL

DECLARE @idAddress          INT,
    @idLegalDescription INT,
    @idDetermination    INT,
    @idCommunity        INT,
    @idFirm             INT,
    @idCounty           INT,
    @idFloodZone        INT,
    @Error              INT,
    @RC                 INT,
    @Trancount          INT,
    @Message            VARCHAR(255)

SELECT  @idAddress          = NULL,
    @idLegalDescription = NULL,
    @idDetermination    = NULL,
    @Error              = 0,
    @RC                 = 0,
    @Trancount          = @@TRANCOUNT,
    @Message            = NULL

/* Lookup idAddress, idLegalDescription, idDetermination */

IF @idLOMC IS NOT NULL
BEGIN
    SELECT @idAddress = A.idAddress, @idLegalDescription = LD.idLegalDescription, @idDetermination = D.idDetermination
    FROM [Table#2] L
    INNER JOIN [Table#5] ALD
    ON L.idAddresses_LegalDescriptions_Determinations = ALD.idAddresses_LegalDescriptions_Determinations
    INNER JOIN [Table#1] A
    ON ALD.idAddress = A.idAddress
    INNER JOIN [Table#3] LD
    ON ALD.idLegalDescription = LD.idLegalDescription
    INNER JOIN [Table#4] D
    ON ALD.idDetermination = D.idDetermination
    WHERE L.idLOMC = @idLOMC

    IF @@ROWCOUNT = 0
        BEGIN
            SELECT @Message = 'dbo.spWrapper: Invalid idLOMC'
            GOTO lbl_abort
        END
END

/* Insert record into [Table#1] */

IF @idAddress IS NULL
BEGIN
        IF @Trancount = 0 BEGIN TRANSACTION

        EXEC    @RC = [spTable#1]
                @idLogin    = @idLogin,
                @idAddress  = @idAddress OUTPUT,
                @Street     = @Street,
                @State      = @State,
                @City       = @City,
                @ZipCode5   = @ZipCode5,
                @ZipCode4   = @ZipCode4,
                @GisCode    = @GisCode

                SELECT @Error = @@ERROR

                    IF @RC <> 0 OR @Error <> 0
                        BEGIN
                            IF @Trancount = 0 ROLLBACK TRANSACTION
                                SELECT @Message = 'spWrapper: Error inserting record into [Table#1]'
                                GOTO lbl_abort
                        END
END

/* Update record into [Table#1] */

ELSE
BEGIN
        IF @Trancount = 0 BEGIN TRANSACTION

        EXEC    @RC = [spTable#1]
                @idLogin    = @idLogin,
                @idAddress  = @idAddress,
                @Street     = @Street,
                @State      = @State,
                @City       = @City,
                @ZipCode5   = @ZipCode5,
                @ZipCode4   = @ZipCode4,
                @GisCode    = @GisCode

                SELECT @Error = @@ERROR

                    IF @RC <> 0 OR @Error <> 0
                        BEGIN
                            IF @Trancount = 0 ROLLBACK TRANSACTION
                                SELECT @Message = 'spWrapper: Error updating record in [TspTable#1]'
                                GOTO lbl_abort
                        END
END
halfer
  • 19,824
  • 17
  • 99
  • 186
alybaba726
  • 390
  • 4
  • 14
  • My question is why do you need 5 tables that have a 1:1 relationship? Sounds like something is highly out of the ordinary with your table structures. – Sean Lange Sep 08 '15 at 18:35
  • I unfortunately have no control over that aspect. I find it bizarre and ridiculous too, but I can't change it, the tables were created before my time. – alybaba726 Sep 08 '15 at 18:57
  • Understand about legacy structures. Sucks but sometimes you just have to plug your nose and carry on. The challenge in helping you here is that there isn't a lot of information to work with. I know your code is legacy but you should put some effort into getting rid of those GOTOs and that other nasty stuff for error handling. It would be better to use TRY/CATCH blocks. – Sean Lange Sep 08 '15 at 19:40
  • @SeanLange great idea, I'll look into it. I hate the GOTO, but I'm still learning so I'm taking a lot of cues from past code. – alybaba726 Sep 08 '15 at 20:05
  • With a whole series of procedures you need to run I would consider putting the entire block in a transaction (assuming the inner procedures don't have transaction), then you can control the entire block with a single try/catch. It is a lot cleaner and easier to work with. – Sean Lange Sep 08 '15 at 20:07
  • @SeanLange this stored procedure is just calling 5 other stored procedures, the original stored procedures all have GOTO error handling, will that affect the TRY/CATCH block in my main spWrapper? – alybaba726 Sep 09 '15 at 21:08
  • I can't really give you an answer here. It may or may not have a bearing on your main procedure. It depends on what is happening in those procedures. – Sean Lange Sep 09 '15 at 21:30
  • @SeanLange I guess I'll just have to find out when I start testing :)! Thanks for your help! – alybaba726 Sep 09 '15 at 21:37
  • Or you could go fix those other ones too. :) Would be good practice. – Sean Lange Sep 09 '15 at 21:37
  • The syntax around EXEC @RC = [spTable#1] does not state that idAddress, is an output parameter when it is called from the wapper stored proc. Exec myStoredPRoc idAddress, OUTPUT Also I do not think you need to set them to themselves when calling from the wrapper sp. – Sql Surfer Mar 08 '16 at 21:41

0 Answers0