Run multiple update statements on same table in stored procedure using values from table vlued parameter - sql

I want to update a column in a table uing values from a table valued parameter, then I want to update another column (same rows) depending on the value of the column that was updated on first statement. Here is the code:
#reports as WhatsTableType ReadOnly
BEGIN
update dbo.tblappointments Set dbo.tblappointments.D_report = r.D_report
from dbo.tblappointments as A inner join #reports as r on A.appointmentID = r.appointmentID;
update dbo.tblappointments Set dbo.tblappointments.WantSMS = 0
from dbo.tblappointments as A inner join #reports as r on A.appointmentID = r.appointmentID
where A.D_report = 'Read' or A.D_report = 'DEVICE';
END
The table parameter contain two columns (appointmentID, D_report). I guess I can use single update statement using IIF, I'm not sure about the best way to do this.
Thank you.

Depending on what you want WantSMS to become if D_Report is something else, or NULL, or if it should depend on the existing value in the table, you can do this in one statement as follows:
UPDATE A Set
A.D_report = r.D_report,
A.WantSMS = CASE
-- need to check R for the _new_ value:
WHEN r.D_Report IN ('Read', 'DEVICE') THEN 0
ELSE A.WantSMS END
FROM dbo.tblappointments as A
INNER JOIN #reports as r
ON A.appointmentID = r.appointmentID;
IIF is just fancy CASE but I find CASE a lot more flexible. YMMV.

Related

How can I combine two stored procedures?

