Checking if ID exists and also if another column is null and updating another column - sql

I am about to implement an update statement on a table. I know it sounds really simple, but I'm not able to get through it logically.
Scenario:
There is a table I have with the below format, that gets data everyday through a process. The columns on the table are as follows:
PKID | RecordID | ThirdPartyID | Action | DATEADDED
PKID: The auto incremental Primary Key.
RecordID: Can have duplicates.
ThirdpartyID: Can be multiple values and also accepts NULLS.
Action: The column that needs to be updated
DateAdded: Contains the GETDATE() of when the record is imported into the table.
Problem:
There is a process that imports new records into this table everyday. When the records are inserted for a day, I need to check the following:
Check if the newly Inserted RecordIDs are already existing in the table.
If the RecordID entered today, is already there in the table (there can be multiple entries of the same RecordID in the old records),
Check if the ThirdPartyID is NULL in the old records for that RecordID.
If the ThirdPartyID exists in any of the old records for that RecordID, update the Action Column with 'Multiple Entries.'
Else do nothing.
Please let me know if I can provide any further clarification or details in this regard.

I would approach the problem like this:
Load new data into a Temp table.
Inner Join the 2 tables on RecordID which will join only if the RecordID exists in both tables...
update the Action column to "Multiple Entries" if the ThirdPartyID field is also null.
Script should be something like this:
UPDATE Main
SET Action = 'Multiple Entries'
FROM Main INNER JOIN Temp ON Main.RecordID = Temp.RecordID
WHERE Main.ThirdPartyID IS NOT NULL

You could get a copy of the inserted data by OUTPUT-ing it to a table variable, then perform the update by joining to the original table. e.g:
DECLARE #inserted TABLE
(PKID INT
,RecordID INT
,ThirdPartyID INT
,Action VARCHAR(MAX)
,DateAdded DATE);
INSERT TestTable1
(RecordID
,ThirdPartyID
,Action
,DateAdded)
OUTPUT
inserted.PKID
,inserted.RecordID
,inserted.ThirdPartyID
,inserted.Action
,inserted.DateAdded
INTO #inserted
(PKID
,RecordID
,ThirdPartyID
,Action
,DateAdded)
VALUES
(1
,2
,NULL
,GETDATE());
UPDATE t
SET ThirdPartyID = 'Multiple Entries'
FROM #inserted i
JOIN TestTable1 t
ON i.RecordID = t.RecordID
WHERE t.ThirdPartyID IS NOT NULL;

Related

Insert bulk data into two related tables with foreign keys from another table

I have imported some data to a temp SQL table from an Excel file. Then I have tried to insert all rows to two related tables. Simply like this: There are Events and Actors tables with many to many relationship in my database. Actors are already added. I want to add all events to Events table and then add relation(ActorId) for each event to EventActors tables.
(dbo.TempTable has Title, ActorId columns)
insert into dbo.Event (Title)
Select Title
From dbo.TempTable
insert into dbo.EventActor (EventId, ActorId)
Select SCOPE_IDENTITY(), ActorId --SCOPE_IDENTITY() is for EventId
From dbo.TempTable
When this code ran, all events inserted into Events, but the relations didn't inserted into EventActors because of Foreign Key error.
I think there should be a loop. But I am confused. I don't want to write C# code for this. I know there would be a simple but advanced solution trick for this in SQL Server. Thanks for your help.
Use the output clause to capture the new IDs, with a merge statement to allow capture from both source and destination tables.
Having captured this information, join it back to the temp table for the second insert.
Note you need a unique id per row, and this assumes 1 row in the temp table creates 1 row in both the Event and the EventActor tables.
-- Ensure every row has a unique id - could be part of the table create
ALTER TABLE dbo.TempTable ADD id INT IDENTITY(1,1);
-- Create table variable for storing the new IDs in
DECLARE #NewId TABLE (INT id, INT EventId);
-- Use Merge to Insert with Output to allow us to access all tables involves
-- As Insert with Output only allows access to columns in the destination table
MERGE INTO dbo.[Event] AS Target
USING dbo.TempTable AS Source
ON 1 = 0 -- Force an insert regardless
WHEN NOT MATCHED THEN
INSERT (Title)
VALUES (Source.Title)
OUTPUT Source.id, Inserted.EventId
INTO #NewId (id, EventId);
-- Insert using new Ids just created
INSERT INTO dbo.EventActor (EventId, ActorId)
SELECT I.EventId, T.ActorId
FROM dbo.TempTable T
INNER JOIN #NewId I on T.id = T.id;

How to move SQL records from one table to another inside a trigger

