How can I combine two stored procedures? - sql

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.

Related

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

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.

How to Update a column Before Select?

I am setting a stored procedure for select and I want to update the value of one column in the database Before doing the Select.
This is what I tried but it's not working.
#roleID int and #query varchar(240)
SELECT
EP.Equipe_Projet_Id AS PROJET_ID,
U.USR_ID,
CleRepartition = CASE
WHEN #RoleID = 1 AND #query IS NOT NULL
THEN 100
AND (UPDATE EQUIPE_PROJET SET CleRepartition = 100
WHERE EP.Equipe_Projet_Id = #PROJET_ID AND EP.Role_Id = 3)
ELSE NULL
END
FROM
[EQUIPE_PROJET] EP
Expecting update of column on database and having it's value
i want to update the value of Column CleRepartition in the database while selecting.
This is not possible in a SELECT query. A SELECT retrieves data from the database. An UPDATE modifies data. These are two separate statements and cannot be combined.
You are doing this work in a stored procedure. Within a stored procedure, you can run an UPDATE and SELECT in any order, so you can accomplish both tasks. If you are concerned about data changing in the database between the two statements, you can wrap them in a transaction.
Stored procedure can do update then select after.
So I added the query of update in the beginning, then I do the select.
Like this:
UPDATE EP
SET CleRepartition = CASE
WHEN #RoleID = 1 AND #query IS NOT NULL
THEN 100
AND (UPDATE EQUIPE_PROJET
SET CleRepartition = 100
WHERE EP.Equipe_Projet_Id = #PROJET_ID
AND EP.Role_Id = 3)
ELSE NULL
END
FROM [EQUIPE_PROJET] EP
SELECT
EP.Equipe_Projet_Id AS PROJET_ID,
U.USR_ID,
CleRepartition
FROM
[EQUIPE_PROJET] EP
I hope that this will help someone.

How to store data from a SELECT statement and use that data to loop with an UPDATE statement

I am using PLSQL and I want to store the query results form SELECT statement in an array and then I want to loop using the elements from that array to UPDATE all the rows. The problem with the code below is that it returns a single-row. Sub-query returns more than one row because he is trying to set more than one variable in a row. Can you help me in this situation?
This is my code:
CREATE OR REPLACE PROCEDURE looping IS
BEGIN
FOR rec IN (SELECT IID FROM DATMCCN0)
LOOP
UPDATE DATMCCN0
SET E_NOME = (SELECT I_NOME FROM DAT_CCNCONFIG0 INNER JOIN DATMCCN0 ON DAT_CCNCONFIG0.I_NOME = DATMCCN0.CAPLIC where DATMCCN0.IID = rec.IID)
where IID = rec.IID;
END LOOP;
END;
EXECUTE looping;
You do not need a loop and can do it all in one MERGE statement (assuming your correlated query returns a single row for each IID):
CREATE OR REPLACE PROCEDURE looping
IS
BEGIN
MERGE INTO DATMCCN0 dst
USING (
SELECT b.IID,
I_NOME
FROM DAT_CCNCONFIG0 a
INNER JOIN DATMCCN0 b
ON a.I_NOME = b.CAPLIC
) src
ON ( src.IID = dst.IID)
WHEN MATCHED THEN
UPDATE SET E_NOME = src.I_NOME;
END;
If it does not then you will need to get only a single row, something like this:
CREATE OR REPLACE PROCEDURE looping
IS
BEGIN
MERGE INTO DATMCCN0 dst
USING (
SELECT b.IID,
MAX( I_NOME ) AS I_NOME
FROM DAT_CCNCONFIG0 a
INNER JOIN DATMCCN0 b
ON a.I_NOME = b.CAPLIC
GROUP BY b.IID
) src
ON ( src.IID = dst.IID)
WHEN MATCHED THEN
UPDATE SET E_NOME = src.I_NOME;
END;
One literal answer for your question "How to store data from a SELECT statement and use that data [to loop] with an UPDATE statement" would be a statement like this:
UPDATE
(SELECT src.E_NOME, dst.I_NOME
FROM DAT_CCNCONFIG0
JOIN DATMCCN0 src ON DAT_CCNCONFIG0.I_NOME = scr.CAPLIC
JOIN DATMCCN0 dst ON src.IID = dst.IID)
SET E_NOME = I_NOME;
However, it does not solve your problem that a single-row subquery returns more than one. Have a look at MT0's answer for that.

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.