Create a custom auto-increment field in SQL Server - sql

How can I have this input in the database like 15-001 where 15 is the last two digit of the year (based on datetimeNow) and 001 is my paper number?

You can keep two fields:
1. ID field - auto incremented on each record inserted
2. Varchar ID field - computed column
Try creating table like this:
CREATE TABLE PaperTable
(
PaperID int IDENTITY (1,1) NOT NULL
, PageNumber varchar(100)
, PaperAlphaID AS Cast(Right(Year(getDate()),2) as varchar(2)) +'-'+ PageNumber
);
Result I got when I added "001" and "002" in as my paper number:
PaperID PageNumber PaperAlphaID
------- ---------- ------------
1 001 15-001
2 002 15-002
You may use PaperID if you Paper number to be autogenerated. You will just then need to type cast and concate:
PaperAlphaID AS Cast(Right(Year(getDate()),2) as varchar(2)) +'-'+ Cast(PaperID as varchar(50))

Related

Query to combine value of another column value in insert command of same table

I'm really sorry if you don't understand my question, my english is not good .
kindly correct it if can
I create a table called 'Class'
create table class(
candidate_id int identity,
candidate_name varchar(50),
candidate_course varchar(15) default 'SQL Server');
I just want to insert only candidate_name column
Insert into class(Candidate_name)
values('User');
If I execute this command i'll get
Candidate_id
Candidate_name
Candidate_course
1
user
SQL Server
As, identity column will generate no.s so is it possible combine both with candidate_name while inserting .
Just like other languages Print("Hello world "+S) where s='Stack' output would be
Hello world Stack
Expecting output like this
Candidate_id
Candidate_name
Candidate_course
1
user1
SQL Server
2
user2
SQL Server
3
user3
SQL Server
nth
user nth
SQL Server
kindly help . Hope i'm clear
You can concatenate those 2 values simply using '+'.
Also, we need to convert the candidate_id to varchar, since it is integer.
Query
select candidate_id,
Candiate_name + cast(candidate_id as varchar(10)) as candidate_name,
Candidate_course
From class;
It is not possible to concatenate an identity with a user defined value provided in a raw insert statement. That being said there are a couple of things that you can do.
Define the table with a generated column.
You can actually define a column in your table that is generated from other columns.
create table class(
candidate_id int identity,
candidate_name varchar(50),
candidate_course varchar(15) default 'SQL Server',
candidate_name_id AS CONCAT(candidate_name, '_', candidate_id)
);
Insert into class(Candidate_name)
VALUES
('User'),
('User'),
('User');
SELECT *
FROM dbo.class AS c
This produces the following table.
candidate_id
candidate_name
candidate_course
candidate_name_id
1
User
SQL Server
User_1
2
User
SQL Server
User_2
3
User
SQL Server
User_3
For further reference on 'Computed Columns'
https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-ver16
Define The Table With A Sequence
Instead of using an identity you can use a sequence which gives you a lot more flexibility. You can generate the next value for the sequence and use it in your insert statements. I actually recommend this since you can generate the sequence before hand and use it in other parts of your code.
CREATE SEQUENCE SQ_class INCREMENT BY 1 START WITH 1 AS INT;
create table class(
candidate_id int DEFAULT NEXT VALUE FOR SQ_class,
candidate_name varchar(50),
candidate_course varchar(15) default 'SQL Server'
);
Insert into class(candidate_id, Candidate_name)
VALUES
(NEXT VALUE FOR SQ_class, CONCAT('User', '_', NEXT VALUE FOR SQ_class)),
(NEXT VALUE FOR SQ_class, CONCAT('User', '_', NEXT VALUE FOR SQ_class)),
(NEXT VALUE FOR SQ_class, CONCAT('User', '_', NEXT VALUE FOR SQ_class));
SELECT *
FROM dbo.class AS c
Which gives you the following result
candidate_id
candidate_name
candidate_course
1
User_1
SQL Server
2
User_2
SQL Server
3
User_3
SQL Server
in the same column you can achieve that, and as the other answer shows you can generate it on every sele as it is redundat, to have another column.
But you can make a generated column
MS SQL Server 2017 Schema Setup:
create table class(
candidate_id int identity,
candidate_name varchar(50),
fnew_candidate AS (candidate_name + cast(candidate_id as varchar(10))) PERSISTED,
candidate_course varchar(15) default 'SQL Server');
Insert into class(Candidate_name)
values('User');
SQL Fiddle
Query 1:
SELECT * FROM class
Results:
| candidate_id | candidate_name | fnew_candidate | candidate_course |
|--------------|----------------|----------------|------------------|
| 1 | User | User1 | SQL Server |
You may use a Trigger to update the inserted candidate_name automatically as the following:
CREATE TRIGGER ClassInsert ON Class
FOR INSERT AS
Begin
Update Class Set candidate_name = (candidate_name + Cast(candidate_id as nvarchar(5)))
Where candidate_id = (Select Max(candidate_id) From Class);
End
See a demo from db<>fiddle.