I have one problem here....please help me.
I have a table called Master_BoxStock and I created a stored procedure like this:
BEGIN
UPDATE Master_BoxStock
SET currentQty = currentQty - #insertQty
WHERE boxName = #newBoxName
END
After that I want to take the result, update it again like this:
UPDATE Master_BoxStock
SET currentQty = Result
WHERE warehouseName = 'Display'
How should I do that?
Based on the syntax I would say you are using SQL Server.
If I'm correct, you can use the OUTPUT clause:
DECLARE #Output as table
(
currentQty int -- (I'm guessing the data type here....)
)
UPDATE Master_BoxStock
SET currentQty = currentQty - #insertQty
OUTPUT Inserted.currentQty INTO #Output
WHERE boxName = #newBoxName
UPDATE m
SET currentQty = o.currentQty
FROM Master_BoxStock m
CROSS JOIN #Output o
WHERE warehouseName = 'Display'
Note:
I've used cross join assuming your first update only effects one row. If that's not the case, you'll get multiple rows in the table variable and will have to add to the table variable also the row identifier so that you will know what row to pick.

Update all rows with one SQL query

I'm using this PostgreSQL table to store configuration variables:
CREATE TABLE SYS_PARAM(
SETTING_KEY TEXT NOT NULL,
VALUE_TYPE TEXT,
VALUE TEXT
)
;
How I can update all configuration settings values using one SQL statement?
you can use where true at the end and it update all rows in your table.
for example:
UPDATE table_name set table_column = value where true;
it will be update all rows in one SQL query.
If you plan on performing these updates more than once or twice over time, it would be good to have a function handle this for you. You could use the table itself as a type for a variadic parameter within a function, like so:
-- The function
CREATE OR REPLACE FUNCTION update_sys_param(VARIADIC params sys_param[])
RETURNS VOID
AS $$
BEGIN
UPDATE sys_param
SET value_type = upd.value_type, value = upd.value
FROM
sys_param src
INNER JOIN
UNNEST(params) upd
ON (src.setting_key = upd.setting_key);
END; $$ LANGUAGE PLPGSQL;
-- To call it
SELECT update_sys_param(('SMTP_PORT','int','123'),('SMTP_OTHER','text','435343'));
However, if this is a one-time update you can try either of these two:
UPDATE using JOIN
UPDATE sys_param
SET
value_type = new.value_type,
value = new.value
FROM
sys_param src
INNER JOIN
new_params new --< this table/view/cte must already exist or you must create it.
ON (src.setting_key = new.setting_key);
UPDATE using CASE
UPDATE sys_param
SET value = CASE setting_key
WHEN 'SMTP_PORT' THEN '2100'
(..and so on..)
END;
-- You would need to repeat the case statement if you intend on updating the value_type, too.
I guess you can achieve this by doing correlated update.
Please refer to the posts below:
https://www.ibm.com/support/knowledgecenter/ssw_i5_54/sqlp/rbafyexsub4.htm
You can join against a list of values and update with that:
update sys_param
set value = v.new_value
from (
values
('SMTP_PORT', '123'),
('SMTP_SERVER', 'new_server'),
('SMTP_USERNAME', 'Arthur')
) as v(skey, new_value)
where v.skey = sys_param.setting_key;
This assumes that setting_key is the primary key of that table.

SQL Server After Update Trigger - Single Table - 2 Columns

I have a table (dbo.membersdatatable) that has multiple columns. I would like this trigger to update a column called "memberstatus" when "memberdesignation" is updated to a value of "10" from a value of "9".
-------SQL STATEMENT BELOW---------------
IF UPDATE([MemberDesignation])
--need to make it so it will recognize when memberdesignation = 10
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
FROM dbo.MembersDataTable AS mdtbl
INNER JOIN inserted AS i ON i.StudentID = mdtbl.StudentID
Use triggers SPARINGLY. For example, my system has 138 tables, 550 stored procedures and only 28 triggers. I wish I had less.
But if you decide a trigger is required, it will look something like this:
CREATE TRIGGER [t_MemberDesignationSideEffect] ON [dbo].MembersDataTable
FOR UPDATE
AS
SET NOCOUNT ON
IF NOT ( UPDATE([MemberDesignation]) ) RETURN
-- REMINDER: All triggers can and will fire for a set of rows...not just one
UPDATE mdtbl
SET MemStatus = '0'
FROM inserted i
JOIN dbo.MembersDataTable mdtbl on i.StudentID = mdtbl.StudentID
JOIN deleted d on d.StudentID = mdtbl.StudentID
WHERE i.memberdesignation = '10'
and d.memberdesignation = '9'
GO
You are writing an update trigger on table. Here you can use deleted and inserted magic tables. In case of update trigger:
Deleted table contains the row as it was before the UPDATE statement.
Inserted table contains the row as it is after the UPDATE statement.
create trigger update_member_status
on membersdatatable
for update
as
begin
declare #old_designation int
declare #new_designation int
set #old_designation = (select memberdesignation from deleted)
set #new_designation = (select memberdesignation from inserted)
if (#old_designation = 9 and #new_designation = 10)
begin
update membersdatatable
set memstatus = '0'
from membersdatatable as mdtbl
inner join inserted as i on i.StudentID = mdtbl.StudentID
end
end
You are going to update member status of all rows with a
memberdesignation = 10
you can probably add conditions to this query in order to update only the ones you want by using a date field or another
Simply call this procedure after updating your table
CREATE PROCEDURE USP_MemberStatusRules()
AS
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
WHERE memberdesignation = 10
AND .....
AND .....
GO

SQL Trigger Using Variables

I need help creating this trigger, any help will be appreciate it, I can't save this script, it's saying 'Invalid column name OfferId'. But I checked all the columns names and they are correct
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
DECLARE #OfferId char(5) SET #OfferId = (Select OfferId From INSERTED i, OrderOffer a Where i.OrderOfferid = a.OrderOfferid);
DECLARE #UnitsAvailable int SET #UnitsAvailable = (Select SUM(UnitsAvailable) From dbo.Offer Where OfferId=#OfferId);
UPDATE dbo.OrderOffer SET dbo.UnitsAvailable = #UnitsAvailable
FROM INSERTED i, OrderOffer a
WHERE i.OrderOfferid = a.OrderOfferid
END
Try this:
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
UPDATE a
SET dbo.UnitsAvailable =
(
Select SUM(b.UnitsAvailable)
From dbo.Offer b
Where b.OfferId = a.OfferId
)
FROM OrderOffer a
INNER JOIN INSERTED i
ON i.OrderOfferid = a.OrderOfferid
END
NB: I removed the variables since that would assume you only updated one row at a time. Even if the update runs over multiple rows, the above should still work.

Update Trigger Affecting Too Many Rows

I wrote the following trigger:
begin
update NFL.TeamStatistics
set Passing_Yards = (select sum(Quarterbacks.Yards)
from NFL.Quarterbacks
where Quarterbacks.Team = inserted.Team)
from NFL.Quarterbacks
inner join inserted on Quarterbacks.Team = inserted.Team;
Whenever someone updates the passing yards in the table about quarterbacks, it should automatically set NFL.TeamStatistics.Passing_Yards to the sum of each team's passing yards.
I used the following update statement to test it:
update NFL.Quarterbacks
set Quarterbacks.Yards = 4000
where Team = 'PIT';
However, in the table NFL.TeamStatistics it set the passingyards for all teams to 4000 instead of just for PIT. What is the matter?
You need to add a where clause and column in NFL.TeamStatistics that you want to compare to
e.g:
begin
update NFL.TeamStatistics
set Passing_Yards = (select sum(Quarterbacks.Yards)
from NFL.Quarterbacks
where Quarterbacks.Team = inserted.Team)
from NFL.Quarterbacks
inner join inserted on Quarterbacks.Team = inserted.Team
where Team = Quarterbacks.Team;
Assuming you were comparing to Quaterbacks.Team
You should use where clause in your update statement in order to filter data you are going to update.