Shorthand for inserting row into history table with SQL - sql

I've got a trigger which copies a row whenever updated or deleted into a history table.
As of now I'm doing:
INSERT INTO history (column_x, column_y, column_z) VALUES (X, Y, Z);
Is it possible to shorthand it with:
INSERT INTO history VALUES (OLD)
The above does not work, but it gives an idea of what I'm looking for.
The columns match exactly as I've created the history table with:
CREATE TABLE history (LIKE original)

You should have some primary key defined in the table. Then you can do the insert select statement:
INSERT INTO history
SELECT * FROM notHistory WHERE ID = #ID

Related

How to copy some records of table and change some columns before insert into this table again in sql server?

In my SQL Server table, I have a table whose PK is GUID with lots of records already.
Now I want to add records which only needs to change the COMMON_ID and COMMON_ASSET_TYPE column of some existing records.
select * from My_Table where COMMON_ASSET_TYPE = "ASSET"
I am writing sql to copy above query result, changing COMMON_ID value to new GUID value and COMMON_ASSET_TYPE value from "ASSET" to "USER", then insert the new result into My_Table.
I do not know how to write it since now I feel it is a trouble to insert records manually.
Update:
I have far more columns in table and most of them are not nullable, I want to keep all these columns' data for new records except above two columns.Is there any way if I do not have to write all these column names in sql?
Try to use NEWID if you want to create new guid:
INSERT INTO dbo.YourTable
(
COMMON_ID,
COMMON_ASSET_TYPE
)
select NEWID(), 'User' as Common_Asset_Type
from My_Table
where COMMON_ASSET_TYPE = "ASSET"
UPDATE:
As a good practice I would suggest to write all column names explicitly to have a clean and clear insert statement. However, you can use the following construction, but it is not advisable in my opinion:
insert into table_One
select
id
, isnull(name,'Jon')
from table_Two
INSERT INTO My_Table (COMMON_ID,COMMON_LIMIT_IDENTITY, COMMON_CLASS_ID,COMMON_ASSET_TYPE)
SELECT NEWID(), COMMON_LIMIT_IDENTITY, COMMON_CLASS_ID,'USER'
FROM My_Table
WHERE COMMON_ASSET_TYPE = 'ASSET'
If I've understood correctly you want to take existing records in your table, modify them, and insert them as new records in the same table.
I'll assume ID column contains the the GUID?
I'd first create a temporary table
CREATE TABLE #myTempTable(
ID UNIQUEIDENTIFIER,
Name varchar(max),
... etc
);
Fill this temp table with the records to change with your SELECT statement.
Change the records in the temp table using UPDATE statement.
Finally, Insert those "new" records back into the primary table. with INSERT INTO SELECT statement.
You will probably have to sandwitch the INSERT INTO SELECT with IDENTITY_INSERT (on/off):
SET IDENTITY_INSERT schema_name.table_name ON
SET IDENTITY_INSERT schema_name.table_name OFF
IDENTITY_INSERT "Allows explicit values to be inserted into the identity column of a table."

Get just Inserted/Modified record based on updated_timestamp

I want to get just Inserted/Modified record based on updated_timestamp.
I have following scenario for DB2 database:
Triggering insert or update query to DB. The table contains updated_timestamp field which capture the insert or updated time.
Want to get my previous inserted/ updated record only using select query.
Example
insert into table_name(x,y,CURRENT TIMESTAMP);
want to get the above inserted record using select as
select * from table_name where updated_timestamp > ?
with what value should I replace the ?, above query should return me latest inserted record as x,y,<time_stamp>
If I understand what your asking, couldn't you use a subquery pulling the max(updated_timestamp) and other values from the table and use that to filter to only the most recently updated records for each one?
Something like this:
insert into table_name (x, y, timestamp)
Select table_name.x, table_name.y, DateTime()
from table_name join (select x, y, Max(updated_timestamp)
updated_timestamp from table_name) table_name2
on table_name.x = table_name2.x and table_name.y = tablename2.y
and table_name.updated_timestamp = table_name2.updated_timestamp
if your db2 version as this option you can use final table like this
SELECT updated_timestamp
FROM FINAL TABLE (INSERT INTO table_name (X, X, updated_timestamp )
VALUES(valueforX, valueforY, CURRENT TIMESTAMP));
look IBM Doc
you can use a variable too:
CREATE OR REPLACE VARIABLE YOURLIB.MYTIMESTAMP TIMESTAMP DEFAULT CURRENT TIMESTAMP;
INSERT INTO table_name (X, X, updated_timestamp )
VALUES(valueforX, valueforY, YOURLIB.MYTIMESTAMP));
but the best solution is update your table with you primary key and get your timestamp with your primary key after.
A suggestion, you use trigger for update last timestamp. May be can you use autotimestamp like this :
CREATE TABLE table_name
(
X VARCHAR(36),
Y VARCHAR(36),
CHANGE_TS TIMESTAMP FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP NOT NULL
)

