In the project I'm working at the Id for certain insert statements is managed by hdbsequences. Now I want to create a sequence for another table that already has existing data in it and I want it to start with the max id value of the data of that table.
I know I could just manually set the "start_with"-Property to it but that is not an option because we need to transport the sequence to another system later where the data in that corresponding table is not the same as on the current system (therefore the ID is different).
I also know of the "reset_by"-Property in which I can select the max value of the table, the problem is that I don't know how to trigger that explicitly.
What I already found out, is that the "reset_by"-Property is called whenever the database is restarted, but unfortunately that is not also not an option because we can't reset the database to not disrupt the other systems.
Thanks in advance for your time and help.
You can do an ALTER SEQUENCE and set the value to be used by the next sequence usage with the option "restart with".
For instance (schema name and sequence name have to be replaced):
alter sequence "<schema name>"."<sequence name>" restart with 100;
The integer value behind the "restart with" option has to be set to the value which has to be used next. So in case your last ID is 100, set it to 101. 101 is the value returned by the next NEXTVAL call on the sequence.
Related
We use a sequence in a Db2 database. Recently, we have migrated the data from an AIX server to a Linux server. During that the latest number of that sequence was not moved to the Linux system. As a consequence, we are seeing duplicates values now.
Here is how we use the sequence:
SELECT NEXTVAL FOR SEQ_YFS_ORDER_NO FROM SYSIBM.SYSDUMMY1
The current value of the sequence on Linux is 100092142. How can I update it to the current value that we have on the AIX system, i.e to (100110960)?
You can modify the sequence using ALTER SEQUENCE. An option offered by ALTER SEQUENCE is to RESTART it with a specific value. Try something like this:
ALTER SEQUENCE SEQ_YFS_ORDER_NO RESTART WITH 100110960
Also note that sequence numbers typically are cached. This may lead to a gap and could have caused the issue during the migration.
Use the below query to fetch next sequence value from DB2 database.
SELECT NEXT VALUE FOR "Sequence_name" FROM SYSIBM.SYSDUMMY1
Work Around
ALTER SEQUENCE SEQ_YFS_ORDER_NO INCREMENT BY (100110960-100092142);
SELECT SEQ_YFS_ORDER_NO FROM dual;
ALTER SEQUENCE SEQ_YFS_ORDER_NO INCREMENT BY 1;
Before backup of your database, you can too create one Stored Procedure to SET "START WITH" with current_value to all your SEQUENCES, so when you will do restore, they will be restored with your desired starts.
I've almost seen every post concerning this question but haven't captured the best one. Some of them recommend using Identity but some triggers to perform incrementing integer column.
I'd like also to use triggers as there will be more delete happen in my table in this case. In addition, as I have mainly come from Interbase DBMS where I used to create a before insert trigger on table this issue sucks until now as I migrated from Interbase to MS SQL Server.
This is how I did in Interbase
CREATE trigger currency_bi for currency
active before insert position 0
AS
declare variable m integer;
begin
select max(id)+1 from currency into :m;
if (:m is NULL ) then m=1;
new.id=:m;
end
So, as I should frequently use this, which is the best way to create a trigger that increments integer column using max(id)+1 ?
Don't use triggers to do this, it will either kill the performance or cause all sorts of concurrency problems, depending on your use of transactions and locking.
It's better to use one of mechanisms available in the engine -- identity property or sequence object.
If you're running a newer version of SQL Server, with sequence feature available, use sequence. It will allow you to reserve a range of ids from the client applcation, and assign them to new rows on the client, before sending them to server for insert.
Always use Identity option , because as you told that you frequently delete the record, in this case trigger will some time give wrong information ( Called Isolation level).
Suppose one transaction delete the highest one record and just before or same time your trigger fired. So it get the deleted highest record which is not exist after few second.
So when you fired select query, it show the gap which is wrong.
Sqlserver give the inbuilt mechanism of this type of situation with auto identity true option.
http://mrbool.com/understanding-auto-increment-in-sql-server/29171
You donot bother about this. Also draw back of trigger is if multiple insert happened, then it always fired after the last insert statement.
Try to never use trigger , as it is harmful and not controllable.
Still if you want , then add in your insert statement , not use trigger
How can I auto-increment a column without using IDENTITY?
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?
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.
ALTER TABLE table_name ALTER COLUMN column_name RESTART WITH 99999;
Fixed my issue. "99999" is the next ID to be used for example
We are using SQL Server 2008. We have an Existing database and it was required to ADD a new COLUMN to one of the Table which has 2700 rows only but one of its column is of type VARCHAR(8000). When i try to add new column (CHAR(1) NULL) by using ALTER table command, it takes too much time!! it took 5 minutes and the command was still running to i stopped the command.
Below is the command, i was trying to add new column:
ALTER TABLE myTable Add ColumnName CHAR(1) NULL
Can someone help me to understand that How the SQL Server handles
the ALTER Table command? what happens exactly?
Why it takes so much time to Add new column
EDIT:
What is the effect of Table size on ALTER Command?
Altering a table requires a schema lock. Many other operations require the same lock too. After all, it wouldn't make sense to add a column halfway a select statement.
So a likely explanation is that a process had the table locked for 5 minutes. The ALTER then has to wait until it gets the lock itself.
You can see blocked processes, and the blocking process, from the Activity Monitor in SQL Server Management Studio.
Well, one thing to bear in mind is that you were adding a new fixed length column to the table. The way that rows are structured in storage, all fixed length columns are placed before all of the variable length columns, for each row. So every row would have had to be updated in storage to make this change.
If, in turn, this caused the number of rows which could be stored on each page to change, a great many new allocations may have been required.
That being said, for the number of rows indicated, I wouldn't have though it should take 5 minutes - unless, as Andomar indicated, there was some lock contention also involved.
I recently created a SQL dump of a database behind a Django project, and after cleaning the SQL up a little bit was able to restore the DB and all of the data. The problem was the sequences were all mucked up. I tried adding a new user and generated the Python error IntegrityError: duplicate key violates unique constraint.
Naturally I figured my SQL dump didn't restart the sequence. But it did:
DROP SEQUENCE "auth_user_id_seq" CASCADE;
CREATE SEQUENCE "auth_user_id_seq" INCREMENT 1 START 446 MAXVALUE 9223372036854775807 MINVALUE 1 CACHE 1;
ALTER TABLE "auth_user_id_seq" OWNER TO "db_user";
I figured out that a repeated attempt at creating a user (or any new row in any table with existing data and such a sequence) allowed for successful object/row creation. That solved the pressing problem.
But given that the last user ID in that table was 446 - the same start value in the sequence creation above - it looks like Postgresql was simply trying to start creating rows with that key.
Does the SQL dump provide the wrong start key by 1? Or should I invoke some other command to start sequences after the given start ID? Keenly curious.
The dump is fine, no problem. If your code (or default value for the column) uses nextval() to get the next value from the sequence, everything will be fine as well. Check your code and see what it does, what SQL is executed. With this information you can see why things are going wrong.
Good luck!