SQL Server identity column inserted 0 value with seed of 1 - sql

This is somewhat related to question: SQL server identity column values start at 0 instead of 1
But I'm not sure what happening here. We have our "blank" database which we use to start customer's accounts. We do that by backing up and restoring database.
Customer gets completely blank tables after restore. Example of table, all our tables have PKs exactly like this one:
CREATE TABLE [dbo].[RNPRatePlanStop]
(
[RatePlanStopKey] [int] IDENTITY(1,1) NOT NULL,
[RatePlanKey] [int] NOT NULL,
.....
)
Once in a while (not always and not on all tables) when new record inserted - 0 not expected 1 inserted. I'm not sure how this can be fixed or what I'm doing wrong. This is causing problems in UI because we don't count on having 0 keys..

Also declaration is IDENTITY(1,1) when I run command like this:
SELECT IDENT_CURRENT('RNPRatePlanStop')
It returned 0. For this table and about 7 other tables. Don't know how that was possible, maybe because IDENTITY was applied later via script.
Solution was to "seed" proper identity on those tables:
DBCC CHECKIDENT(RNPRatePlanStop, RESEED, 1)
After that - they all reset correctly and all is well. Still a mistery how those few out of a 100+ tables ended up like so.

Related

sybase sql anywhere 11 query results are incorrect

I have the following table which has >13.000 rows.
CREATE TABLE "DBA"."mytable" (
"c1" numeric(8,0) NOT NULL,
"c2" numeric(2,0) NOT NULL,
"c3" numeric(4,0) NOT NULL,
"c4" numeric(8,0) NOT NULL,
PRIMARY KEY ("c1","c2","c3","c4")
)
The following query returns no rows when there are at least two rows that happen to meet the condition:
select * from mytable A where A.c1=229 and A.c3=1
More strangely, a slightly modified (but same) version of the query returns 2 rows as expected:
select * from mytable A where A.c1=229 and A.c3+1=2
Having suspected there is some physical corruption in the db, I have created a new db, created the table with the above code and loaded values from an unload file. The results are the same.
I know all four columns in PK is not good design, but this shouldn't be an excuse for the db to return wrong results.
By playing with the column creation order and dropping the PK the problem disappears and reappears.
Does aynbody know a fix or some workaround about this problem?
The DB is on a Windows 8 64-bit system, the locale is Turkish.
Thanks
I remember long ago in the times I used Sybase, that sometimes the table's data get silently corrupted.
The only solution we found was to re-create the table and insert the data again. I'm sorry but that was the only solution we found. So, you could copy the data to another table, then drop and recreate your table, and finally copy the data back.

Adding Row in existing table (SQL Server 2005)

I want to add another row in my existing table and I'm a bit hesitant if I'm doing the right thing because it might skew the database. I have my script below and would like to hear your thoughts about it.
I want to add another row for 'Jane' in the table, which will be 'SKATING" in the ACT column.
Table: [Emp_table].[ACT].[LIST_EMP]
My script is:
INSERT INTO [Emp_table].[ACT].[LIST_EMP]
([ENTITY],[TYPE],[EMP_COD],[DATE],[LINE_NO],[ACT],[NAME])
VALUES
('REG','EMP','45233','2016-06-20 00:00:00:00','2','SKATING','JANE')
Will this do the trick?
Your statement looks ok. If the database has a problem with it (for example, due to a foreign key constraint violation), it will reject the statement.
If any of the fields in your table are numeric (and not varchar or char), just remove the quotes around the corresponding field. For example, if emp_cod and line_no are int, insert the following values instead:
('REG','EMP',45233,'2016-06-20 00:00:00:00',2,'SKATING','JANE')
Inserting records into a database has always been the most common reason why I've lost a lot of my hairs on my head!
SQL is great when it comes to SELECT or even UPDATEs but when it comes to INSERTs it's like someone from another planet came into the SQL standards commitee and managed to get their way of doing it implemented into the final SQL standard!
If your table does not have an automatic primary key that automatically gets generated on every insert, then you have to code it yourself to manage avoiding duplicates.
Start by writing a normal SELECT to see if the record(s) you're going to add don't already exist. But as Robert implied, your table may not have a primary key because it looks like a LOG table to me. So insert away!
If it does require to have a unique record everytime, then I strongly suggest you create a primary key for the table, either an auto generated one or a combination of your existing columns.
Assuming the first five combined columns make a unique key, this select will determine if your data you're inserting does not already exist...
SELECT COUNT(*) AS FoundRec FROM [Emp_table].[ACT].[LIST_EMP]
WHERE [ENTITY] = wsEntity AND [TYPE] = wsType AND [EMP_COD] = wsEmpCod AND [DATE] = wsDate AND [LINE_NO] = wsLineno
The wsXXX declarations, you will have to replace them with direct values or have them DECLAREd earlier in your script.
If you ran this alone and recieved a value of 1 or more, then the data exists already in your table, at least those 5 first columns. A true duplicate test will require you to test EVERY column in your table, but it should give you an idea.
In the INSERT, to do it all as one statement, you can do this ...
INSERT INTO [Emp_table].[ACT].[LIST_EMP]
([ENTITY],[TYPE],[EMP_COD],[DATE],[LINE_NO],[ACT],[NAME])
VALUES
('REG','EMP','45233','2016-06-20 00:00:00:00','2','SKATING','JANE')
WHERE (SELECT COUNT(*) AS FoundRec FROM [Emp_table].[ACT].[LIST_EMP]
WHERE [ENTITY] = wsEntity AND [TYPE] = wsType AND
[EMP_COD] = wsEmpCod AND [DATE] = wsDate AND
[LINE_NO] = wsLineno) = 0
Just replace the wsXXX variables with the values you want to insert.
I hope that made sense.

