Create automatically generated timestamp column in table? - sql

How to create a automatically generated timestamp column in table in Microsoft SQL Server 2019? Timestamp column should be automatically generated when I insert or update table.
In IBM Db2 database the syntax is the following:
create table myschema.mytable (col1 int, col2 timestamp not null generated always for each row on update as row change timestamp
insert into myschema.mytable (col1) values (1)
update myschema.mytable set col1 = 2
After insert/update of column col1, column col2 is automatically generated as current timestamp.

In Microsoft SQL Server you can try this code:
CREATE TABLE myschema.mytable
(
col1 int,
col2 datetime not null default(current_timestamp)
)
INSERT INTO myschema.mytable(col1) VALUES (1)
UPDATE myschema.mytable SET col1 = 2
SELECT * FROM myschema.mytable
Update:
Let's create temporary table for test
DECLARE #mytable TABLE
(
col1 int,
col2 datetime not null default(current_timestamp)
)
INSERT INTO #mytable(col1) VALUES (1)
SELECT * FROM #mytable
UPDATE #mytable SET col1 = 2
SELECT * FROM #mytable

Related

Insert into a table with the data present in one table which match the first row of another table

I am new to sql.
I want to insert a data to backup table from main table that also matches the first record of another table.
suppose I have backup table with name "baktble" and main table with name "sales".
note : both tables have same columns c1,c2,c3,c4,c5,c6.
and I have a buffer table "buftble" with columns only the first 3 columns of bakup and sales table c1,c2,c3.
Now how to insert a data into backup table from sales table which matches the columns of first record.
I tired this but got error.
insert into baktble
select *
from sales
where col1,col2,col3 in (
select top 1 col1,col2,col3
from buftble).
So while nbk's as is the correct SQL syntax for your query:
create table baktble(col1 int, col2 int, col3 int, col4 int, col5 int, col6 int);
create or replace table sales(col1 int, col2 int, col3 int, col4 int, col5 int, col6 int);
create or replace table buftble(col1 int, col2 int, col3 int);
insert into buftble values
(1,10,100),
(2,20,200),
(3,30,300);
insert into sales values
(1,10,100, 101, 102, 103),
(2,20,200, 201, 202, 203),
(3,30,300, 301, 302, 303);
insert into baktble
select *
from sales
where (col1,col2,col3) in (
select top 1 col1,col2,col3
from buftble);
this only ever inserts zero or one row from sales into baktble.
Because the top 1 only selects one row from buftble
If I had to guess what you are wanting to do is ether:
insert all sales that match the distinct rows in buftble
insert the first sales row that matches the distinct rows in buftble
The first is done with:
insert into baktble
select *
from sales
where (col1,col2,col3) in (
select distinct col1,col2,col3
from buftble);
and the later (with the assumption that col4 is valid to sort duplicate values by) using QUALIFY and ROW_NUMBER like so:
insert into baktble
select *
from sales
where (col1,col2,col3) in (
select distinct col1,col2,col3
from buftble)
qualify row_number() over (partition by col1,col2,col3 order by col4 desc) = 1;

Hive : Cannot copy data from unpartitioned table to partitioned table

I have an unpartitioned table
create table tabUn
(
col1 string,
col2 int
)
Lets say it has some data. Next I created a partitioned table
CREATE EXTERNAL TABLE tabPart
(
col1 string,
col2 int
)
PARTITIONED BY (col_date string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION '/path/to/table';
Finally, I tried to copy the data over
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
INSERT OVERWRITE TABLE tabPart PARTITION(data_date='2018-10-01')
SELECT
(
col1,
col2,
'2018-10-01' as col_date
) select * FROM tabUn;
but I get the below error
FAILED: NullPointerException null
What am I doing wrong?
Your select statement seems to be incorrect.
INSERT OVERWRITE TABLE tabPart PARTITION (data_date='2018-10-01')
SELECT col1,col2,'2018-10-01' as col_date from tabUn;

MERGE syntax SQL Server 2012 error

Have a question about the MERGE syntax for which I cannot find the answer.
I have the following case:
Step1:
create temp table #TempTbl
Step2: MERGE:
MERGE INTO T1 target
USING T2 AS source ON (bunch of columns)
WHEN MATCHED
UPDATE
SET some columns from target equal some columns from source
WHEN NOT MATCHED BY TARGET
THEN INSERT (bunch of columns)
VALUES (bunch of columns from SOURCE)
OUTPUT $action, deleted.* into #TempTbl
What I need to know is for my above steps wouldn't I find only empty data in my temporary table #TempTbl, as I only stated WHEN NOT MATCHED ... THEN INSERT, not DELETE?
Second question, what type of column should $action be, as I'm having the error message:
Column name or supplied values do not match table definition
Although I've tried to define the first column from my table both varchar(100), nvarchar(100), but with no luck. But, If I omit the $action field, then my statement works.
So, the column that will hold the $action should be nvarchar(10).
The following statement would add rows to the temp table for both insert and update (as the update is really a delete followed by an insert) but with different actions:
-- sample test data
create table t1 (col1 int, col2 int)
create table t2 (col1 int, col2 int)
insert t1 values (1,1),(2,1)
insert t2 values (2,2),(3,3)
create table #temptbl (dml_action nvarchar(10), col1 int, col2 int)
-- merge statement
merge into t1 target
using t2 as source
on target.col1 = source.col1
when matched
then update set target.col2 = source.col2
when not matched by target
then insert (col1, col2) values (source.col2, source.col2)
output $action, inserted.col1, inserted.col2 into #temptbl ;
-- sample result
select * from #temptbl
dml_action col1 col2
---------- ----------- -----------
INSERT 3 3
UPDATE 2 2
If you don't want the update rows you could wrap the entire batch into another statement like so:
insert #temptbl (dml_action, col1, col2)
select dml_action, col1, col2
from
(
merge into t1 target
using t2 as source
on target.col1 = source.col1
when matched
then update set target.col2 = source.col2
when not matched by target
then insert (col1, col2) values (source.col2, source.col2)
output $action as dml_action, inserted.col1, inserted.col2
) a
where a.dml_action = 'INSERT'

How do I update a table based off the generated index key of an insert?

I'm created a temp table with most of the values I need to insert into a set of tables. From this temp table I have all the values I need for the insert to the first table, but the insert to the next table depends on the identity key generated by the insert to the first table.
I could very well just update my temp table after the first insert, but I'd like to try using the output clause.
I want something like this:
INSERT INTO Table1
<values from temp table>
OUTPUT <update my temp table with generated identity keys>
INSERT INTO Table2
<values from temp table including the output updated id column>
I think you better create another temp table (OR) table type variable and go from there as shown below. Cause I don't think you can update the same temp table from where you are inserting using output clause.
CREATE TABLE TestTable (ID INT not null identity primary key,
TEXTVal VARCHAR(100))
create TABLE #tmp(ID INT, TEXTVal VARCHAR(100))
create TABLE #tmp1(ID INT, TEXTVal VARCHAR(100))
CREATE TABLE TestTable1 (ID INT not null, TEXTVal VARCHAR(100))
INSERT #tmp (ID, TEXTVal)
VALUES (1,'FirstVal')
INSERT #tmp (ID, TEXTVal)
VALUES (2,'SecondVal')
INSERT INTO TestTable (TEXTVal)
OUTPUT Inserted.ID, Inserted.TEXTVal INTO #tmp1
select TEXTVal from #tmp
INSERT INTO TestTable1 (ID, TEXTVal)
select ID, TEXTVal from #tmp1
You could merge your temptable into Table1, and output the results to a variable table, then insert the original data joined to the variable table into Table2.
Example:
DECLARE #MyIDs TABLE (TempTableID int NOT NULL, Table1ID int NOT NULL)
MERGE INTO Table1
USING TempTable AS Tmp
ON Table1.SomeValue = Tmp.SomeValue
WHEN NOT MATCHED THEN
INSERT (col1, col2, col3, col4, col5)
VALUES (tmp.col1, tmp.col2, tmp.col3, tmp.col4, tmp.col5)
OUTPUT Tmp.ID
,Table1.ID
INTO #MyIDs;
INSERT INTO Table2 (col1, col2, col3, col4, col5, Table1ID)
SELECT tmp.col1, tmp.col2, tmp.col3, tmp.col4, tmp.col5, new.Table1ID
FROM TempTable tmp
JOIN #MyIDs new ON tmp.ID = new.TempTableID

SQL-Multiple Insert into identity table

I need to to do a insert from a table with the following structure:
Table A
Col1 Col2 Col3 Col4
intID1 intID2 intID3 intID4
I need to select the rows from the above table that are null
for col1,col2,col3 and insert those rows into a table that will generate an identity
row that I need to use to insert into another table.I am not sure of the
sql statement or the general method used to select those rows and insert them multiple times and retrieve the identity id one by one to insert into the next table.
Any help is greatly appreciated!
Sample process:
Table A
Col1 Col2 Col3 Col4
1 3 7 null
null null null 45
null null null 67
1)Retrieve rows 2 and 3
2)Insert 2 and 3 into another table to retrieve identity id for both rows
3)Insert identities from step 2 into another table
Venk covered step 1 and 2 I think. For 3 can use the OUPUT clause to retrieve the identity value from set operation.
Get Identity of multiple insertion in sql server 2008
INSERT INTO TABLEB(Col1,Col2,Col3,Col4)
SELECT * FROM TABLEA WHERE Col1 is NULL AND Col2 is NULL AND Col3 is NULL;
Sounds like you need the output operator:
declare #TableA table(Col1 int, Col2 int, Col3 int, Col4 int);
declare #TableB table(id int identity(1,1), Col1 int, Col2 int, Col3 int, Col4 int);
declare #Audit table(id int);
insert into #TableA
select 1,3,7,null union all
select null, null, null, 45 union all
select null, null, null, 67;
-- copy null columns from #TableA to #TableB
-- and output id's to #Audit
insert into #TableB
output inserted.id
into #Audit
select *
from #TableA
where Col1 is null
and Col2 is null
and Col3 is null;
-- Copied #TableB values and #Audit values
select * from #TableB;
select * from #Audit;