When inserting a new row in table A, another row also gets inserted in table B - sql

So I am working with these two tables, Dependency and DependencyList.
I am trying to write an SQL query that, when a new row gets created in table Dependencies, another one also gets created in DependencyList, having the DependencyId filled with the Id of the newly created Dependency.
The Id column of both tables is auto-incremented.
Would that be possible, in any way?

You would typically do this with a FOR INSERT trigger. You can access the previously generated id using the inserted pseudo-table.
CREATE TRIGGER myTrigger ON Dependencies FOR INSERT
AS INSERT INTO DependencyList (DependencyId) SELECT Id FROM inserted;
Demo on DB Fiddlde
You can also do this with two insert statements, using SCOPE_IDENTITY() to retrieve the last insert id:
INSERT INTO Dependencies(isResolved, AssignedToTaskId) VALUES(0, 0);
INSERT INTO DependencyList (DependencyId) SELECT SCOPE_IDENTITY();
Demo

Related

Trigger: How does the inserted table work? How to access its rows?

I have the following table
Data --Table name
ID -- Identity column
PCode -- Postal Code
I created the following trigger:
CREATE TRIGGER Trig
ON Data
FOR INSERT
AS
BEGIN
Select * from inserted
END
And inserted the following values
INSERT INTO Data VALUES (125)
INSERT INTO Data VALUES (126)
INSERT INTO Data VALUES (127)
It shows this:
But I was expecting something like this:
After the 1st insertion, the trigger is executed -> one row is shown in the inserted table.
After the 2nd insertion, the trigger is executed -> two rows are shown in the inserted table.
After the 3rd insertion, the trigger is executed -> three rows are shown in the inserted table.
According to msdn.microsoft all the rows inserted are in this table.
How can I access the inserted table so that I can see all the expected rows and not separately?
You can not. From the Use the inserted and deleted Tables article on microsoft.com, you can read:
The inserted table stores copies of the affected rows during INSERT and UPDATE statements.
That means that the inserted table will only contain rows for the current INSERT or UPDATE statement.
If you do want to see all rows for several such INSERT or UPDATE statements, you will have to store these rows in a table you created yourself.
There are 2 table available in a trigger, the inserted and the deleted. Each update on table XXX is actually a delete row X from XXX then an insert of row X in table XXX. So the inserted inside the trigger is a copy of what got inserted. You can do a lot with a trigger, but triggers are dangerous.
For example, on a performance gig, I found a huge SP being run by a trigger, we dropped it and the database came back online. Or another example, if you do a trigger wrong to audit logins, you can down the server.
As TT mentioned, if you want to see all the inserted records then you need to change your Trigger to something like this:
CREATE TRIGGER Trig
ON Data
FOR INSERT
AS
BEGIN
Select * into "tablename"
from
(Select * from inserted) Ins
END

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;

Using Trigger to insert record in another table, AND write back the ID into original record ..?

I have a simple trigger setup, which is used to insert records into a RentJournal table, whenever there is a record inserted in the UnitAGA table.
The RentJournal table has a primary key ID column named RentJournalID, which is auto incrementing. The UnitAGA table also has a nullable foreign key column named RentJournalID, which links each UnitAGA entry, to its corresponding entry in RentJournal table (which is inserted through the Trigger below).
Problem is that currently this Trigger is only inserting values into RentJournal table. But now I want to also fetch the ID assigned for each RentJournal entry through this Trigger, and write that into the corresponding UnitAGA record, whose insert actually triggered the Trigger in the first place. How do I do this ?
The Trigger code as of right now is this:
USE [RentDB]
GO
ALTER TRIGGER [RTS].[InsertRentJournalEntry]
ON [RTS].[UnitAGA]
AFTER INSERT
AS
BEGIN
INSERT INTO RTS.RentJournal
(UnitId, AdjustmentType, EffectiveDate, ReferenceFormNo)
SELECT
UnitId, 'AGA', EffectiveDate, ReferenceFormNo FROM inserted
END
Have a look at the INSERT logical table that is available in insert triggers:
DML triggers use the deleted and inserted logical (conceptual) tables. They are structurally similar to the table on which the trigger is defined, that is, the table on which the user action is tried. The deleted and inserted tables hold the old values or new values of the rows that may be changed by the user action. For example, to retrieve all values in the deleted table, use: SELECT * FROM deleted
http://technet.microsoft.com/en-us/library/ms189799.aspx
Then use ##IDENTITY to get the value of the identity column on your RentJournal table.
So you should be able to do something like:
update INSERTED set RentJournalID = ##IDENTITY

