copy single/multiple records from a query and update the same in the queried table - tsql

Ok, I have a query that will bring 1 or more records I know how to update but I need to insert the same PN and Keyvalue to a temp table so I can revert my update at a later time.
I could create a table var and put the records in it then update from the table var and do my insert from the table var.
Is that the most efficient method?

declare #tempTable table(PART nvarchar(30), [ENTDATE] [datetime])
declare #entdate datetime
set #entdate = getdate()
insert into #tempTable(PIW_PART, PIW_ENTDATE)
select mfgp.part, #entdate from [dbo].[PARTMFGS] mfgp
inner join PARTS p on mfgp.MFP_PART = par_code
where mfgp.MFP_MANUFACTPART = 'ddd1' and mfgp.MFP_MANUFACTURER = 'udy'
and (PREVENTREORDERS = '+')
update rp
set PREVENTREORDERS = '-',
UPDATED = getdate(),
UPDATEDBY = 'IONUSER'
from PARTS rp
inner join #tempTable tt on tt.PART collate Latin1_General_BIN = code
--#tempTable
insert into PARTS_temp (PIW_PART, PIW_ENTDATE)
select * from #tempTable

Related

SQL Server During Merge can i store source table value into variable

See my code to understand what i am trying.
DECLARE #LI NVARCHAR(100)
DECLARE #XFundCode VARCHAR(20)
SET #LI = ''
MERGE INTO TblLineItemTemplate Trg
USING
(
SELECT MAX(Section) AS Section,
MAX(LineItem) AS LineItem,
MAX(XFundCode) AS XFundCode,
MAX(StandardDate) AS StandardDate,
MAX(StandardValue) AS StandardValue,
MAX(ActualProvidedByCompany) AS ActualProvidedByCompany,
MAX(TickerID) AS TickerID
FROM #TmpTenQKData
GROUP BY LineItem
) AS Src
ON UPPER(TRIM(Trg.LineItem)) = UPPER(TRIM(Src.LineItem)) AND Trg.TickerID = Src.TickerID
WHEN MATCHED THEN
UPDATE SET
XFundCode = Src.XFundCode,
Action = 'U',
Insertdate = GETDATE()
WHEN NOT MATCHED THEN
SET #LI=Src.LineItem
SET #XFundCode = Src.XFundCode
INSERT
(
TickerID,
LineItem,
XFundCode,
Action,
UserID,
Insertdate
)
VALUES
(
TRIM(#TickerID),
TRIM(#LI),
TRIM(#XFundCode),
'I', #UserID,
GETDATE()
);
i want to store this way without OUTPUT clause
SET #LI=Src.LineItem
SET #XFundCode = Src.XFundCode
is it possible ?
please tell me a way to store source table value into variable during
insert/update from merge statement.
for each insert how can i store source table value by output clause. thanks

PostgreSql: why this update works incorrectly?

There is table t1 in what I need to replace id with new value.
The 2nd table t_changes contains substitutions
old_id->new_id.
But when I do UPDATE the t1 contains the same new id value for all records.
What is incorrect?
The same update works in T-SQL successfully.
drop table t1;
drop table t2;
drop table t_changes;
create table t1
(id INT,name text, new_id INT default(0));
create table t_changes
(old_id INT,new_id int)
insert into t1(id,NAME)
VALUES (1,'n1'),(2,'n2'),(3,'n3');
insert into t_changes(old_id,new_id)
values(1,11),(2,12),(3,13),(4,13)
select * from t1;
select * from t_changes;
-------!!!!
update t1
set new_id = n.new_id
from t1 t
inner join t_changes n
on n.old_id=t.id;
select * from t1
------------------------------
"id" "name" "new_id"
-----------------
"1" "n1" "11"
"2" "n2" "11"
"3" "n3" "11"
This is your Postgres update statement:
update t1
set new_id = n.new_id
from t1 t inner join
t_changes n
on n.old_id = t.id;
The problem is that the t1 in the update refers to a different t1 in the from. You intend for them to be the same reference. You can do this as:
update t1
set new_id = n.new_id
from t_changes n
where n.old_id = t.id;
Your syntax is fairly close to the syntax supported by some other databases (such as SQL Server). However, for them, you would need to use the table alias in the update:
update t
set new_id = n.new_id
from t1 t inner join
t_changes n
on n.old_id = t.id;
How about doing this instead:
update t1
set new_id = (SELECT new_id FROM t_changes WHERE old_id=id);
Note that if for some row in t1 there is no corresponding row in t_changes, this will change t1.new_id to NULL.

Converting Traditional IF EXIST UPDATE ELSE INSERT into MERGE is not working?

I am going to use MERGE to insert or update a table depending upon ehether it's exist or not. This is my query,
declare #t table
(
id int,
name varchar(10)
)
insert into #t values(1,'a')
MERGE INTO #t t1
USING (SELECT id FROM #t WHERE ID = 2) t2 ON (t1.id = t2.id)
WHEN MATCHED THEN
UPDATE SET name = 'd', id = 3
WHEN NOT MATCHED THEN
INSERT (id, name)
VALUES (2, 'b');
select * from #t;
The result is,
id name
1 a
I think it should be,
id name
1 a
2 b
You have your USING part slightly messed up, that's where to put what you want to match against (although in this case you're only using id)
declare #t table
(
id int,
name varchar(10)
)
insert into #t values(1,'a')
MERGE INTO #t t1
USING (SELECT 2, 'b') AS t2 (id, name) ON (t1.id = t2.id)
WHEN MATCHED THEN
UPDATE SET name = 'd', id = 3
WHEN NOT MATCHED THEN
INSERT (id, name)
VALUES (2, 'b');
select * from #t;
As Mikhail pointed out, your query in the USING clause doesn't contain any rows.
If you want to do an upsert, put the new data into the USING clause:
MERGE INTO #t t1
USING (SELECT 2 as id, 'b' as name) t2 ON (t1.id = t2.id) --This no longer has an artificial dependency on #t
WHEN MATCHED THEN
UPDATE SET name = t2.name
WHEN NOT MATCHED THEN
INSERT (id, name)
VALUES (t2.id, t2.name);
This query won't return anything:
SELECT id FROM #t WHERE ID = 2
Because where is no rows in table with ID = 2, so there is nothing to merge into table.
Besides, in MATCHED clause you are updating a field ID on which you are joining table, i think, it's forbidden.
For each DML operations you have to commit (Marks the end of a successful the transaction)Then only you will be able to see the latest data
For example :
GO
BEGIN TRANSACTION;
GO
DELETE FROM HumanResources.JobCandidate
WHERE JobCandidateID = 13;
GO
COMMIT TRANSACTION;
GO

tsql trigger behaves abnormally

I have a trigger which is as follows:
ALTER TRIGGER [trigger_CATEGORY_VALUE_ID] ON [dbo].[tblA]
FOR UPDATE
AS
SET NOCOUNT ON
IF ( UPDATE([CATEGORY_VALUE_ID]))
BEGIN
INSERT INTO [dbo].[htblB]
( ID
, CATEGORY_VALUE_ID
, STATUS_END_DATE
, STATUS_END_DATE_SOURCE)
SELECT
t.ID
, t.CATEGORY_VALUE_ID
, GETDATE()
, t.UPDATE_SOURCE
FROM [dbo].[tblCAPITATION] t
INNER JOIN inserted ins
ON t.CATEGORY_VALUE_ID = ins.CATEGORY_VALUE_ID
END
What it needs to do is insert a new row in htblB when the column CATEGORY_VALUE_ID is updated. It works fine if only one row is updated. But if it has multiple row updates, then 2 to the power number of rows updated amount of new rows are inserted in htblB.
UPDATE dbo.tblCAPITATION
SET CAPITATION_STATUS_CATEGORY_VALUE_ID = '80574', UPDATE_SOURCE = 'TEST3'
WHERE CAPITATION_ID = 2 OR CAPITATION_ID = 3
This statement will insert 4 new rows to htblB instead of 2.
May you please shed some light on why this is hapening and how to prevent it?
Thanks!
I'm going to assume that ID is the primary key, if so then you should be joining inserted on ID not category_value_id
ALTER TRIGGER [trigger_CATEGORY_VALUE_ID] ON [dbo].[tblA]
FOR UPDATE
AS
SET NOCOUNT ON
IF ( UPDATE([CATEGORY_VALUE_ID]))
BEGIN
INSERT INTO [dbo].[htblB]
( ID
, CATEGORY_VALUE_ID
, STATUS_END_DATE
, STATUS_END_DATE_SOURCE)
SELECT
t.ID
, t.CATEGORY_VALUE_ID
, GETDATE()
, t.UPDATE_SOURCE
FROM [dbo].[tblCAPITATION] t
INNER JOIN inserted ins
ON t.ID = ins.ID
END

Help needed with Update trigger t-sql

How to create trigger on Update in transact sql, to set another field in updated row?
For example:
UPDATE table SET true_false = 1 WHERE ID = #ID
will run command:
UPDATE table SET date = GETDATE() WHERE ID = #ID
.
Please help. I can't figure it out ;)
Keep in mind that you must always allow for the possibility of multi-row updates in any trigger you write.
create trigger tr_U_YourTable
on YourTable
for Update
as
begin
if update(true_false)
update yt
set date = getdate()
from Inserted i
inner join Deleted d
on i.ID = d.ID
inner join YourTable yt
on i.ID = yt.ID
where coalesce(i.true_false,0) <> coalesce(d.true_false,0)
end