sql identity issue

I have column id which has identity column
CREATE TABLE EMP
(id int primary key identity(1,1),
name varchar(255));
Problem is that after 10 its gives value 111 then 112
why it is not giving 11
It depends how you are inserting the data into it. If it's simple INSERT INTO and nothing else around it, it's weird.
Maybe it's that issue with MSSQL 2012 server? There is a know bug about identity jump when server restarts.
More information http://www.codeproject.com/Tips/668042/SQL-Server-Auto-Identity-Column-Value-Jump-Is
Whatever the cause, you can reset your identity column using the DBCC CHECKIDENT command.
It accepts parameters to allow you to reset the value to whatever you desire. For example this:
DBCC CHECKIDENT ('[TableNameHere]', RESEED, 11)
Will reset the column to 11 - you can substitute whatever number is required as the final parameter.
Using TRUNCATE TABLE will also reset any identity columns - but it will also delete all your data, obviously. Using DELETE will remove data, but it does not change identity values.

DB2 naming a sequence on create table

This may seem like a pointless question, but I'll ask it.
In creating a DDL, I want to have all my relationships and "extra" information NAMED, so when the db throws an error its using MY name and not some auto-generated ID
this is great for my relations and indexes, however I've noticed that DB2 stores "sequences", and it just names them... I can't seem to figure out how to name them in the create script - and going in AFTER creation to figure out what is what is not an option.
EXAMPLE
SEQUENCE MY_SCHEMA.SQL131021121240860 is what DB2 named it when I created
What I'd like to do
CREATE SEQUENCE MY_SCHEMA.MY_TABLE_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 32767 0 0 CACHE 20;
I've tried this BEFORE the CREATE TABLE, and AFTER... but the sequences ALWAYS go in with this 'SQL131021121240..' naming
Here are the two ways I've tried it....
-- BEFORE, as my ERD software does...
CREATE SEQUENCE MY_SCHEMA.TEST_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 32767 0 0 CACHE 20;
CREATE TABLE MY_SCHEMA.TEST (
ID SMALLINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1, INCREMENT BY 1 ) NOT NULL,
NAME VARCHAR( 255 ) NOT NULL,
CONSTRAINT MY_SCHEMA_TEST_PK PRIMARY KEY ( ID )
) IN STORE16K;
-- AFTER, as it makes sense to me, that the table has to exist first
CREATE TABLE MY_SCHEMA.TEST2 (
ID SMALLINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1, INCREMENT BY 1 ) NOT NULL,
NAME VARCHAR( 255 ) NOT NULL,
CONSTRAINT MY_SCHEMA_TEST2_PK PRIMARY KEY ( ID )
) IN STORE16K;
CREATE SEQUENCE MY_SCHEMA.TEST2_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1000 MAXVALUE 32767 0 0 CACHE 20;
In both cases a sequence that is named by the DB shows up in the SEQUENCES folder....
can it be done? is there a reason NOT to do it?, I just hate seeing labels like "SQL131021121240860" showing up in diagrams and DDLs....
In doing some more reading, it appears as though I don't understand SEQUENCES, however I think my question is still relevant. I'd still like to NAME them.
I'm confused by the fact that sequences get automatically created on identity fields - the comments in this post ( DB2 Auto generated Column / GENERATED ALWAYS pros and cons over sequence ) make it seem as thou it's an either/or proposition to use 'generated identity' or 'sequences' - but the behavior of CREATE TABLE with a single column as identity DOES create a sequence...NOT ONLY that but it appears as though it's a 1:1 - which may be needed for identity, and its most likely that a defined sequence can be used by other things.. I get that they are "not bound" to tables specifically....
either way - my question of HOW to NAME them, instead of letting the DB name this is still my point.
Thx
As you have already realized, DB2 implicitly creates a sequence for each IDENTITY column, and there is no way to supply the name for such a sequence. Your requirement to have custom names seems arbitrary.