Multiple row insert into two tables avoiding loops

I have a set of value which have to be inserted into two tables.Input has say 5 row and I have to insert these 5 rows into table A first.Table A has a identity column.Next i have to insert these 5 rows into table B with an extra column which is the identity from table A.
How this can be done with out using any loops?
Any help will be highly helpful.
INSERT INTO TABLE_A(COL2,COL3)
SELECT COL2,COL3 FROM #TEMP_TAB
set #identityval=##identity
INSERT INTO TABLE_B(COLA,COLB,COLC)
SELECT #identityval,COL2,COL3,COL4 FROM #TEMP_TAB
You cannot insert into multiple tables using a single statment.
What you could do is create an insert trigger on Table A so that after the insert occurs this performs the new insert with the identity of the value inserted into Table A and insert it into Table B.
Here is one solution.
take max of identity column from table TABLE_A
insert new records in table TABLE_A
then insert records on TABLE_B from TABLE_A with Identity greater than last max identity.
Thanks,
Gopal
What you want to do is not possible.
You can get only the value from the last insert using the ##identity variable. This way its possible to add to multiple tables setting the right foreign key without selecting the just inserted row again using a cursor. This approach is not useful when inserting multiple rows at once.
From the documentation:
Use the ##identity global variable to retrieve the last value inserted into an IDENTITY column. The value of ##identity changes each time an insert or select into attempts to insert a row into a table.
Here is a procedure which inserts a single row and you can use the return value to create a reference to the inserted data in another table:
create procedure reset_id as
set identity_insert sales_daily on
insert into sales_daily (syb_identity, stor_id)
values (102, "1349")
select ##identity
select ##identity
execute reset_id

Sql Server trigger insert values from new row into another table

I have a site using the asp.net membership schema. I'd like to set up a trigger on the aspnet_users table that inserted the user_id and the user_name of the new row into another table.
How do I go about getting the values from the last insert?
I can select by the last date_created but that seems smelly. Is there a better way?
try this for sql server
CREATE TRIGGER yourNewTrigger ON yourSourcetable
FOR INSERT
AS
INSERT INTO yourDestinationTable
(col1, col2 , col3, user_id, user_name)
SELECT
'a' , default , null, user_id, user_name
FROM inserted
go
You use an insert trigger - inside the trigger, inserted row items will be exposed as a logical table INSERTED, which has the same column layout as the table the trigger is defined on.
Delete triggers have access to a similar logical table called DELETED.
Update triggers have access to both an INSERTED table that contains the updated values and a DELETED table that contains the values to be updated.
You can use OLDand NEW in the trigger to access those values which had changed in that trigger. Mysql Ref
In a SQL Server trigger you have available two psdeuotables called inserted and deleted. These contain the old and new values of the record.
So within the trigger (you can look up the create trigger parts easily) you would do something like this:
Insert table2 (user_id, user_name)
select user_id, user_name from inserted i
left join table2 t on i.user_id = t.userid
where t.user_id is null
When writing triggers remember they act once on the whole batch of information, they do not process row-by-row. So account for multiple row inserts in your code.
When you are in the context of a trigger you have access to the logical table INSERTED which contains all the rows that have just been inserted to the table. You can build your insert to the other table based on a select from Inserted.
Create
trigger `[dbo].[mytrigger]` on `[dbo].[Patients]` after update , insert as
begin
--Sql logic
print 'Hello world'
end