I have table in my SQL Server database with following columns
ID | NAME | DOB | APPLICATION NO |
1 | JOHN | 31/05/1986 | KPL\2014\1 |
2 | MARY | 26/04/1965 | KPL\2014\2 |
3 | VARUN | 15/03/1972 | KPL\2014\3 |
Here column ID is an auto increment column and column APPLICATION NO is dependent on ID.
That means APPLICATION NO is the concatenation of KPL\, YEAR and column value of ID.
Then how can I make an insert query?
Why don't you use a computed column ?
I would change the table's definition.
add a "year" column
add an "application_name" column (if it's not always "KPL").
then create your computed column, with the needed fields
alter table <yourTable> add computed_application_name as (application_name + '/' + CAST(<yearColumn> as VARCHAR(4) + '/' + <otherColumn> + CAST(id as VARCHAR(MAX))
Just use a computed column:
alter table t
add application_no as ('KPL' + cast(year(getdate()) as varchar(255)) + cast(id as varchar(255));
It occurs to me that you really want the year when the row was inserted. For that purpose, I would recommend adding a createdat column and then using that instead of getdate():
alter table t add CreatedAt datetime default getdate();
If you have data in the table, then set the value (this is not needed if the table is empty):
update table t set CreatedAt = getdate();
Then define application_no:
alter table t
add application_no as ('KPL' + cast(year(CreatedAt) as varchar(255)) + cast(id as varchar(255));
Simply use a computed column for 'APPLICATION_NO':
create table tbl (
ID int,
NAME varchar(10),
DOB date,
APPLICATION_NO as ('KPL\'+cast(year(dob) as char(4))+'\'+cast(id as varchar))
)
You can further persist and index it as well.
You can create a trigger to run after insert. In your insert, ignore application_no. And your trigger update this column based on ID.
Something like this:
CREATE TRIGGER [TRIGGER_TABLE1] ON TABLE1
AFTER INSERT
AS
BEGIN
UPDATE TABLE1
SET APPLICATION_NO = 'KPL\' + CONVERT(VARCHAR, YEAR(GETDATE())) + '\' + CONVERT(VARCHAR, ID)
WHERE APPLICATION_NO IS NULL
END
EDIT: This way, you should be able to use other columns values as well. APPLICATION_NO just need to accept NULL values. So you control like this what will be updated or not.
Use SCOPE_IDENTITY get the inserted record Id
Declare #Id INT
Insert Into TABLENAME(NAME ,DOB )
Values('Name','1/1/1990')
Set #Id=SCOPE_IDENTITY()
IF(#Id>0)
begin
declare #col varchar(100)=''
set #col= 'KPL\' + CONVERT(varchar(4),YEAR(GETDATE()))+'\' + CONVERT(varchar(4),#Id)
Update TABLENAME
SET APPLICATIONNO= #col
Where ID = #id
end
If you really want to do it by yourself with an insert statement:
assuming that you want to insert data from another table
and TABLE1 is the table you described in your question and TABLE2 would be the table you want to import data from:
DECLARE #MAXID INT
SELECT #MAXID = MAX(ID) FROM TABLE1
INSERT INTO TABLE1
(NAME,DOB,APPLICATION_NO)
SELECT
NAME,
DOB,
'KPL\'
+ CONVERT(CHAR(4),YEAR(GETDATE()) +'\'
+ CONVERT(VARCHAR(25), #MAXID + ROW_NUMBER() OVER (ORDER BY NAME)) AS APPLICATION_NO
FROM TABLE2
Related
I have this table "ART":
COD - varchar(20) PK
DES - varchar(50)
Simple example data are:
COD DES
MM000000 AA
MM000001 BB
MM000010 CC
MM000145 DD
How do I increment the column COD by 1 every insert? The final pk format must be: 'MM' + 6 digits
DECLARE #a INT = 0;
WHILE #a < 100
BEGIN
SELECT 'MM' + RIGHT('000000' + CAST(#A as VARCHAR(6)),6)
SET #a += 1
END
CREATE TABLE #a
(
Id INT IDENTITY(1,1),
Code AS 'MM' + RIGHT('000000' + CAST(Id as VARCHAR(255)),6)
)
INSERT INTO #a DEFAULT VALUES
INSERT INTO #a DEFAULT VALUES
INSERT INTO #a DEFAULT VALUES
SELECt * FROM #a
but identity can be an unevenly growing value
I guess it is better and more safe to define the identity column as a computed column in the table definition
Please refer to SQL tutorial on Custom Sequence String as SQL Identity Column
The solution requires a simple identity column of integer data type increasing by 1 with every insert
Then a second column, actually a computed column created as follows will help you for the solution of your requirement
COD as dbo.udf_ZeroPaddingAndConcat('ID-', CAST(Id as nvarchar(10)),6,'0'),
Actually the custom function module is just doing the zero padding here as
SELECT #Prefix + RIGHT(REPLICATE(#PaddingChar, #Length) + CAST(#Id as nvarchar(10)), #Length)
You will also find the function source code in the same referenced document
i have one trigger like this:
alter trigger newTrigger
on table2
after insert
as
begin
declare #rowData nvarchar(max)
if exists(select * from inserted)
begin
Set #rowData = (select * from inserted)
end
insert into table1(rowData, date)
values(#rowData, getdate())
end
i want after insert into table2, the inserted record and date insert to table1
but i cant merge the data of row into one column!
------------------table2--------------------
id | name | lname | birth
1 j jj 2000-03-03
-------------------table1 after insert into table2 -----------------
rowData | date
a,j,jj,2000-03-03 2017-05-07
You have to do the conversion and add one by one each column
eg:
Set #rowData = (select cast(col1 as varchar(10)) + cast(col2 as varchar(10)) from inserted)
for your edit with the col names. If the column already is varchar, the only that you have to take care is to avoid the length overflow :
Set #rowData = (select cast((id + ',' + name + ',' + lname + ',' + cast(birth as varchar(12)) ) as varchar(4000)) from inserted)
In table Requisitions i have tow columns RequisitionID and Code.
I need to update Code value based on RequisitionID value in this format.
RN-000RequisitionID/2017 so output will be RN-0001/2017 for example if RequisitionID =1
i have tried the below query but it didn't work.
update [dbo].[Requisitions] set [Code]='RN-000 "'RequisitionID'"/2017'
Modification in your query:
update [dbo].[Requisitions] set [Code]='RN-000'+RequisitionID+'/2017'
if above didn't work, use:
update [dbo].[Requisitions] set [Code]='RN-000'+CONVERT(VARCHAR,RequisitionID)+'/2017'
Hope it helps.
You need to us a + to CONCATENATE them together. You will also have to cast 2017 to a VARCHAR so that the + operator isn't interpreted as addition, rather concatenation.
declare #table table (RequisitionID int, Code varchar(64))
insert into #table values
(1,'RN-000')
update #table
Set Code= Code + cast(RequisitionID as varchar(1)) + '/2017'
Where RequisitionID = 1
select * from #table
+---------------+--------------+
| RequisitionID | Code |
+---------------+--------------+
| 1 | RN-0001/2017 |
+---------------+--------------+
I am working with Microsoft SQL Server 2014. In our requirement, custom formatted sequence number is include.
The sequence number format is CAT-YYYY-MM-NNNNNN. Sample data:
CAT-2016-10-000001
CAT-2016-10-000002
.
.
.
CAT-2016-10-999999
I don't want to use GUID or any other and I want to work with a procedure or function.
So, I am trying with this:
CREATE TABLE [category]
(
[id] int NOT NULL UNIQUE IDENTITY,
[category_no] nvarchar(20) NOT NULL,
[category_name] nvarchar(50) NOT NULL,
PRIMARY KEY ([id])
);
CREATE FUNCTION generate_category_no()
RETURNS CHAR(20)
AS
BEGIN
DECLARE #category_no CHAR(20)
SET #category_no = (SELECT MAX(category_no) FROM category)
IF #category_no IS NULL
SET #category_no = 'CAT-' + YEAR(getDate()) + '-' + MONTH(getDate()) + '-000001'
DECLARE #no int
SET #no = RIGHT(#category_no,6) + 1
RETURN 'CAT-' + YEAR(getDate()) + '-' + MONTH(getDate()) + '-' + right('00000' + CONVERT(VARCHAR(10),#no),6)
END
GO
ALTER TABLE category DROP COLUMN category_no;
ALTER TABLE category ADD category_no AS dbo.generate_category_no();
INSERT INTO category (category_name)
VALUES ('BMW'), ('JAGUAR');
When I run the above SQL in step-by-step, it is OK. It shown no error. But when I run the following command:
SELECT * FROM category;
it shows the following error:
Msg 217, Level 16, State 1, Line 1
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
I don't know how to solve this one. And even I don't know my function has worked or not. I referenced from internet for this function.
ADDED
I need to reset sequence no for every month. Eg. for next month, no should be as follow:
CAT-2016-11-000001
Please, enlighten me. Thanks in advance!
Modify your function as below
ALTER TABLE category DROP COLUMN category_no;
alter FUNCTION dbo.generate_category_no( #id int)
RETURNS CHAR(20)
AS
BEGIN
RETURN 'CAT-' + cast(YEAR(getDate()) as varchar(10)) + '-' + cast(MONTH(getDate()) as varchar(10))+ '-' + right('00000' + CONVERT(VARCHAR(10),#id),6)
END
ALTER TABLE category ADD category_no AS dbo.generate_category_no(id);
INSERT INTO category
(category_name)
VALUES
('BMW13'),
('JAGUAR');
SELECT * FROM category will give the below result.
1 BMW CAT-2016-10-000001
2 JAGUAR CAT-2016-10-000002
3 BMW1 CAT-2016-10-000003
4 BMW13 CAT-2016-10-000004
Try this:
To initialize your new field:
ALTER TABLE category DROP COLUMN category_no;
ALTER TABLE category ADD category_no CHAR(20)
UPDATE category set category_no = dbo.generate_category_no()
For other insert:
CREATE TRIGGER [dbo].[category_i]
ON [dbo].[category]
AFTER INSERT
AS BEGIN
UPDATE category
SET category_no = dbo.generate_category_no()
FROM inserted
WHERE category.pk = inserted.pk
END
But you can try to use SEQUENCE feature, available on Sql Server by 2012 version
About SEQUENCE you can see here
Biggest flaw in your function is it will not work for Batch Insert's
Since you have ID auto generated, here is a easier way to do this
category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6))
Demo
CREATE TABLE #seq
(
id INT IDENTITY(1, 1),
name VARCHAR(10),
category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6))
)
INSERT INTO #seq
(name)
VALUES ('val')
Result :
id name category_no
-- ---- -----------
1 val CAT-2016-10-000001
Finally, I solved the problem. My Function look like as follow:
CREATE FUNCTION generate_category_no()
RETURNS CHAR(20)
AS
BEGIN
DECLARE #category_no CHAR(20)
SET #category_no = (SELECT MAX(category_no) FROM category WHERE category_no LIKE CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-%'))
IF #category_no is null SET #category_no = CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-000000')
DECLARE #no INT
SET #no = RIGHT(#category_no,6) + 1
RETURN CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-', RIGHT('00000' + CONVERT(VARCHAR(10),#no),6))
END
GO
And I insert data as follow:
INSERT INTO category (category_no, category_name) VALUES (dbo.generate_category_no(),'BMW');
INSERT INTO category (category_no, category_name) VALUES (dbo.generate_category_no(),'JAGUAR');
One things is that We can call function from INSERT query.
So, when I run the following sql:
SELECT * FROM category;
It give the result as shown in below.
+---+--------------------+--------------+
|id |category_no |category_name |
+---+--------------------+--------------+
| 1 |CAT-2016-10-000001 | BMW |
| 2 |CAT-2016-10-000002 | JAGUAR |
+---+--------------------+--------------+
Thanks everybody for helping me. Thanks!!!
I am building a functionality that will filter a data on all column table.
Let's say I have this table:
-------------------------------------
| ID | NAME | Address | Remarks |
| 1 | Manny | Phil | Boxer-US |
| 2 | Timothy | US | Boxer |
| 3 | Floyd | US | Boxer |
| 4 | Maidana | US | Boxer |
| 5 | Marquez | MEX | Boxer |
-------------------------------------
I search for "US", it should give me IDs 1-4 since "US" exists in their columns.
I could have this to filter it:
SELECT ID FROM tbl_Boxers
WHERE ID LIKE '%US%' OR NAME LIKE '%US%' OR Address LIKE '%US%' OR Remarks LIKE '%US%'
But I'm trying to avoid a long WHERE clause here since in actual, I have around 15 columns to look at.
Is there any other way to minimize the where clause?
Please help.
Thanks
The way this is normally done is to make a 'Searchable Field' column where you concatinate all search columns into one field for searching.
So while that provides an easier overview and querying it adds some management of the data you need to be aware off on inserts and updates.
Also on its own - it's not an optimal way of searching, so if performance is important - then you should look to implement full text search.
So the question is where you want to have the 'overhead' and whether that functionality your building is going to be run often or just once in a while.
If it is the former, and performance is important - look to full text. If it is just a once-in-a-while query, then I'd properly just do the long WHERE clause myself to avoid adding more overhead on the maintenance of the data
Check the following solution. Here the query is generated dynamically based on the column names in your table.
This is applicable if the given table is a physical table. This solution wont work for temporary tables or table variables.
BEGIN TRAN
--Simulate your table structure
--Should be a physical table. Cannot be a temp table or a table variable
CREATE TABLE TableA
(
ID INT,
NAME VARCHAR(50),
ADDRESS VARCHAR(50),
REMARKS VARCHAR(50)
)
--Added values for testing
INSERT INTO TableA(ID, name , address ,remarks) VALUES(1,'Manny','Phil','Boxer-US')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(2,'Timothy','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(3,'Floyd','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(4,'Maidana','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(5,'Marquez',' MEX','Boxer')
--Solution Starts from here
DECLARE #YourSearchValue VARCHAR(50)--Will be passed
SET #YourSearchValue = 'US' --Simulated passed value
CREATE TABLE #TableCols
(
ID INT IDENTITY(1,1),
COLUMN_NAME VARCHAR(1000)
)
INSERT INTO #TableCols
(COLUMN_NAME)
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE table_name = 'TableA';
DECLARE #STARTCOUNT INT, #MAXCOUNT INT, #COL_NAME VARCHAR(1000), #QUERY VARCHAR(8000), #SUBQUERY VARCHAR(8000)
SELECT #STARTCOUNT = 1, #MAXCOUNT = MAX(ID) FROM #TableCols;
SELECT #QUERY = '', #SUBQUERY = ''
WHILE(#STARTCOUNT <= #MAXCOUNT)
BEGIN
SELECT #COL_NAME = COLUMN_NAME FROM #TableCols WHERE ID = #STARTCOUNT;
SET #SUBQUERY = #SUBQUERY + ' CONVERT(VARCHAR(50), ' + #COL_NAME + ') LIKE ''%' + #YourSearchValue + '%''' + ' OR ';
SET #STARTCOUNT = #STARTCOUNT + 1
END
SET #SUBQUERY = LEFT(#SUBQUERY, LEN(#SUBQUERY) - 3);
SET #QUERY = 'SELECT * FROM TableA WHERE 1 = 1 AND (' + #SUBQUERY + ')'
--PRINT (#QUERY);
EXEC (#QUERY);
ROLLBACK
Hope this helps.