Converting Cursor based Duplication Procedure to SQL

I am trying to take a stored procedure that copies parent/child/grandchild rows into the same tables with a new unique identifier. The purpose of this is to produce a duplicate 'Order' with 'Order Lines' and 'Order Line Attributes'. The procedure currently in place is done using cursors, and I'd like to try and create a set based version.
One issue I've hit early on, is that automatic numbering in a human friendly format is done in a stored procedure.
DECLARE #sales_order_id nvarchar(50)
EXEC GetAutoNumber 'Order', #sales_order_id output
The execution is done within the cursor as it loops through the order Lines of a single order. Is there any way to call this on the fly? I thought of using a table value function but can't because the stored procedure updates the autonumber table to create the new value.
Ideally I would want to craft an insert statement that automatically retrieves/updates the AutoNumber that could be done across multiple rows simulatenously, for example:
INSERT INTO ORDER (
OrderId, -- Guid
OrderNumber, -- Human Friendly value that needs Autoincremented
...
)
SELECT
NEWID(),
???
FROM ORDER
WHERE OrderId = #OrderToBeCopied
I'm using SQL Server 2008, any suggestions?
EDIT: One reason that an identity column would not work is that the table these autonumbers are being stored in serves multiple entities and their prefixes. For instance, here is the DDL for the autonumber table:
CREATE TABLE [dbo].[pt_autonumber_settings](
[autonumber_id] [uniqueidentifier] NULL,
[autonumber_prefix] [nvarchar](10) NULL,
[autonumber_type] [nvarchar](50) NULL,
[changed_by] [nvarchar](30) NOT NULL,
[change_date] [datetime] NOT NULL,
[origin_by] [nvarchar](30) NOT NULL,
[origin_date] [datetime] NOT NULL,
[autonumber_currentvalue] [nvarchar](50) NULL
) ON [PRIMARY]
So the end result from the stored procedure is the newest autonumber_id for a certain autonumber_type, and it also retrieves the autonumber_prefix and concatenates the two together.
Is there some reason you can't use an IDENTITY column?
Please read edit below as my original answer isn't satisfactory
I'm not entirely sure how your OrderNumber is incremented but you could certainly use ROW_NUMBER() for this. Check out the MSDN doco on it
Assuming you just wanted a number allocated to each Order Id, then you'd have something like;
SELECT NEWID(),
ROW_NUMBER() OVER (ORDER BY <whatever column you need to order by to make the row number meaningful>) As MyFriendlyId
FROM ORDER
WHERE OrderId = #OrderToBeCopied
If it needs to have some sort of initial seed value, then you can always use
ROW_NUMBER() OVER (ORDER BY <whatever column you need to order by to make the row number meaningful>) + 1000 As MyFriendlyId -- or whatever your seed value should be
Edit:
I just re-read your question, and I suspect you wish to make OrderNumber to be unique across all records. I misread it initially to be something like an incremental line number to detail line items of the OrderId.
My solution in this case won't be any good, and I'd more inclined to go with the other answer suggested about having an identity column.
You could potentially select MAX(OrderNumber) at the beginning and then use that in conjunction with ROW_NUMBER but this is dangerous as it is likely to be a dirty read and won't guarantee uniquness (if someone performs a concurrent insert). If you did have a unique constraint and there was a concurrent insert while both reading the same MAX(OrderNumber) then you are likely to face unique constraint violations...so yeah...why can't you use an identity column :)