SQL Server : how to insert into 2 different tables

This seems like a really simple answer, but for some reason I can't wrap my head around how I should accomplish this...
I've got two different tables:
Campaign
Campaign_Customer
Where dbo.Campaign is all of the details of the campaign, and dbo.Campaign_Customer is basically a summary table that contains the CampaignID, CustomerID, CreationDate, and DeletionDate (if there is one)
So, when I go to insert a new record into my dbo.Campaign table, I need to be able to use the CampaignID that it generates to create a record into my dbo.Campaign_Customer table.
I know this is possible, but I don't know the proper way to do so. Any help?
You will need to have 2 separate insert statements within transaction. If your campaign Id is identity column you can get its value using scope_identity function in select after first insert
BEGIN TRANSACTION
INSERT INTO dbo.Campain (x, y, z) VALUES (x, y, z)
DECLARE #id int
SELECT #id = scope_identity()
INSERT INTO dbo.Campaign_Customer (CampaignId, x, y) VALUES (#id, x, y)
COMMIT
You could create a trigger to do this:
CREATE TRIGGER [Campaign_Trigger] on dbo.Campaign
AFTER INSERT AS
INSERT INTO dbo.Campaign_Customer (CampaignId, x, y)
VALUES (t.CampaignID, t.x, t.y)
FROM Inserted t

Revert backup table data to original table SQL

I have created a backup for my country table.
create table country_bkp as select * from country;
What SQL should I use to restore the country table to it's original state?
I can do
insert into country select * from country_bkp;
but it will just have duplicate entries and probably fail as primary key would be same .
Is there an SQL command to merge data back?
Last alternative would be
DROP TABLE country;
create table country as select * from country_bkp;
but I want to avoid this as all the grants/permissions would get lost by this.
Other cleaner way would be
delete from country ;
insert into country select * from country_bkp;
But I am looking for more of a merge approach without having to clear data from original table.
Instead of dropping the table, which, as you noted, would lose all the permission defitions, you could truncate it to just remove all the data, and then insert-select the old data:
TRUNCATE TABLE country;
INSERT INTO country SELECT * FROM county_bkp;
In my case, INSERT INTO country SELECT * FROM county_bkp; didnt work because:
It wouldnt let me insert in Primary Key column due to
indentity_insert being off by default.
My table had TimeStamp columns.
In that case:
allow identity_insert in the OriginalTable
insert query in which you mention all the columns of OriginalTable (Excluding TimeStamp Columns) and in Values select all columns from BackupTable (Excluding TimeStamp Columns)
restrict identity_insert in the OriginalTable at the end.
EXAMPLE:
Set Identity_insert OriginalTable ON
insert into OriginalTable (a,b,c,d,e, ....) --[Exclude TimeStamp Columns here]
Select a,b,c,d,e, .... from BackupTable --[Exclude TimeStamp Columns here]
Set Identity_insert OriginalTable Off
Only One Solution to Recover Data from Backup table is Rename Original table with random name and than rename Backup table with Original Table name in case if Identity Insert is ON for Original Table.
for example
Original Table - Invoice
Back Up Table - Invoice_back
Now Rename these tables :
Original Table - Invoice_xxx
Back Up Table - Invoice

Sqlite database with single row

I want to create a sqlite database table having single row and multiple columns.
Each time entire row will be updated.
In the sqlite i can create the table but first time updating entire row is not working.
The update entire row works only after the first INSERT command. Instead of doing first time INSERT command is it possible to execute UPDATE command as soon as the table is created?
I am doing following steps:
$ sqlite3 test.db
sqlite> create table company (Id int primary key not null, name text, age int);
sqlite> update company set id=1, name='test', age=30;
sqlite> select * from company;
sqlite>
Here select statement is not returning anything.
Is there any restriction in SQL to use the UPDATE command very beginning?
You seem to be ignoring how sql works. You perform an update of nothing and expect that a row magically exists after that.
You have to do an insert first.
You want to try
insert into company values (1, 'test', 30);
in order to have one record.
update only changes what is alread there, it cannot be used to create (that is: insert) new records.
Now, after having created your first record, you can change it with a
update company set age = 45 where id = 1;