Why seed value not working fine? - sql

I'm using SQL Server 2012, and I have a primary key column of type bigint.
Sometimes on new insertions it takes a huge jump of 1000 or 10000 for new primary key.
For example:
ID
--
1
2
3
4
5
6
7
8
9
10001
10002
Why does this happen? Is this a bug?

This is the behaviour of SQL Server 2012.
To fix this issue, you need to make sure, you add a NO CACHE option in sequence creation / properties like this.
create sequence Sequence1
as int
start with 1
increment by 1
no cache
go
create table Table1
(
id int primary key,
col1 varchar(50)
)
go
create trigger Trigger1
on Table1
instead of insert
as
insert Table1
(ID, col1)
select next value for Sequence1
, col1
from inserted
go
insert Table1 (col1) values ('row1');
insert Table1 (col1) values ('row2');
insert Table1 (col1) values ('row3');
select *
from Table1
Hope this helps..

Related

"Batch auto-increment" IDs for multiple row insertion

I am working in SQL Server 2017, and I have a table of the form:
tbl_current
COL1 COL2
-----------
A 1
B 3
C 56
which I want to periodically insert into the table tbl_release.
This table would have an extra ID column, which I'd like to auto-increment with each "batch insertion". For example, let's say I perform the the ingestion of tbl_current into tbl_release, it would look like this:
tbl_release
ID COL1 COL2
----------------
1 A 1
1 B 3
1 C 56
Now, let's say I perform another ingestion with the same data, it'd look like:
tbl_release
ID COL1 COL2
----------------
1 A 1
1 B 3
1 C 56
2 A 1
2 B 3
2 C 56
What is the best way to achieve this? Is there some SQL Server feature that would allow to achieve this, or do I need to run some sub-queries?
I'd personallly use a sequence for this. Assuming the insert into your ephemeral table is done, it'd looks omething like this:
declare #ID int = next value for sequence dbo.mySequence;
insert into tbl_release
(ID, col1, col2)
select #ID, col1, col2
from tbl_current;
You can try this using MAX() function as shown below.
Declare #maxId int
set #maxId = (Select isnull(id, 0) from tbl_Current)
set #maxId = #maxId + 1
--Now to insert
insert into tbl_release values (#maxId, <Column1Value>, <Column2Value>)
For multiple insert you can try this
INSERT INTO tbl_release
SELECT #maxId, col1, col2 FROM tbl_Current
If your table's Id column is identity then you can also use the Scope_Identity to get the max value of Id column.
Your id is really an object. I would strongly suggest that you give it a full table:
create table batches (
batch_id int identity(1, 1) primary key,
batch_start_date datetime,
. . .
);
Then, your existing table should be structured as:
create table releases (
release_id int identity(1, 1) primary key,
batch_id int not null references batches(batch_id),
col1 char(1),
col2 int
);
That way, your database has referential integrity.

Know identity before insert

I want to copy rows from the table within the table itself. But before inserting I need to modify a varchar column appending the value of identity column to it.
My table structure is:
secID docID secName secType secBor
1 5 sec-1 G 9
2 5 sec-2 H 12
3 5 sec-3 G 12
4 7 sec-4 G 12
5 7 sec-5 H 9
If I want to copy data of say docID 5, currently this runs through a loop one row at a time.
I can write my query as
insert into tableA (docID, secName, secType, secBor)
select 8, secName, secType, secBor from tableA where docID = 5
But how can I set value of secName before hand so that it becomes sec-<value of secID column>?
Don't try to guess the value of identity column. In your case you could simply create a computed column secName AS CONCAT('sec-', secID). There is no further need to update that column.
DB Fiddle
It is also possible to create an AFTER INSERT trigger to update the column.
Since SQL Server does not have GENERATED ALWAYS AS ('Sec - ' + id) the only simple option I see is to use a trigger.
Adding to my comment something like:
insert into tableA (docID, secName, secType, secBor)
select
ROW_NUMBER() OVER (ORDER BY DocID),
'Sec -'+ ROW_NUMBER() OVER (ORDER BY DocID),
secType, secBor
from tableA
where docID = 5
In SQL Server 2012 and later, you can achieve this by using the new sequence object.
CREATE SEQUENCE TableAIdentitySeqeunce
START WITH 1
INCREMENT BY 1 ;
GO
create table TableA
(
secId int default (NEXT VALUE FOR TableAIdentitySeqeunce) not null primary key,
varcharCol nvarchar(50)
)
declare #nextId int;
select #nextId = NEXT VALUE FOR TableAIdentitySeqeunce
insert TableA (secId, varcharCol)
values (#nextId, N'Data #' + cast(#nextId as nvarchar(50)))

Query for Merge values from 3 column and merge as Primary Key in Oracle

In one table few columns are there and in 3 columns i want to merge values from these 3 columns and generate as Primary key after merging these 3 values.
Col1 having Datatype length 4, While col2 & col3 having datatype length 5 & 3 respectively. In col2 & col3 if any values are less than the maximum length then use LPAD with 0 and then after Merge into the Primary Key.
Ex- If col1 = 1234, col2 = 142, col3 = 32 then after merging It should be like "123400142032" as Primary Key.
You probably need something like this.
CREATE TABLE yourtable
(
col1 NUMBER,
col2 NUMBER,
col3 NUMBER
);
ALTER TABLE yourtable ADD (ID NUMBER GENERATED ALWAYS AS ( LPAD(col1,4,0)||LPAD(col2,5,0)||LPAD(col3,3,0) ) );
ALTER TABLE yourtable ADD CONSTRAINT t_test_pk PRIMARY KEY (ID) USING INDEX;
You may then insert only 3 columns and the column id gets automatically populated with a number such as 123400142032.
INSERT INTO yourtable (col1, col2, col3)
VALUES (1234, 142, 32);
Note : The create table script is just for understanding. You may not need it since you already have an existing table.
The virtual column syntax GENERATED .. AS works only in 11g and above. For lower versions, you may require a before insert trigger and a sequence.
with lp as
(select max(length(employee_id)) mp from employee),
llp as
(select max(length(first_name)) mf from employee)
select lp.*,lpad(employee_id,lp.mp,'0'),llp.*, lpad(first_name,llp.mf,'0'),
employee_id||lpad(employee_id,lp.mp,'0')||lpad(first_name,llp.mf,'0')from lp,llp,employee;
note: here employee_id and first_name are the columns, you can assume it as column1 and column2..

Compare between columns on different tables

I need to write T-SQL code that will compare between T1.PercentComplete that need to be between T2.StageFrom and T2.StageTo. and than get the T2.Bonus_Prec and join T1
T1:
T2:
The desired result for T2.Bonus_Prec is 0.02 since T1.Percent_Complete is .27, which is between 0 and 1.
The thing is that each Key can have a different T2.StageID between 1-6.
If Key have just one T2.StageID it'll be 0. (fast way for me to know that there is only 1 bonus option)
If it have more than 1 it's will start with 1. (This can be changed if needed)
T1:
DROP TABLE T1;
CREATE TABLE T1(
Key VARCHAR(10) NOT NULL PRIMARY KEY
,Percent_Complete_ NUMBER(16,2) NOT NULL
);
INSERT INTO T1(Key,Percent_Complete_) VALUES ('Key Vendor',Percent_Complete);
INSERT INTO T1(Key,Percent_Complete_) VALUES ('***',0.27);
T2:
DROP TABLE T2;
CREATE TABLE T2(
Key VARCHAR(50) NOT NULL
,StageID INT NOT NULL
,Stage_From NUMERIC(10,2) NOT NULL
,Stage_To NUMERIC(8,2) NOT NULL
,Stage_Bonus_Prec NUMERIC(16,2) NOT NULL
);
INSERT INTO T2(Key,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('Key',Stage_Id,Stage_From,Stage_To,Stage_Bonus_Prec);
INSERT INTO T2(Key,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',1,0,0.8,0.02);
INSERT INTO T2(Key,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',2,0.8,1,0.035);
INSERT INTO T2(Key,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',3,1,-1,0.05);
OUTPUT:
+-----+-------------------+--------------------+
| Key | Percent_Complete | [Stage_Bonus_Prec] |
+-----+-------------------+--------------------+
| *** | 0.27 | 0.02 |
+-----+-------------------+--------------------+
Here is a SQLFiddle with these values
It is still not clear what you are trying to do but I made an attempt. Please notice I also corrected a number of issues with ddl and sample data you posted.
if OBJECT_ID('T1') is not null
drop table T1
CREATE TABLE T1(
KeyVendor VARCHAR(10) NOT NULL PRIMARY KEY
,PercentComplete VARCHAR(16) NOT NULL
);
INSERT INTO T1(KeyVendor,PercentComplete) VALUES ('***','0.27');
if OBJECT_ID('T2') is not null
drop table T2
CREATE TABLE T2(
MyKey VARCHAR(50) NOT NULL
,StageID INT NOT NULL
,Stage_From NUMERIC(10,0) NOT NULL
,Stage_To NUMERIC(8,0) NOT NULL
,Stage_Bonus_Prec NUMERIC(16,3) NOT NULL
);
INSERT INTO T2(MyKey,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',1,0,0.8,0.02);
INSERT INTO T2(MyKey,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',2,0.8,1,0.035);
INSERT INTO T2(MyKey,StageID,Stage_From,Stage_To,Stage_Bonus_Prec) VALUES ('***',3,1,-1,0.05);
select *
from T1
cross apply
(
select top 1 Stage_Bonus_Prec
from T2
where t1.PercentComplete >= t2.Stage_Bonus_Prec
and t1.KeyVendor = t2.MyKey
order by Stage_Bonus_Prec
) x
Taking a shot at this as well, since it's still a bit unclear:
SELECT t1.percent_complete, t2.Stage_Bonus_Prec
FROM T1 INNER JOIN T2
ON T1.[key vendor] = T2.[Key] AND
T1.[percent_complete] BETWEEN T2.Stage_From AND T2.Stage_To
Joining T1 and T2 on [Key Vendor] and [Key] and using the BETWEEN operator to find the percent_complete value that is between Stage_From and Stage_To.
I think I'm still missing something since I'm still confused about where Key value of *** comes from in your desired results.
SQLFiddle of this in action, based on a slightly fixed up version of your DDL (you put your field names in their own data record, I've removed them since they don't belong there).

T-SQL Insert Column from Other Table

Hello I am trying to insert values from one table column to another table. I am using SQL Server 2008 R2. Here is example:
Table 1
Declare #Table1 table (file varchar(15), type int, partiesid int)
Table 2
Declare #Table2 table (file varchar(15), ....many other columns)
I would like to insert file from Table 2 into Table 1 as well as some other static values.
So select * from table1 would end up looking like this:
File Type PartiesID
GW100 1 555
GW101 1 555
GW103 1 555
GW104 1 555
where the GW100, GW101, etc come from table2 and the 1 and 555 are static for every row.
I tried insert into table1 (file,type,partiesid) values (select file from table2,1,555) but that doesn't work. Is there a way where it will just insert a row for each unique file and also insert the static fields of 1 and 555 as separate columns?
Thanks!
Insert into #table2
(
file,
type,
partiesid,
...(other columns for which you need to give static values)
)
select
file,
type,
partiesid,
...(static values for columns)
from #table1
You can try the below query:
USE dbName
GO
INSERT INTO table2 (column_name(s))
SELECT column_name(s) FROM table1;
GO