Generating name based on ID and current year using SQL Server

I am trying to generate value for the ProjektNummer (Name) column based on the value of the ID (primary key column.
So for example, when ID is 142, then the ProjektNummer should be 19142. 19 indicating the current year and 142 is the value of its ID.
Now, when the year changes, the id part in the value of the project name column needs to be restarted from zero while the actual ID should follow the identity and be incremented by 1 as usual.
So if the last record in the Year 2019 has ID=164, the first record in the year 2020 should be:
ID: 165 ProjektNummer: 20001
.. and the second record in year 2020 would be:
ID: 166 ProjektNummer: 20002
One way to achieve this is by creating a new view say 'vMaxLastId' and storing the max value of 'ID' for its corresponding year. This record will be used as a reference in another trigger.
So, if the first record in the year 2020 has ID: 165 Another trigger will subtract the value (164) for year 2019 (which is stored in the view), from the value of 'ID' after inserting a new record in 'table1' using the second trigger. (this should be done before inserting tho)
165-164=1
166-164=2
167-164=3
....
When the year will change from 2019 to 2020 the max id and year in 2020 will be added as a new record in the view. I have implemented this but there are multiple problems associated with this approach.
Kindly suggest me any possible way to solve this problem. I am willing to make any kind of change to the DB, query or trigger or the whole concept.
The first thought that crossed my mind would be to create a SEQUENCE object to generate the ID portion of the value. Since there are no fancy rules around the numbering, just this should do.
CREATE SEQUENCE dbo.ProjektID;
That will give you a bigint. To consume it, CONCAT that to the current year, and put your padding zeros onto the sequence value. You could set this as the default value for the column.
CONCAT( YEAR( GETDATE() ) % 100 , RIGHT( CONCAT('000', NEXT VALUE FOR dbo.ProjektID), 3))
Then schedule a job to run at midnight on the first of the year to restart the sequence.
ALTER SEQUENCE dbo.ProjektID
RESTART;
I think that would cover your requirements.
The most pragmatic solution I could think of is the use of a INSTEAD OF trigger on that specific main table.
My test table:
CREATE TABLE dbo.MyTestProject
(
id INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
, dateInserted DATETIME2(7) NOT NULL
, projectNumber INT NULL
);
And the example trigger:
CREATE TRIGGER dbo.triMyTestProject
ON dbo.MyTestProject
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE
#maxYear INT
, #maxNumber INT
, #startNumber INT
, #dateInserted DATETIME2;
SELECT
#dateInserted = dateInserted
FROM Inserted;
SET #startNumber = CAST(FORMAT(#dateInserted, 'yy') AS INT) * 1000 + 1;
SELECT
#maxNumber = MAX(projectNumber)
, #maxYear = ISNULL(MAX(YEAR(dateInserted)), YEAR(#dateInserted))
FROM dbo.MyTestProject;
INSERT INTO dbo.MyTestProject
(
dateInserted
, projectNumber
)
VALUES
(
#dateInserted, IIF(YEAR(#dateInserted) > #maxYear OR #maxNumber IS NULL, #startNumber, #maxNumber + 1)
);
END;
Add test data:
INSERT INTO dbo.MyTestProject (dateInserted) VALUES (SYSDATETIME());
INSERT INTO dbo.MyTestProject (dateInserted) VALUES (SYSDATETIME());
INSERT INTO dbo.MyTestProject (dateInserted) VALUES (SYSDATETIME());
INSERT INTO dbo.MyTestProject (dateInserted) VALUES ('20200102');
INSERT INTO dbo.MyTestProject (dateInserted) VALUES ('20200202');
Test result:
SELECT * FROM dbo.MyTestProject;
id dateInserted projectNumber
----------- --------------------------- -------------
1 2019-12-06 17:27:58.8813628 19001
2 2019-12-06 17:27:58.8833638 19002
3 2019-12-06 17:27:58.8883448 19003
4 2020-01-02 00:00:00.0000000 20001
5 2020-02-02 00:00:00.0000000 20002

How to create a deterministic uniqueidentifier (GUID) from an integer value

Note: This is not about database design nor about the general use of a GUID. This is about deterministically create such GUID's for test data, on a Microsoft SQL server.
We are migrating our database away from integer identifiers to the uniqueidentifier data type.
For test purposes we want to migrate our test data sets to known GUID values, deterministically based on our former integer values
UPDATE Unit
SET UnitGuid = NEWID(UnitId)
Obviously this does not work right away. How to use the UnitId to create a deterministic GUID?
You could create keymap table:
CREATE TABLE tab_map(id_old INT PRIMARY KEY, guid UNIQUEIDENTIFIER);
INSERT INTO tab_map(id_old, guid)
SELECT id, NEWID()
FROM src_table;
DBFiddle Demo
After that you could use simple query or wrap with a function:
SELECT guid
FROM tab_map
WHERE id_old = ?
Stop thinking about the problem from a "string" perspective. an int is made up of 4 bytes. A uniqueidentifier is made up of 16 bytes. you can easily take 12 fixed bytes and append the four bytes from an int to the end of those, and get a solution that works for all int values:
declare #Unit table
(
UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10),
IntegerId int
)
-- Add *3* data rows
INSERT INTO #Unit(Characters, IntegerId) VALUES ('abc', 1111),('def', 2222),('ghi',-17)
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE #GuidPrefix binary(12) = 0xefbeadde0000000000000000
UPDATE #Unit
SET UniqueColumn = CONVERT(uniqueidentifier,#GuidPrefix + CONVERT(binary(4),IntegerId))
-- Check the result
SELECT * FROM #Unit
Result:
UniqueColumn Characters IntegerId
------------------------------------ ---------- -----------
DEADBEEF-0000-0000-0000-000000000457 abc 1111
DEADBEEF-0000-0000-0000-0000000008AE def 2222
DEADBEEF-0000-0000-0000-0000FFFFFFEF ghi -17
(For various reasons, we have to provide the first four bytes in a different order than the one that is used by default when displaying a uniqueidentifier as a string, which is why if we want to display DEADBEEF, we had to start our binary as efbeadde)
Also, of course, insert usual warnings that if you're creating guids/uniqueidentifiers but not using one of the prescribed methods for generating them, then you cannot assume any of the usual guarantees about uniqueness.
I ended up solving this for myself. Here's my solution for future reference:
I create a prefix part of the GUID in the form of deadbeef-0000-0000-0000-, then append a "stringified", zero-padded version of the Id column's integer value to it, like 000000000001, wich results in
DEADBEEF-0000-0000-0000-000000000001
in this example.
Here's the SQL command for this action on a whole table:
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE #GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT #GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
Warnings:
This implementation works only for positive int values (which are up
to 2147483647 max)
This is only intended for test data! Use is
strongly discouraged for production data!
And here's a complete working example:
-- Create an example table with random GUID's
CREATE TABLE Unit
(
UniqueColumn UNIQUEIDENTIFIER DEFAULT NEWID(),
Characters VARCHAR(10),
IntegerId int
)
-- Add 2 data rows
INSERT INTO Unit(Characters, IntegerId) VALUES ('abc', 1111)
INSERT INTO Unit(Characters, IntegerId) VALUES ('def', 2222)
-- Deterministically creates a uniqueidentifier value out of an integer value.
DECLARE #GuidPrefix nvarchar(max) = N'deadbeef-0000-0000-0000-'; -- without the last 12 digits
UPDATE Unit
SET UniqueColumn =
(SELECT #GuidPrefix + RIGHT('000000000000' + CAST(IntegerId AS NVARCHAR (12)), 12 ) AS NUMBER_CONVERTED)
-- Check the result
SELECT * FROM Unit
Result:
UniqueColumn Characters IntegerId
--------------------------------------- ---------- ---------
DEADBEEF-0000-0000-0000-000000001111 abc 1111
DEADBEEF-0000-0000-0000-000000002222 def 2222

How to create custom, dynamic string sequence in SQL Server

Is there any way to dynamically build sequences containing dates/strings/numbers in SQL Server?
In my application, I want every order to have a unique identificator that is a sequence of: Type of order, Year, Month, Incrementing number
(ex: NO/2016/10/001, NO/2016/10/002)
where NO = "Normal order", 2016 is a year, 10 is a month and 001 is an incrementing number. The idea is that it is easier for employees to comunicate using these types of identificators (of course this sequence would not be primary key of database table)
I know that I could create a stored procedure that would take Order type as an argument and return the sequence, but I'm curious if there is any better way to do it.
Cheers!
An IDENTITY column might have gaps. Just imagine an insert which is rollbacked out of any reason...
You could use ROW_NUMBER() OVER(PARTITION BY CONVERT(VARCHAR(6),OrderDate,112) ORDER BY OrderDate) in order to start a sorted numbering starting with 1 for each month. What will be best is depending on the following question: Are there parallel insert operations?
As this order name should be unique, you might run into unique-key-violations where you'd need complex mechanisms to work around...
If it is possible for you to use the existing ID you might use a scalar function together with a computed column (might be declared persistant):
CREATE TABLE OrderType(ID INT,Name VARCHAR(100),Abbr VARCHAR(2));
INSERT INTO OrderType VALUES(1,'Normal Order','NO')
,(2,'Special Order','SO');
GO
CREATE FUNCTION dbo.OrderCaption(#OrderTypeID INT,#OrderDate DATETIME,#OrderID INT)
RETURNS VARCHAR(100)
AS
BEGIN
RETURN ISNULL((SELECT Abbr FROM OrderType WHERE ID=#OrderTypeID),'#NA')
+ '/' + CAST(YEAR(#OrderDate) AS VARCHAR(4))
+ '/' + REPLACE(STR(MONTH(#OrderDate),2),' ','0')
+ '/' + REPLACE(STR(#OrderID,5),' ','0')
END
GO
CREATE TABLE YourOrder
(
ID INT IDENTITY
,OrderDate DATETIME DEFAULT(GETDATE())
,OrderTypeID INT NOT NULL --foreign key...
,Caption AS dbo.OrderCaption(OrderTypeID,OrderDate,ID)
);
GO
INSERT INTO YourOrder(OrderDate,OrderTypeID)
VALUES({ts'2016-01-01 23:23:00'},1)
,({ts'2016-02-02 12:12:00'},2)
,(GETDATE(),1);
GO
SELECT * FROM YourOrder
The result
ID OrderDate OrderTypeID Caption
1 2016-01-01 23:23:00.000 1 NO/2016/01/00001
2 2016-02-02 12:12:00.000 2 SO/2016/02/00002
3 2016-10-23 23:16:23.990 1 NO/2016/10/00003
You could create a computed column in your table definition which concatenates other values in your database into the kind of Identifier you're looking for.
Try this for a simplified example:-
CREATE TABLE Things (
[Type of Order] varchar(10),
[Year] int,
[Month] int,
[Inc Number] int identity(1,1),
[Identifier] as [Type of Order] + '/' + cast([Year] as varchar) + '/' + cast([Month] as varchar) + '/' + cast([Inc Number] as varchar)
)
insert into Things
values
('NO',2016,10)
select * from Things
If you wanted to do something more complex you could always use a trigger to update the column post insert or update.

Incrementing custom primary key values in SQL

I am asked to generate custom ID values for primary key columns. The query is as follows,
SELECT * FROM SC_TD_GoodsInward WHERE EntityId = #EntityId
SELECT #GoodsInwardId=IIF((SELECT COUNT(*) FROM SC_TD_GoodsInward)>0, (Select 'GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'+CONVERT(varchar,#EntityId)+'_'+(SELECT RIGHT('0000'+CONVERT(VARCHAR,CONVERT(INT,RIGHT(MAX(GoodsInwardId),4))+1),4) from SC_TD_GoodsInward)), (SELECT 'GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'+CONVERT(varchar,#EntityId)+'_0001'))
Here the SC_TD_GoodsInward is a table, GoodsInwardId is the value to be generated. I am getting the desired outputs too. Examples.
GI_131118_1_0001
GI_131212_1_0002
GI_131212_1_0003
But, the above condition fails when the last digits reach 9999. I simulated the query and the results were,
GI_131226_1_9997
GI_140102_1_9998
GI_140102_1_9999
GI_140102_1_0000
GI_140102_1_0000
GI_140102_1_0000
GI_140102_1_0000
GI_140102_1_0000
After 9999, it goes to 0000 and does not increment thereafter. So, in the future, I will eventually run into a PK duplicate error. How can i recycle the values so that after 9999, it goes on as 0000, 0001 ... etc. What am I missing in the above query?
NOTE: Please consider the #EntityId value to be 1 in the query.
I am using SQL SERVER 2012.
Before giving a solution for the question few points on your question:
As the Custom primary key consists of mainly three parts Date(140102), physical location where transaction takes place (entityID), 4 place number(9999).
According to the design on a single date in a single physical location there cannot be more than 9999 transactions -- My Solution will also contain the same limitation.
Some points on my solution
The 4 place digit is tied up to the date which means for a new date the count starts from 0000. For Example
GI_140102_1_0001,
GI_140102_1_0002,
GI_140102_1_0003,
GI_140103_1_0000,
GI_140104_1_0000
Any way the this field will be unique.
The solution compares the latest date in the record to the current date.
The Logic:
If current date and latest date in the record matches
Then it increments 4 place digit by the value by 1
If the current date and the latest date in the record does not matched
The it sets the 4 place digit by the value 0000.
The Solution: (Below code gives out the value which will be the next GoodsInwardId, Use it as per requirement to fit in to your solution)
declare #previous nvarchar(30);
declare #today nvarchar(30);
declare #newID nvarchar(30);
select #previous=substring(max(GoodsInwardId),4,6) from SC_TD_GoodsInward;
Select #today=RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)
+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2);
if #previous=#today
BEGIN
Select #newID='GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)
+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)
+'_'+CONVERT(varchar,1)+'_'+(SELECT RIGHT('0000'+
CONVERT(VARCHAR,CONVERT(INT,RIGHT(MAX(GoodsInwardId),4))+1),4)
from SC_TD_GoodsInward);
END
else
BEGIN
SET #newID='GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)
+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)
+'_'+CONVERT(varchar,1)+'_0000';
END
select #newID;
T-SQL to create the required structure (Probable Guess)
For the table:
CREATE TABLE [dbo].[SC_TD_GoodsInward](
[EntityId] [int] NULL,
[GoodsInwardId] [nvarchar](30) NULL
)
Sample records for the table:
insert into dbo.SC_TD_GoodsInward values(1,'GI_140102_1_0000');
insert into dbo.SC_TD_GoodsInward values(1,'GI_140101_1_9999');
insert into dbo.SC_TD_GoodsInward values(1,'GI_140101_1_0001');
**Its a probable solution in your situation although the perfect solution would be to have identity column (use reseed if required) and tie it with the current date as a computed column.
You get this problem because once the last 4 digits reach 9999, 9999 will remain the highest number no matter how many rows are inserted, and you are throwing away the most significant digit(s).
I would remodel this to track the last used INT portion value of GoodsInwardId in a separate counter table (as an INTEGER), and then MODULUS (%) this by 10000 if need be. If there are concurrent calls to the PK generator, remember to lock the counter table row.
Also, even if you kept all the digits (e.g. in another field), note that ordering a CHAR is as follows
1
11
2
22
3
and then applying MAX() will return 3, not 22.
Edit - Clarification of counter table alternative
The counter table would look something like this:
CREATE TABLE PK_Counters
(
TableName NVARCHAR(100) PRIMARY KEY,
LastValue INT
);
(Your #EntityID might be another candidate for the counter PK column.)
You then increment and fetch the applicable counter on each call to your custom PK Key generation PROC:
UPDATE PK_Counters
SET LastValue = LastValue + 1
WHERE TableName = 'SC_TD_GoodsInward';
Select
'GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)
+RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)
+RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'
+CONVERT(varchar,#EntityId)+'_'
+(SELECT RIGHT('0000'+ CONVERT(NVARCHAR, LastValue % 10000),4)
FROM PK_Counters
WHERE TableName = 'SC_TD_GoodsInward');
You could also modulo the LastValue in the counter table (and not in the query), although I believe there is more information about the number of records inserted by leaving the counter un-modulo-ed.
Fiddle here
Re : Performance - Selecting a single integer value from a small table by its PK and then applying modulo will be significantly quicker than selecting MAX from a SUBSTRING (which would almost certainly be a scan)
DECLARE #entityid INT = 1;
SELECT ('GI_'
+ SUBSTRING(convert(varchar, getdate(), 112),3,6) -- yymmdd today DATE
+ '_' + CAST(#entityid AS VARCHAR(50)) + '_' --#entity parameter
+ CASE MAX(t.GI_id + 1) --take last number + 1
WHEN 10000 THEN
'0000' --reset
ELSE
RIGHT( CAST('0000' AS VARCHAR(4)) +
CAST(MAX(t.GI_id + 1) AS VARCHAR(4))
, 4)
END) PK
FROM
(
SELECT TOP 1
CAST(SUBSTRING(GoodsInwardId,11,1) AS INT) AS GI_entity,
CAST(SUBSTRING(GoodsInwardId,4,6) AS INT) AS GI_date,
CAST(RIGHT(GoodsInwardId,4) AS INT) AS GI_id
FROM SC_TD_GoodsInward
WHERE CAST(SUBSTRING(GoodsInwardId,11,1) AS INT) = #entityid
ORDER BY gi_date DESC, rowTimestamp DESC, gi_id DESC
) AS t
This should take the last GoodInwardId record, ordered by date DESC and take its numeric "id". Then add + 1 to return the NEW id and combine it with today's date and the #entityid you passed. If >9999, start again from 0000.
You need a timestamp type column tho, to order two inserted in the same date + same transaction time. Otherwise you could get duplicates.
I have simplified the answer even more and arrived with the following query.
IF (SELECT COUNT(GoodsInwardId) FROM SC_TD_GoodsInward WHERE EntityId = #EntityId)=0
BEGIN
SELECT #GoodsInwardId= 'GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'+
CONVERT(varchar,#EntityId)+'_0001'
END
ELSE
BEGIN
SELECT * FROM SC_TD_GoodsInward WHERE EntityId = #EntityId AND CONVERT(varchar,CreatedOn,103) = CONVERT(varchar,GETDATE(),103)
SELECT #GoodsInwardId=IIF(##ROWCOUNT>0,
(Select 'GI_'+
RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'+
CONVERT(varchar,#EntityId)+'_'+
(SELECT RIGHT('0000'+CONVERT(VARCHAR,CONVERT(INT,RIGHT(MAX(GoodsInwardId),4))+1),4) from SC_TD_GoodsInward WHERE CONVERT(varchar,CreatedOn,103) = CONVERT(varchar,GETDATE(),103))),
(SELECT 'GI_'+RIGHT('00'+CONVERT(varchar,datepart(YY,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(MM,getdate())),2)+
RIGHT('00'+CONVERT(varchar,datepart(DD,getdate())),2)+'_'+
CONVERT(varchar,#EntityId)+'_0001'))
END
select * from SC_TD_GoodsInward