Domanda

I got a Table with an Auto Increment Column which looks like:

ALTER TABLE SOMESCHEMA.SOMETABLE 
    ALTER COLUMN ID 
        SET DATA TYPE INTEGER GENERATED BY DEFAULT 
        SET INCREMENT BY 1 
        SET NO ORDER 
        SET NO CYCLE 
        SET MINVALUE 1 
        SET MAXVALUE 2147483647 
        SET NO CACHE;

As long as i let the DBMS generate the Ids everything works fine and I can get the generated Id via:

SELECT IDENTITY_VAL_LOCAL() FROM sysibm.sysdummy1

But sometimes i need to insert a row with an ID of my choice and there i get into trouble.

Lets say we got a single row in the table with ID 1.
Now i insert a new row with a manually assigned id of 2.
The next time i try to insert a new row without a preset ID i get an error SQL0803 "DUPLICATE KEY".

I assume the internal "NextId" field for that Auto-Increment Column doesnt update itself if the Id of a row is manually set.

So I tried reseting this field with:

ALTER TABLE SOMESCHEMA.SOMETABLE ALTER COLUMN ID RESTART WITH 3

But this causes a permanent Table lock, which i dont know how to unlock.

How can i get this "Mixed-Mode" ID-Column working? Is it possible to get it to work like MySQL where the DBMS automatically updates the "NextID" upon a manually-Id Insert? If not, how can I release that {insert swear-word here} lock that pops up if i try to reset the NextId?

È stato utile?

Soluzione

SQL0913 isn't creating a lock - it is reporting that a lock exists. ALTER TABLE needs an exclusive lock on the table in order to reset the ID number. A table can be locked by another process having it open, or it can be locked by this process if there are uncommitted rows.

There is another reason the table is in use - soft close (or pseudo-close). For performance reasons, DB2 for i keeps cursors in memory so that they can be reused as efficiently as possible. So even if you say CLOSE CURSOR, DB2 keeps it in memory. These soft closed cursors can be closed by the command ALCOBJ OBJ((SOMSCHEMA/SOMETABLE *FILE *EXCL)) WAIT(1) CONFLICT(*RQSRLS) The CONFLICT(*RQSRLS) parameter tells DB2 to close all soft closed cursors.

So the root of the issue is that DB2 wants exclusive access to the table. Which is sort of a design question, because typically one doesn't manipulate the table's structure during the work day. It sounds as though this table is sometimes a parent and sometimes a child when it comes to ID numbers. If that is the case, may I suggest that you ALTER the table again?

I think the implementation might be better if you used a trigger rather than auto-increment. Fire the trigger on INSERT. If ID is supplied, do nothing. If ID is not supplied, SELECT MAX(ID)+1 and use that as the actual ID number you commit to the database.

Altri suggerimenti

ALTER TABLE table_name ALTER COLUMN column_name RESTART WITH 99999;

Fixed my issue. "99999" is the next ID to be used for example

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top