This question already has answers here:
Set a custom identity value on a auto increment field
(2 answers)
Closed 9 years ago.
I have created a table and with a primary key called OrderNo.
However, I want the OrderNo be auto increment as well.
How can I do in the following format?
"ABC201320001", "ABC201320002", "ABC201320003", ............ etc.
Here ABC is My Company Name(Default),
2013 is Current Year,
2 is the age of my Company
and 0001 is the Document No(Running Number)
Here the auto increment(ABC0001,ABC0002,...) is working good... but the problem is how to get current year(2013,..) and age of my company(2,..) increments based on the current year changes to next year.
Is there a way I can do this in SQL Server?
Use an IDENTITY and a computed column
CREATE TABLE Tablename (
ID int NOT NULL IDENTITY (1, 1),
...
...
/*gives 000-999. Change the RIGHT as needed to give more*/
PIC_ID AS 'PIC' + RIGHT('000000000' + CAST(ID as varchar(10)), 3)
CONSTRAINT PK_name PRIMARY KEY CLUSTERED (PIC_ID)
)
You can change the RIGHT to cover as many digits as needed, or you may not want leading zeroes:
PIC_ID AS 'PIC' + CAST(ID as varchar(10))
In your case it would look like this:
create table tablename
(
ID int identity (0000, 1),
PIC_ID as 'PIC'+right('0000'+cast(ID as varchar(5)), 5) persisted,
constraint PK_tablename primary key (ID)
)
Related
I have an SQLite database for an art exhibition. In the table "exhibits" I have columns for the artwork ID, the exhibition space ID, a begin date, and an end date. The default value for "end date" is NULL.
Of course, the same artwork cannot be displayed in two different spaces at once. So I want to ensure that a new row with an artwork ID is not created unless all existing rows with that same artwork ID have a non-null end date.
Is there some kind of constraint, trigger, etc. that I can add to the table to ensure this?
I am not an expert on writing triggers for SQLite but something like this should work,
CREATE TRIGGER check_open_ended_exhibit BEFORE INSERT ON exhibits
BEGIN
SELECT RAISE(ABORT, "Open ended exhibit exists")
WHERE EXISTS(SELECT * FROM exhibits WHERE artworkID = NEW.artworkID AND enddate IS NULL);
END
According to your information “Artwork” cannot be displayed twice in the same show which means the EndTime is a unique field when constraining it together with Artwork. So by making these two together your constrain you won’t be able to insert a record if you already have “artwork and NULL”.
So yeah you can just create a unique constrain on these two columns.
CREATE TABLE testConstrain (
id INTEGER NOT NULL,
endDate DATETIME
)
CREATE UNIQUE INDEX testConstrain
ON testConstrain(id, endDate);
INSERT INTO testConstrain VALUES('1',null)
INSERT INTO testConstrain VALUES('2','01-01-2018')
INSERT INTO testConstrain VALUES('1','01-01-2018')
INSERT INTO testConstrain VALUES('1',null)
`
And you will get:
Started executing query at Line 11
(1 row affected)
(1 row affected)
(1 row affected)
Msg 2601, Level 14, State 1, Line 4
Cannot insert duplicate key row in object 'bginsburg.testConstrain' with unique index 'testConstrain'. The duplicate key value is (1, ).
The statement has been terminated.
I have a table which has one primary key integer:
CREATE TABLE TBL (ID INTEGER PRIMARYKEY,ZID INTEGER)
That zid integer field that must be incremented from the previous one found in the database.
I could do something like that:
INSERT INTO TBL (zid) VALUES ((SELECT MAX(zid) + 1 FROM TBL));
However, the value of that integer field will, at some point, reset to zero. Therefore I want to increment from the last entry, not necessarily the maximum in the entire table.
How can I do that? A trigger?
Thanks.
how about a query like:
SELECT zid + 1 FROM TBL ORDER BY id DESC LIMIT 1
with this select query you will only get the value from the last line (+1)
I would like to automatically insert a primary key every time I add a new record to an SQLite3 table, much like a PRIMARY KEY AUTOINCREMENT except that the value should be randomly chosen from some range (say 0000 through 9999) rather than being assigned sequentially.
For demonstration purposes, let's restrict the range to 1 through 6 instead and try to populate the following table:
CREATE TABLE dice (rolled INTEGER PRIMARY KEY NOT NULL);
Now every time I insert a new record into that table, I want a new random primary key to be created.
The following works and does exactly what I want
INSERT INTO dice VALUES(
(
WITH RECURSIVE roll(x) AS (
VALUES(ABS(RANDOM()) % 6 + 1)
UNION ALL
SELECT x % 6 + 1 FROM roll
)
SELECT x FROM roll WHERE (
SELECT COUNT(*) FROM dice where rolled = x
) = 0 LIMIT 1
)
);
except that I have to invoke it manually/explicitly.
Is there any way to embed the above (or an equivalent) calculation for the random primary key into a DEFAULT clause for the "rolled" column or into some sort of trigger, so that a new key will be calculated automatically every time I insert a record?
I want to design a database system (I use SQLite)and in a table where I keep the history, I store some values of an employee (name,surname, id, etc..) One of the fields are some working positions which currently are 3, but in the future may increased to 4 or 5... Which is is more clever to do?
1) Have a table with all the fields (among them: wp1, wp2, wp3) and later add a column for the wp3, or
2) Store all these working positions to a diferrent table where i will have 2 fields id and wp and store the diferrent wp to multiple records?
Is a 'working position' a job title? A record of employment at a previous company?
1 is a bad idea.
You probably want something like this:
create table employees (
id int primary key,
name text not null
);
create table working_positions (
id int primary key,
employee_id int not null references employees(id), /* foreign key to employees table */
...other attributes of a working position...
);
I am saving documents to database, each document has to have an id with the format YYYY-00000:
the first 4 characters are the current year
the second five characters are numbers. They start with 1 each year and then increment.
For example I could have these documents in my database: 2011-00001, 2011-00002, 2011-00003, 2012-00001, 2012-00002, ...
I am thinking something like this:
add two columns to table Documents (Year and Number)
Year is computed column, something like year(getdate())
Number is computed column, which gets value from a function GetNextNumberForCurrentYear
GetNextNumberForCurrentYear returns next number for the current year (for example select max(Number) + 1 from Documents where Year = year(getdate()), and some isnull checking)
But i fear, that two users could want to save the document at the same time and that they would receive the same Number. Is this possible? Any better ideas?
It is a ASP.NET C# web application, .NET 4.0, MSSQL 2005, I have the control over all the parts of the application.
PS: after insert I would like to return the Id of the new document to the user, so I would probably have to do something like: select Id from Documents where SomeId = scope_identity(), so I guess there should be an identity column somewhere...?
Edit (final solution): I get the next number from stored procedure, build the Id of the document (in format YYYY-00001) in .NET, save the whole document to the database (using TransactionScope for whole process) and then return the Id to the user.
create table DocumentNumbers ([Year] int not null, Number int not null default 1)
insert into DocumentNumbers ([Year], Number)
select 2012, 1 -- and more...
create procedure GetNextDocumentNumber
#year int
as
begin
declare #myResult table (nextNumber int)
update DocumentNumbers
set Number = isnull(Number, 0) + 1
output inserted.Number into #myResult
where [Year] = #year
select top 1 nextNumber from #myResult
end
You could create a table NumberSeries, which contains a column Year and a column CurrentNo and a function that returns the next number from it like the following:
DECLARE #myResult TABLE (nextNumber INT)
UPDATE NumberSeries
OUTPUT INSERTED.NextNo INTO #myResult
SET
CurrentNo = ISNULL(CurrentNo, 0) + 1
WHERE
Year = Year(GetDate())
DECLARE #result INT
#result = (SELECT TOP 1 nextNumber FROM #myResult)
RETURN #result
This updates the NumberSeries table atomically and inserts the new value into the #myResult table variable. After that, it returns the first (and only) value from the #myResult table variable.
Everything else, like SCOPE_IDENTITY() and such may cause errors when using triggers or in other cases - the solution using the OUTPUT clause is safe.
EDIT
As for returning the ID of the inserted document: this is basically the same thing.
DECLARE #myDocId TABLE (yr int, no int)
INSERT INTO Documents
OUTPUT INSERTED.Year , INSERTED.YearID INTO #myDocID
...
SELECT TOP 1
CAST(yr AS NVARCHAR) +
'_' +
RIGHT(REPLICATE('0', 5) + CAST(no AS NVARCHAR), 5) AS NewID