Stored Procedure Problem - Exits Prematurely?

  • SQL Server 7.0 SP3

    I am having a problem with a stored procedure and I am pulling my hair out trying to figure out whats wrong.

    The stored procedure contains a section of code consisting of 3 simple update statements like those shown below.  These are the last statements in the stored procedure. The select @error & insert into debugtable statements were put in to determine that at least the sections of code were at least passed thru if the WHERE clause failed.

    The stored procedure is called hundreds of times a day.  A couple of times a week, the following happens.

    Table one is updated but Table 2 & Table 3 is not.  The debugtable shows an entry for Table1 Update with a error code of 0 and a row count of 1.  There are no entries for  Table2 or Table3.  Its like the stored procedure exited after inserting the Table1 update info into the debugtable.

    There are no entries in the server event logs or the sql server logs at the time of the problem.

    If anyone has any ideas or how to further troubleshoot the problem, that would be great.

    IF @Name != ' '

    BEGIN

    update Table1

       set Col2 = 'A',

           Col3 = 'B'

     where Col1 = @Name

    select @Error = @@ERROR, @RowCount = @@ROWCOUNT 

    insert into DebugTable values (getdate(),'Table1 Update',STR(@Error),STR(@RowCount))

    update Table2

       set Col2 = 'A',

           Col3 = 'B'

     where Col1 = @Name

    select @Error = @@ERROR, @RowCount = @@ROWCOUNT 

    insert into DebugTable values (getdate(),'Table2 Update',STR(@Error),STR(@RowCount))

    update Table3

       set Col2 = 'A',

           Col3 = 'B'

     where Col1 = @Name

    select @Error = @@ERROR, @RowCount = @@ROWCOUNT 

    insert into DebugTable values (getdate(),'Table3 Update',STR(@Error),STR(@RowCount))

    END

  • So can you reproduce the error - I'm guessing not? But if you can, try stepping through the stored proc in debug mode and see whether that gets you anywhere.

    Does the problem always happen at the same time of day? Perhaps when some other process is running?

    You could try running Profiler - set up a trace that filters out as much 'noise' as possible and focuses purely on the execution of the stored proc and leave it running - may provide some clues.

    Good luck

    Phil

    The absence of evidence is not evidence of absence
    - Martin Rees
    The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
    - Phil Parkin

  • Hi

    Sorry if this is a bit over-obvious but it looks to me like at the time it "fails" that tables 2 and 3 don't have a Col1 value that matches @Name. As there are no errors or exceptions then it looks to me like it's doing exactly what it's supposed to.

    Avoid the temptaption to say "...but I know there are relevant rows in the tables". My guess is that SQL-Server thinks not (maybe some other process locking the tables or something!)

    My next step would be, before each of the update steps do a count of the table where Col1 = @Name and save that in a working table somewhere along with some sort of date / time stamp (so you can tie the values with the "failures"). It's also possible that the first update causes the value of @Name to be Nulled, so it would be worth holding the value of @Name as well, before each update

    Then when it goes wrong you can see if you actually have any data that needs changing...

     Hope that helps

    Sam

  • Thanks for the suggestions.  It is not reproducable & appears to be random.

    It is a good suggestion to add the @Name value to my debug table before the updates but even if there were no rows in table 2 or table 3 that matched the WHERE clause the debug insert statement should have inserted the Table2 Insert & @@Error & @@ROWCOUNT into the debug table. Its almost as if the stored procedure just exited after the Table1 Inserted debug statement.

    I will try profiler but since it only happens 1 or 2 times a week, it will be a little tough to keep logs from being huge.

     

     

     

  • Just thought following might help in resolving your problem

    When a statement with in sp executes in sql server, and there is a error, whether the next statement will execute or not depends on the severity of the error.

    It might be happening in your case that the severity of the error in executing second update is so high that the sql server is aborting before even coming to error handling code. I have observed this behavior many times and I have started using the following stardard for coding stored procedures, which seem to work very well.

    1. Do not write error handling code inside stored procedures (since it is not certain that it will execute)

    2. Exit the sp as soon as error occurs with a return error code

    3. handle the error at the calling routine (VB-->ADO for example)

    Example

    Create Procedure TestSP

    ...

    BEGIN

      UPDATE TABLE1

      SET    ...

      WHERE  ...               ---Scenario 1 Severe error results in sp abort here

      SELECT @M_ERR = @@ERROR,...

      IF @M_ERR <> 0

        RETURN @M_ERR    ---Scenario 2 less Severe error results in controlled exit

      UPDATE TABLE2

      SET    ...

      WHERE  ...               ---Scenario 1 Severe error results in sp abort here

      SELECT @M_ERR = @@ERROR,...

      IF @M_ERR <> 0

        RETURN @M_ERR    ---Scenario 2 less Severe error results in controlled exit

      ...

      RETURN 0

    END

    -- VB --> ADO--------------------------------------

    Function blnExecTestSp() as boolean

      On Error Goto blnExecTestSpError

     

      blnExecTestSp = False

      'Create connection (usrCn) and command (usrCmd)

      'Set parameters for usrCmd

      usrCmd.Execute

     

      If usrCmd.Parameters(0) <> 0  --- Scenario 3 Handle less severe errors

        'Error information available in usrCmd.Errors

        'Handle the error, write to log,...

        Exit function

      End if

      blnExecTestSp = True

      Exit function

    blnExecTestSpError:            --- Scenario 4 Handle severe errors here

      'Error information available in usrCmd.Errors

      'Handle the error, write to log,...

    End Function

    As you can see here severe errors are handled using Scenario 1 and 4

    and less severe errors are handled using Scenario 2 and 3

  • Fair point but this wouldn't work if your SP was kicked of by another server process (say, a batch job).

    I do generally dissagree though... you should always have error handling in your procedures.

    It's true that serious errors just kill the procedure before your error handler kicks in and you need to cater for that, but if you properly construct your error handler it can return some valuable info on the cause of what went wrong as you can include data into your error string. You can of course get round that by using output parameters for returning error data but you start getting complexity and defeat the object of not having error handling...

    I think you really need a good combination of both techniques.

    Sam

  • Thanks for the suggestions.  Unfortunately, the SP is called by a 3rd party application that I have no control over.  I do not know what sort of error handling it has.  I am only given a required SP name, input & output parameters.

    If a serious error occurs that simply stops execution of the SP, shouldn't there be some sort of error info in the SQL log? 

  • Try the following example. It is similar to the one in the original problem. I am trying to write to a log table for each insert. You can run it in query analyzer to see the results.

    Note that only the first insert succeeds. Second insert has a error trying to insert string into integer column. Log table will not have entry for second insert.

    This is one of the case where the execution stops where error occurs (second insert). There may be other cases...

    When I said severe error, I didn't meen fatal errors. So you will not see these errors in Sql*server log or event log. These errors have the different severity level.

    Drop Table dbo.RpTest123

    Go

    Create Table dbo.RpTest123

    (code int,

     name varchar(12)

    )

    go

    Drop table dbo.RpTestLog123

    go

    Create Table dbo.RpTestLog123

    (

     error varchar(12),

     descr  varchar(255)

    )

    go

    drop procedure dbo.RpTest123Sp

    go

    Create procedure dbo.RpTest123Sp

    AS

    Begin

      declare @m_err int

      insert into dbo.RpTest123 values (1,'Rajesh1')

      select @m_err = @@error

      insert into dbo.RpTestLog123 values(STR(@m_err),'first insert')

      insert into dbo.RpTest123 values ('sdfd','Rajesh2')

      select @m_err = @@error

      insert into dbo.RpTestLog123 values(STR(@m_err),'second insert')

    end

    go

    ---------------------------------

    Now run the sp once

    exec dbo.RpTest123Sp

    check the log table

    select * from dbo.RpTestLog123

    ------------------

     0   first insert

     

     

  • Rajesh, thanks for the sample code.  It was enlightnening.  SQL Server should not just exit the procedure because of the 'string in an integer col' error.  The statement should fail & the error code should available in the @@error variable.  That is a serious deficiency.

    I did not know of this behavior and it gives me more things to look at.

    Again, thanks!    

Viewing 9 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic. Login to reply