i got a function in sql that generate sequential series of alphanumeric
no.like (c000,c0001 .......) , which is working good . but when i deleted all data in table , it starts from last generated no. i want it to reset its value from "c0000" .
code is as follows :-
create table Customers
(
dbID int identity not null primary key,
CustomerName varchar(100)
)
create function CustomerNumber (#id int)
returns char(5)
as
begin
return 'C' + right('0000' + convert(varchar(10), #id), 4)
end
alter table Customers add CustomerNumber as dbo.CustomerNumber(dbID)
thanks in advance....
EDIT 1 -
how to update it to increment based on last value . means if last entry having no. c0053 , and i deleted this record , so when next entry added it should have value "C0053" not "C0054".
thanks
Truncate Table Command is good way to reset Identity, but there is other command also to reset Identity after deletion of records.
DBCC CHECKIDENT (TableName, RESEED, 0)
After Deleting you can use this command to reset Identity to 0.
TRUNCATE TABLE
Removes all rows from a table or specified partitions of a table, without logging the individual row deletions. TRUNCATE TABLE is similar to the DELETE statement with no WHERE clause; however, TRUNCATE TABLE is faster and uses fewer system and transaction log resources.
TRUNCATE TABLE Customers
or remove your in build function.
My suggestion is instead of deleting all rows of data why dont you truncate the table.
If you are truncate the table it automatically reset your auto increment to 0
TRUNCATE TABLE your_table_name;
This example would truncate the table and remove all records from that table. and rest your auto increment too.
The SQL TRUNCATE TABLE command is used to delete complete data from an existing table
Try this way. May help you.
Related
After deleting the duplicate records from the table,
I want to update Identity column of a table with consecutive numbering starting with 1. Here is my table details
id(identity(1,1)),
EmployeeID(int),
Punch_Time(datetime),
Deviceid(int)
I need to perform this action through a stored procedure.
When i tried following statement in stored procedure
DECLARE #myVar int
SET #myVar = 0
set identity_insert TempTrans_Raw# ON
UPDATE TempTrans_Raw# SET #myvar = Id = #myVar + 1
set identity_insert TempTrans_Raw# off
gave error like...Cannot update identity column 'Id'
Anyone please suggest how to update Identity column of that table with consecutive numbering starting with 1.
--before running this make sure Foreign key constraints have been removed that reference the ID.
--insert everything into a temp table
SELECT (ColumnList) --except identity column
INTO #tmpYourTable
FROM yourTable
--clear your table
DELETE FROM yourTable
-- reseed identity
DBCC CHECKIDENT('table', RESEED, new reseed value)
--insert back all the values
INSERT INTO yourTable (ColumnList)
SELECT OtherCols FROM #tmpYourTable
--drop the temp table
DROP TABLE #tmpYourTable
GO
The IDENTITY keword is used to generate a key which can be used in combination with the PRIMARY KEY constraint to get a technical key. Such keys are technical, they are used to link table records. They should have no other meaning (such as a sort order). SQL Server does not guarantee the generated IDs to be consecutive. They do guarantee however that you get them in order. (So you might get 1, 2, 4, ..., but never 1, 4, 2, ...)
Here is the documentation for IDENTITY: https://msdn.microsoft.com/de-de/library/ms186775.aspx.
Personally I don't like it to be guaranteed that the generated IDs are in order. A technical ID is supposed to have no meaning other then offering a reference to a record. You can rely on the order, but if order is information you are interested in, you should store that information in my opinion (in form of a timestamp for example).
If you want to have a number telling you that a record is the fifth or sixteenth or whatever record in order, you can get always get that number on the fly using the ROW_NUMBER function. So there is no need to generate and store such consecutive value (which could also be quite troublesome when it comes to concurrent transactions on the table). Here is how to get that number:
select
row_number() over(order by id),
employeeid,
punch_time,
deviceid
from mytable;
Having said all this; it should never be necessary to change an ID. It is a sign for inappropriate table design, if you feel that need.
If you really need sequential numbers, may I suggest that you create a table ("OrderNumbers") with valid numbers, and then make you program pick one row from OrderNumbers when you add a row to yourTable.
If you everything in one transaction (i.e. with Begin Tran and Commit) then you can get one number for one row with no gabs.
You should have either Primary Keys or Unique Keys on both tables on this column to protect against duplicates.
HIH,
Henrik
Check this function: DBCC CHECKIDENT('table', RESEED, new reseed value)
Okay first a little bit of background, I've inherited maintaining a Database on MSSQL 2000.
In the Database there's a massive collection of interconnected tables, through Foreign keys.
What I'm attempting to do is to rebuild each table in a sorted fashion that will eliminate gaps in the IDENT column of the table.
On one table in particular I have the following columns:
RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue
It uses RL_ID as the IDENT column which currently reports 32620 by using DBCC CHECKIDENT (Table)
There is, however, only 12128 rows of information in this table.
So I tried a simple script to copy all the information in a sorted fashion into a new table:
INSERT INTO Table_1
SELECT RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue
FROM RaidLoot
ORDER BY RL_ID
Then Delete all the rows from the source table with:
TRUNCATE TABLE (RaidLoot)
Verify the IDENT is 1 with:
DBCC CHECKIDENT (RaidLoot)
Now copy the Data back into the Original table from Row 1 to the end:
SET IDENTITY_INSERT RaidLoot ON
INSERT INTO RaidLoot (RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue)
SELECT RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue
FROM Table_1
ORDER BY RL_ID
SET IDENTITY_INSERT RaidLoot OFF
Now verify that I only have the 12128 rows of data:
DBCC CHECKIDENT (RaidLoot)
(Note: I end up with 32620 again since it never did renumber the RL_ID, it just put them back into the same spots leaving the gaps). So where / how can I get it to Renumber the RL_ID column starting from 1 so that when it writes the data back to the original table I don't have the gaps?
The only other solution I can see is a heartache process of Manually changing each row RL_ID in the Table_1 before I write it back to the Original table. While this isn't impossible. I have another table that has approx 306,000 rows of data, but the IDENT report lists out as 450,123, so I'm hoping there is an easier way to automate the renumbering process.
If you really have to do this (seems like a great waste of time to me), you will have to adjust all of the foreign key references as well.
Consider the strategy of adding a NewID column for each table and populate the new column sequentially. Then you can use this NewID column in the queries needed to adjust the foreign keys. Very messy nonetheless unless you can come up with a consistent pattern to do so.
Since you can query the metadata to determine foreign keys, etc. this is certainly possible, and definitely should be considered seriously if you really do have lots of tables.
ADDED
There is a simple way to populate the NewID column
declare #id int
set #id = 0
update MyTable set NewID=#id, #id=#id+1
It is not obvious that this works, but it does.
I don't think it has to do with RL_ID being referenced by other tables in the schema - if I set up a single table test, the identity will always show up as the max number in the identity field:
CREATE TABLE #temp (id INT IDENTITY(1,1), other VARCHAR(1))
INSERT INTO #temp
( other )
VALUES ( -- id - int
'a' -- other - varchar(1)
),('b'),('c'),('d'),('e')
SELECT *
FROM #temp
SELECT *
INTO #holder
FROM #temp
WHERE other = 'C'
TRUNCATE TABLE #temp
SET IDENTITY_INSERT #temp ON
INSERT INTO #temp
( id, other )
SELECT id ,
other
FROM #holder
DBCC CHECKIDENT (#temp)
DROP TABLE #temp
DROP TABLE #holder
So your new identity is 32620 because that is the MAX(RL_ID)
I ran a delete script to delete all rows that had an id greater than 0 to clear the table and now when I try to add rows to the table, the id starts off where it left off from before. How can I delete the info in the table so the id starts off at 1 again?
Delete statement doesnt reset the identity value. Use Truncate table command if you want identity value to be reset. something like this..
TRUNCATE TABLE Table_Name
This will empty the table and reset the identity value.
Only use TRUNCATE when you want all the rows to be deleted. As it does not allow you to use WHERE clause.
I don't think that is possible in the same table. Which database are you using? In previous versions of MS Access compacting the database used to work but not any more. I don't think SQL Server allows that either. The only way is to copy the records from this table to a new table, delete the old table and rename the new table to the old table name.
In MS-SQL you can have a play with DBCC CHECKIDENT (yourtable, reseed, 0)
I want to delete new record if the same record created before.
My columns are date, time and MsgLog. If date and time are same, I want to delete new one.
I need help .
You can check in the table whether that value exists or not in the column using a query. If it exists, you can show message that a record already exists.
To prevent such kind of erroneous additions you can add restriction to your table to ensure unique #Date #Time pairs; if you don't want to change data structure (e.g. you want to add records with such restrictions once or twice) you can exploit insert select counstruction.
-- MS SQL version, check your DBMS
insert into MyTable(
Date,
Time,
MsgLog)
select #Date,
#Time,
#MsgLog
where not exists(
select 1
from MyTable
where (#Date = Date) and
(#Time = Time)
)
P.S. want to delete new one equals to do not insert new one
You should create a unique constraint in the DB level to avoid invalid data no matter who writes to your DB.
It's always important to have your schema well defined. That way you're safe that no matter how many apps are using your DB or even in case someone just writes some inserts manually.
I don't know which DB are you using but in MySQL can use to following DDL
alter table MY_TABLE add unique index(date, time);
And in Oracle you can :
alter table MY_TABLE ADD CONSTRAINT constaint_name UNIQUE (date, time);
That said, you can also (not instead of) do some checks before inserting new values to avoid dealing with exceptions or to improve performance by avoiding making unnecessary access to your DB (length \ nulls for example could easily be dealt with in the application level).
You can avoid deleting by checking for duplicate while inserting.
Just modify your insert procedure like this, so no duplicates will entered.
declare #intCount as int;
select #intCount =count(MsgLog) where (date=#date) and (time =#time )
if #intCount=0
begin
'insert procedure
end
> Edited
since what you wanted is you need to delete the duplicate entries after your bulk insert. Think about this logic,
create a temporary table
Insert LogId,date,time from your table to the temp table order by date,time
now declare four variables, #preTime,#PreDate,#CurrTime,#CurrDate
Loop for each items in temp table, like this
while
begin
#pkLogID= ' Get LogID for the current row
select #currTime=time,#currDate=date from tblTemp where pkLogId=#pkLogID 'Assign Current values
'Delete condition check
if (#currDate=#preDate) and (#currTime=#preTime)
begin
delete from MAINTABLE where pkLogId=#pkLogID
end
select #preDate=#currDate,#preTime=#currTime 'Assign current values as preValues for next entries
end
The above strategy is we sorted all entries according to date and time, so duplicates will come closer, and we started to compare each entry with its previous, when match found we deleting the duplicate entry.
hey all. I have a table in my DB that has about a thousand records in it. I would like to reset the identity column so that all of the ID's are sequential again. I was looking at this but I'm ASSuming that it only works on an empty table
Current Table
ID | Name
1 Joe
2 Phil
5 Jan
88 Rob
Desired Table
ID | Name
1 Joe
2 Phil
3 Jan
4 Rob
Thanks in advance
The easiest way would be to make a copy of the current table, fix up any parentid issues, drop it and then rename the new one.
You could also temporarily remove the IDENTITY and try the folowing:
;WITH TBL AS
(
SELECT *, ROW_NUMBER(ORDER BY ID) AS RN
FROM CURRENT_TABLE
)
UPDATE TBL
SET ID = RN
Or, if you don't care about the order of the records, this
DECLARE INT #id;
SET #id = 0;
UPDATE CURRENT_TABLE
SET #id = ID = #id + 1;
one way, wrap this in a transaction
select id,name into #temp from YourTable
truncate table YourTable
insert YourTable (name)
select name from #temp
Quick solution would be to:
create a new table with the same schema
copy the old table to the new one (except for the identity column)
delete the old table
rename the new table
Because you have foreign keys in the same table (per your comment), you will need to preserve the mapping from old to new somewhere and re-instate the foreign keys to match the new identities.
There are a number of approaches for doing this, but I would strongly question the need to update your primary keys, especially since you already have foreign keys referencing them, and it's just a surrogate key. It's not like you are changing your surrogate key to a GUID or something special.
Here's how I reset identity fields. The CTE (Common Table Expression) above version is overkill. Just use the current Row Number to update the identity column using a simple update statement with a join:
UPDATE [YourTable] SET ID = rn.RowNumber FROM [YourTable]
JOIN (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber
FROM [YourTable]) rn ON rn.ID = [YourTable].ID
This statement may be refactored to be even simpler. If so, I would love to see the simpler version.
I hope this helps someone.
Use DBCC CHECKIDENT. the table doesn't need to be empty:
DBCC CHECKIDENT ( table_name, NORESEED)
Current identity value is not reset.
DBCC CHECKIDENT returns the current
identity value and the current maximum
value of the identity column. If the
two values are not the same, you
should reset the identity value to
avoid potential errors or gaps in the
sequence of values.
DBCC CHECKIDENT ( table_name ) or DBCC CHECKIDENT ( table_name, RESEED )
If the current identity value for a
table is less than the maximum
identity value stored in the identity
column, it is reset using the maximum
value in the identity column.
DBCC CHECKIDENT ( table_name, RESEED, new_reseed_value )
Current identity value is set to the
new_reseed_value. If no rows have been
inserted into the table since the
table was created, or if all rows have
been removed by using the TRUNCATE
TABLE statement, the first row
inserted after you run DBCC CHECKIDENT
uses new_reseed_value as the identity.
Otherwise, the next row inserted uses
new_reseed_value + the current
increment value.
If the table is not empty, setting the
identity value to a number less than
the maximum value in the identity
column can result in one of the
following conditions:
If a PRIMARY KEY or UNIQUE constraint exists on the identity
column, error message 2627 will be
generated on later insert operations
into the table because the generated
identity value will conflict with
existing values.
If a PRIMARY KEY or UNIQUE constraint does not exist, later
insert operations will result in
duplicate identity values.