Understanding Error Code 85132273 in Connection with GETLASTERRORCODE Statements


We recently received a few interesting requests about an error code appearing under particular circumstances: 85132273. This error might typically arise with the Windows Client but also with Web Services and NAS Services as well.

Digging under the hood, this error message is related to a Primary Key violation in SQL Server tables.

In most of cases, this could be due to C/AL code such as the following:

IF NOT MyTable.INSERT THEN …

This is quite an easy and diffuse syntax that looks innocent and clean (admittedly, we even have a few instances of it in the CRONUS demonstration database). However, it is a problematic use of code because it forces an INSERT into a table and if the record already exists, an implicit error is thrown. That gives us that violation of the primary key.

From a development perspective, we recommend that you refactor the code, where possible, in the following way (under a LOCKTABLE):

IF NOT MyTable.GET THEN MyTable.INSERT …

This code is preferable for at least two reasons:

  1. More logically correct

    It does not throw an implicit error caused by a primary key violation. Therefore developers could use GETLASTERRORCODE statement family in a more logical way. This statement family may catch, then, the violation of the primary key server side even though no visible runtime error would ever be show to the user. As short example, this code:

    CLEARLASTERROR;

    SalesPost.RUN;

    MESSAGE(GETLASTERRORTEXT);

    might display the error code 85132273 if there are nested statements like IF NOT INSERT THEN in the SalesPost codeunit.

    Please, be aware that this type of trapped error will not be displayed if also codeunit.RUN has a C/AL exception handling such as:

    CLEARLASTERROR;

    IF NOT SalesPost.RUN THEN

      MESSAGE(GETLASTERRORTEXT);

    In this case, any nested trapped error that might arise from IF NOT INSERT THEN will not be intercepted and no error text will be shown for this kind of violation of primary key.

  2. More efficient in some cases.

    INSERT statements with an implicit violation of the primary key are costly and if the code is typically something like IF NOT INSERT THEN MODIFY and the number of MODIFY statements is high, the statement with IF NOT GET THEN INSERT ELSE MODIFY or, better, IF GET THEN MODIFY ELSE INSERT would be typically faster in terms of performance.

If you intend to implement error statement like GETLASTERRORMESSAGE, GETLASTERRORCODE and GETLASTERRORCALLSTACK, then you might notice that C/SIDE error code refers to a DB:RecordExists. Attached to this blog post, you will find a simple page object as proof of concept to demonstrate when and how this error might arise for a better understanding.

Please use the attached page object only for testing and understanding, and do not use it on a live environment. It is just to demonstrate the error code in a standard CRONUS demonstration database.

These postings are provided “AS IS” with no warranties and confer no rights. You assume all risk for your use.

 

Duilio Tacconi                                      Microsoft Dynamics Italy         

Microsoft Customer Service and Support (CSS) EMEA

Special thanks to Peter Elmqvist from nabsolution.se 

DynamicsNAV_Error85132273ObjectRepro.txt

Comments (5)

  1. The problem with the code "IF NOT MyTable.GET THEN MyTable.INSERT … " is that you need to have all the primary key fields populated. In a number of cases that is not possible (e.g. since it will be populated in the OnInsert trigger).

    Typically that code would currently look like: IF Record.INSERT(TRUE) THEN …

    How do you recommend to rewrite this code?

  2. Johannes Wikman says:

    @Jan: My recommendation is to never execute "IF NOT Record.INSERT(TRUE) THEN", because the code in OnInsert trigger will be run even if the INSERT fails. This could give quite unexpected results…

    How to rework the code depends on what code you execute in OnInsert.

  3. Jens Glathe says:

    Re "IF NOT Record.INSERT(TRUE) THEN"… good to know. 🙂

  4. @Microsoft

    Yes, I certainly agree here.

    Personally I have never liked the "IF INSERT BREAKS DO A MODIFY" style of coding. I have used it on occasion (normally when being lazy) but much prefer not to use the exception trapping.

    @Jan/Jens

    As for the "IF Record.INSERT(TRUE) THEN" I would suggest you move the code that you would have in the OnInsert trigger into a function and explicitly call that function before you do your 'UPSERT' routine. This will explicitly show that the code will always be run.

    But, in the end the only time I've personally used this is when being lazy and I didn't bother to record where I got the record I want to save from. In every case I remember the correct replacement is:

     IF RecordIsNew THEN Record.INSERT(TRUE) ELSE Record.MODIFY(TRUE) ;

  5. Sergii Olefirenko says:

    There is one more drawback of using "IF NOT INSERT THEN …" that we have found: record insertion will be logged to Change Log anyway.

    Just as OnInsert trigger which is executed, OnDatabaseInsert trigger is executed as well.

Skip to main content