I have a sql table (table A) with a column called 'Number'. Inside a trigger (I have an AFTER INSERT,UPDATE trigger) I want to move all records that have the same Number to a different table (say table B)
So if its an insert I want to move all records that have that Number to table B so only the new record exists in the original table (table A).
If its an update I want to make a copy of the record being updated to table B (with old values).
so table B is a history table that holds all previous records and table A should only have one entry per Number.
would be nice to put in the existing AFTER INSERT/UPDATE but if I need another trigger that's fine.
Thanks for any help.
This turned out not as complicated as I thought...
(#itemId set from cursor)
SELECT #tempNumber = [Number] FROM tableA WHERE Id = #itemId;
if (NOT EXISTS(SELECT * FROM deleted)) --is insert
BEGIN
INSERT INTO tableB SELECT *, GETDATE() AS CreatedDate FROM tableA WHERE Number=#tempNumber AND Id != #itemId
DELETE FROM tableA WHERE Number=#tempNumber AND Id != #itemId
END
i decided not to create an entry on update but if needed you I believe you would just do an ELSE and SELECT from deleted and then INSERT.
Hope this helps someone!

After Insert Trigger on Microsoft SQL Server -- Updating a column in a newly created record

I have 3 tables Data table, LookUp_1,LookUp_2 all with column id which are primary key columns. The score1_id and score2_id columns are foreign key columns. score1_id links with id in LookUp_1 and score2_id links with id in LookUp_2.
My question is:
I need to create an after insert trigger which will update the calculation column from null to a specific number/value. This only happens when a new record is inserted into the Data table and it only should affect the newly created record. So for the example i have, id 1 is a newly inserted record, and now the trigger should go on and update the calculation column using the score1_id and score2_id. So it should go into LookUp1 and LookUp2 and check the weights for each id. So for example: 3=7 and 2=3. So after the trigger is completed the record should be updated with calculation column = 21 (since we are multiplying the weights)
so the updated table record should look like this:
Any suggestions on how to go about this?? Or some examples anyone has in mind?
I would greatly appreciate it!
Here is your trigger (well you need to finish it)
Need to update now that you posted column names.
CREATE TRIGGER [triggername]
ON [data]
AFTER
INSERT
AS
BEGIN
declare #v1 int = (Select weight from lookup1 where id=inserted.scoreid1
,#v2 int = (Select weight from lookup2 where id=inserted.scoreid2)
update data
set calculation = #v1*#v2
where inserted.id = data.id
END
or for multiple inserts:
CREATE TRIGGER [triggername]
ON [data]
AFTER
INSERT
AS
BEGIN
update data
set calculation = l1.weight*l2.weight
from data d
join lookup_1 l1 on d.scoreID1=l1.id
join lookup_2 l2 on d.scoreid2=l2.id
join inserted on inserted.id = d.id
END

cannot insert value NULL into column error shows wrong column name

I've added a new column(NewValue) to my table which holds an int and allows nulls. Now I want to update the column but my insert statement only attempts to update the first column in the table not the one I specified.
I basically start with a temp table that I put my initial data into and it has two columns like this:
create table #tempTable
(
OldValue int,
NewValue int
)
I then do an insert into that table and based on the information NewValue can be null.
Example data in #tempTable:
OldValue NewValue
-------- --------
34556 8765432
34557 7654321
34558 null
Once that's complete I planned to insert NewValue into the primary table like so:
insert into myPrimaryTable(NewValue)
select tt.NewValue from #tempTable tt
left join myPrimaryTable mpt on mpt.Id = tt.OldValue
where tt.NewValue is not null
I only want the NewValue to insert into rows in myPrimaryTable where the Id matches the OldValue. However when I try to execute this code I get the following error:
Cannot insert the value NULL into column 'myCode', table 'myPrimaryTable'; column does not allow nulls. INSERT fails.
But I'm not trying to insert into 'myCode', I specified 'NewValue' as the column but it doesn't seem to see it. I've checked NewValue and it is set to allow int and is set to allow null and it does exist on the right table in the right database. The column 'myCode' is actually the second column in the table. Could someone please point me in the right direction with this error?
Thanks in advance.
INSERT always creates new rows, it never modifies existing rows. If you skip specifying a value for a column in an INSERT and that column has no DEFAULT bound to it and is not identity, that column will be NULL in the new row--thus your error. I believe you might be looking for an UPDATE instead of an INSERT.
Here's a potential query that might work for you:
UPDATE mpt
SET
mpt.NewValue = tt.NewValue
FROM
myPrimaryTable mpt
INNER JOIN #tempTable tt
ON mpt.Id = tt.OldValue -- really?
WHERE
tt.NewValue IS NOT NULL;
Note that I changed it to an INNER JOIN. A LEFT JOIN is clearly incorrect since you are filtering #tempTable for only rows with values, and don't want to update mpt where there is no match to tt--so LEFT JOIN expresses the wrong logical join type.
I put "really?" as a comment on the ON clause since I was wondering if OldValue is really an Id. It probably is--you know your table best. It just raised a mild red flag in my mind to see an Id column being compared to a column that does not have Id in its name (so if it is correct, I would suggest OldId as a better column choice than OldValue).
Also, I recommend that you never name a column just Id again--column names should be the same in every table in the database. Also, when it comes join time you will be more likely to make mistakes when your columns from different tables can coincide. It is much better to follow the format of SomethingId in the Something table, instead of just Id. Correspondingly, the suggested old column name would be OldSomethingId.

How to Update a Single record despite multiple Occurances of the same ID Number?

I have a table that looks like the below table:
Every time the user loan a book a new record is inserted.
The data in this table is derived or taken from another table which has no dates.
I need to update this tables based on the records in the other table: Meaning I only need to update this table based on what changes.
Example: Lets say the user return the book Starship Troopers and the book return is indicated to Yes.
How do I update just that column?
What I have tried:
I tried using the MERGE Statement but it works only with unique rows of data, meaning you get an error if the same ID appears more than once.
I also tried using a basic UPDATE Statement and a JOIN but that's not going well.
I am asking because I have ran out of ideas.
Thanks for reading
If you need to update BooksReturn in target table based on the same column in source table
UPDATE t
SET t.booksreturn = s.booksreturn
FROM target t JOIN source s
ON t.userid = s.userid
AND t.booksloaned = s.booksloaned
Here is SQLFiddle demo
You can do this by simple Update & Insert statement.....
Two table A & B
From B you want to insert data into A if not exists other wise Update that data....
,First Insert into temp table....
SELECT *
INTO #MYTEMP
FROM B
WHERE BOOKSLOANED NOT IN (SELECT BOOKSLOANED
FROM A)
,Second Check data and insert into A.
INSERT INTO A
SELECT *
FROM #MYTEMP
And at last write one simple update statement which update all data of A. If any change then it also reflect to that data otherwise data as it is.
You can also update from #MYTEMP table.