create table Table1(
DateIdentify CHAR(15),
primary key(DateIdentify)
);
Insert into Table1 (DateIdentify) VALUES('?');
How I want the 'DateIdentify' to look: (20131002-0001) with 0001 being some sort of an auto incrementer that starts at 0001 and goes up every insert and 20131002 coming from CURDATE(), so adding CURDATE() + 4 digits. I'm wondering if this is possible? If so, could anyone please point me in the right direction?
EDIT:
CREATE TABLE Table1(
IdTable1 int auto_increment NOT NULL,
Date1 datetime,
);
You have to separate your datetime and the auto increment field.
Create your table like this using an auto-increment int field, and your datetime.
For example:
CREATE TABLE Table1(
IdTable1 int PRIMARY KEY IDENTITY(1,1) NOT NULL,
Date datetime
)
Then, you don't have to insert anything in IdTable1 because of it is auto-incremented thanks to keyword IDENTITY (SQL do the auto-increment for you)
NOTE : I wrote this for SQLServer, if you use another database, the code can change a little bit.
Which one do you use ?
EDIT :
You can also do some insert like this :
INSERT INTO Table1
(
Date
)
VALUES
(
'2013-10-02'
)
In case a solution is required as, having only one column with values in desired format you can create a function as:
create function dbo.fn_GetDateIdentify ()
returns varchar(15)
as
begin
declare #DateIdentify varchar(15);
select #DateIdentify =
(select convert (varchar(8),GETDATE (),112) +
'-' +
right ('00000' + cast (
(
(
case when Not exists (select ROW_NUMBER() over( order by (select 1)) from Table1 ) then 1
else (select top 1 ROW_NUMBER() over( order by (select 1)) as currentRownumber from Table1 order by currentRownumber desc) + 1
end
)
)
as varchar(4))
,4));
return #DateIdentify;
end
go;
and then use the function in insert statement as :
insert into Table1 (DateIdentify)
select dbo.fn_GetDateIdentify();
Hope this helps!
Related
How do I insert a sql row into a new table where it meets criteria but resets the id value. In other words, copy the row, but reset the id value.
This is my current sql
INSERT INTO followers_lost SELECT * FROM followers WHERE pk = $pk
I tried to SET id=null and VALUE (0), but both don't work.
All you have to do since you want all the columns except the identity is specify all the non-identity columns on the insert:
INSERT INTO [followers_lost] ([Column1],[column2]...{but not the identity
column})
SELECT [Column1],[column2]...{but not the identity column} FROM followers WHERE
pk = $pk
You can create the column and then update it:
SET #new_id=0;
UPDATE your_table
SET id = #new_id := #new_id + 1
where id = 0
OK based on your comment I think you are trying to take all or some of the fields from Followers except the PK and put them into Followers_Lost where they equal a certain PK. If you want multiple PK's you would need to change the where clause to an IN statement instead of an equal and adjust your values accordingly.
CREATE TABLE dbo.UAT_Followers_Lost (PK INT IDENTITY(1,1),DATA VARCHAR(50) )
CREATE TABLE dbo.UAT_Followers (PK INT IDENTITY(1,1),DATA VARCHAR(50) )
INSERT INTO dbo.UAT_Followers
(DATA)
SELECT 'Jan'
UNION ALL
SELECT 'Feb'
UNION ALL
SELECT 'Mar'
DECLARE #PK INT
SET #PK = 1
INSERT INTO dbo.UAT_Followers_Lost
(Data)
SELECT Data
FROM dbo.UAT_Followers
WHERE PK = #PK
I am creating empty temporary table based on another table in my db and adding an extra column (PRICE) which i am trying to populate from query,
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
NULL AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE
when i fill this table as INSERT INTO #TMP_TABLE ... the value i am getting in PRICE column is either 0 or 1, but when i execute query seperately, i am getting decimal values (like0.0634).
how can i store decimal values in temp table above ? or is there any other way to create empty temp table ?
Use CREATE TABLE and define explicitly columns types:
CREATE TABLE #TMP_TABLE(RowNumber INT, ID <you_type>, Price <your_type>)
Default for NULL is INT, check:
SELECT x = NULL INTO #x;
EXEC tempdb..sp_columns '#x';
So your fraction are converted implicitly to INT
One good rule for future EXPLICIT IS ALWAYS BETTER THAN IMPLICIT
you either create the table with a create table statement:
create table #TMP_TABLE
( RowNumber int
, ID <whatever datatype>
, PRICE numeric(10,2)
);
or if you insist on select into declare the datatype :
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
cast(NULL as numeric(10,2)) AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE
I am converting data from one database to another. The target db has a table called provider with primary key provider_no varchar(6).
I'm writing an insert to copy from source table to target table, and need an incremented key for provider_no. Is there a function to return even the iterations for one insert statement?
There are a lot more columns, but the basic problem i'm trying to solve is:
INSERT INTO `target`.`provider`
(`provider_no`,
`lastUpdateDate`)
SELECT
'', --incremented value
now()
from `source`.`provider`;
Auto Increment only works for int values, but i'm not at liberty here to change the data type.
Also, the source table doesn't have a usable primary key value that I can use for this copy.
To increment the varchar, first cast it to a number (either signed, or unsigned) like so:
INSERT INTO `target`.`provider`
(`provider_no`,
`lastUpdateDate`)
SELECT
cast(the_varchar_field as signed) + 1, --incremented value
now()
from `source`.`provider`;
Example:
mysql> select cast("001" as unsigned) + 1;
+-----------------------------+
| cast("001" as unsigned) + 1 |
+-----------------------------+
| 2 |
+-----------------------------+
Sorry, i thought you wanted to increment the varchar field from the source table.
To 'emulate' an auto increment field as you want to do, we can do it with variables like this:
insert into provider
select #cnt := #cnt +1, now()
from sourceprovider, (select #cnt := 0) q;
And here's a little demo: http://sqlfiddle.com/#!9/09fd4/1
Here's a solution I just implemented. There's a unique column called did on the source table, which I can use indirectly. There's probably a more elegant way to do it, but:
create table temp_key (
key_id int auto_increment primary key,
did varchar(4));
insert into temp_key (did) select did from source.provider;
INSERT INTO target.provider
(provider_no,
lastUpdateDate)
SELECT
k.key_id,
now()
FROM source.provider d
JOIN temp_key k on d.did = k.did;
drop table temp_key;
Scenario/background:
I am trying to create a table of "Tests". For purposes of this question my table will only have 5 columns defined as follows:
CREATE TABLE TestTable
(
Id UNIQUEIDENTIFIER DEFAULT NEWID() NOT NULL,
Name VARCHAR(75) NOT NULL,
DateRequested DATETIME NOT NULL DEFAULT GETDATE(),
TestYear AS YEAR(DateRequested) PERSISTED NOT NULL, -- computed column that shows the year the test was requested. I want to persist this column so I can index on it if need be.
TestNumber CHAR(4) NOT NULL DEFAULT '0000', -- need this to auto increment but also needs to reset for the first test of the year.
CONSTRAINT TestTablePK PRIMARY KEY(Id)
);
GO
My requirement is that I want the 'TestNumber' to "auto-increment" based on the year. For example:
GUID, Test 1 in Old Yr, 2013-01-01 05:00:00.000, 2013, 0001
GUID, Test 2 in Old Yr, 2013-12-25 11:00:00.000, 2013, 0002
GUID, Test 3 in Old Yr, 2013-12-26 09:00:00.000, 2013, 0003
...., ................, ......................., ...., N
GUID, Test N in Old Yr, 2013-12-31 09:00:00.000, 2013, N+1
GUID, Test 1 in New Yr, 2014-01-01 11:00:00.000, 2014, 0001 <-- reset to 1
I was thinking that it would be an auto-increment column but how would I reset it based on this being the first test of a new year? So my incorrect solution thus far has been an "instead of insert" trigger defined as follows:
CREATE TRIGGER InsteadOfInsertTrigger ON dbo.TestTable
INSTEAD OF INSERT AS
BEGIN
-- Get the year of the test request being inserted from the pseudo-insert table.
DECLARE #TestYear INT;
SET #TestYear = (SELECT YEAR(DateRequested) FROM inserted);
-- Grab the maximum TestNumber from TestTable based on the year
-- that we are inserting a record for.
DECLARE #MaxTestNumber INT;
SET #MaxTestNumber = (SELECT MAX(TestNumber) FROM dbo.TestTable WHERE TestYear = #TestYear);
-- If this is the first test of the year being inserted it is a special case
IF #MaxTestNumber IS NULL
BEGIN
SET #MaxTestNumber = 0;
END;
-- Here we take the MaxTestNumber, add 1 to it, and then pad it with
-- the appropriate number of zero's in front of it
DECLARE #TestNumber VARCHAR(4);
SET #TestNumber = (SELECT RIGHT('0000' + CAST((#MaxTestNumber + 1) AS VARCHAR(4)), 4));
INSERT INTO dbo.TestTable(Name, DateRequested, TestNumber)
SELECT Name, DateRequested, #TestNumber FROM inserted;
END;
GO
Now here is some DML showing the trigger in action:
INSERT INTO TestTable(Name, DateRequested)
VALUES('Some Test', '05-05-2013');
INSERT INTO TestTable(Name, DateRequested)
VALUES('Some Other Test', '12-25-2013');
INSERT INTO TestTable(Name, DateRequested)
VALUES('Blah Blah', '12-31-2013');
INSERT INTO TestTable(Name, DateRequested)
VALUES('Foo', '01-01-2014');
SELECT * FROM TestTable ORDER BY TestYear ASC, TestNumber ASC;
So as you can see my trigger works for single row inserts but a keen eye will be able to tell it will not work for multi-row inserts.
CREATE TABLE TempTestTable
(
Name VARCHAR(75) NOT NULL,
DateRequested DATETIME NOT NULL DEFAULT GETDATE()
);
GO
INSERT INTO TempTestTable(Name, DateRequested)
VALUES('Test1', '01-01-2012');
INSERT INTO TempTestTable(Name, DateRequested)
VALUES('Test2', '12-25-2012');
INSERT INTO TempTestTable(Name, DateRequested)
VALUES('Test3', '01-01-2013');
INSERT INTO TempTestTable(Name, DateRequested)
VALUES('Test4', '01-01-2014');
-- This doesnt work because it is a multi-row insert.
INSERT INTO TestTable(Name, DateRequested)
SELECT Name, DateRequested FROM TempTestTable;
My Question
I realize that I can probably handle this with stored procedures and force users to use stored procedures when updating the tables but I want to be extra careful and prevent sysadmins from being able to do direct inserts to the table with an incorrect 'TestNumber'.
So StackOverflow, my question is how can I achieve this? Would I use a cursor inside of my InsteadOfInsertTrigger? I am looking for alternatives.
Not the neatest thing I'll ever write, but seems to do the job:
CREATE TRIGGER InsteadOfInsertTrigger ON dbo.TestTable
INSTEAD OF INSERT AS
BEGIN
;With Years as (
select i.TestYear,
COALESCE(MAX(tt.TestNumber),0) as YMax
from inserted i left join TestTable tt
on i.TestYear = tt.TestYear
group by i.TestYear
), Numbered as (
select i.ID,i.Name,i.DateRequested,
RIGHT('000' + CONVERT(varchar(4),
ROW_NUMBER() OVER (PARTITION BY i.TestYear
ORDER BY i.DateRequested,i.Id) + YMax)
,4) as TestNumber
from inserted i
inner join
Years y
on
i.TestYear = y.TestYear
)
insert into TestTable (Id,Name,DateRequested,TestNumber)
select Id,Name,DateRequested,TestNumber from Numbered;
END;
The first CTE (Years) finds the highest used number for each year that's of interest. The second CTE (Numbered) then uses those values to offset a ROW_NUMBER() that's being assessed over all rows in inserted. I picked the ORDER BY columns for the ROW_NUMBER() so that it's as deterministic as possible.
(I was confused about one thing for a while, but it turns out that I can use TestYear from inserted rather than having to repeat the YEAR(DateRequested) formula)
INSERT INTO `dictionary2` (word,verb)
SELECT SUBSTRING(word FROM 2)
FROM `dictionary1`
WHERE `dictionary1`.word LIKE "w%"
I have two tables, dictionary1(word) and dictionary2(word,verb).
I would like to insert into dictionary2, values from dictionary1, where word starts with 'w' and the value is not present in dictionary2.word.
In the same insert I would like to set the value of dictionary2.verb to 1.
You could use this:
INSERT INTO dictionary2 (word, verb)
SELECT dictionary1.word, 1
FROM
dictionary1 LEFT JOIN dictionary2
ON dictionary1.word = dictionary2.word
WHERE
dictionary1.word LIKE 'w%'
AND dictionary2.word IS NULL
Please see fiddle here.
Try this:
SQL Query:
INSERT INTO `dictionary2` (word,verb)
SELECT word, (select #number :=1)
FROM `dictionary1`
WHERE `dictionary1`.word LIKE "t%"
AND `dictionary1`.word NOT IN(SELECT word FROM dictionary2);
Sample data:
CREATE TABLE `dictionary2` (
ID INT AUTO_INCREMENT PRIMARY KEY,
word VARCHAR (50),
verb VARCHAR (50)
);
CREATE TABLE `dictionary1` (
ID INT AUTO_INCREMENT PRIMARY KEY,
word VARCHAR (50)
);
INSERT INTO `dictionary2`(word,verb)
VALUES
('test','test'),
('test1','test1');
INSERT INTO `dictionary1`(word) VALUES('test'),('testing1');
B.T.W. you can safely change LIKE "t%" into LIKE "w%" ;-)
SQL FIDDLE DEMO