Creating a Stored Procedure - sql

I am trying to create a stored procedure that will allow me to update the ActualArrivalDate and ActualDepartureDate in a TripStop table where StopTypeCode = Drop in the TripStopOrder table.
Create Proc spUpdateTable
#OrderID int, #ArrivalDate datetime, #DepartureDate datetime
As
Begin
Begin Transaction
Select * From dbo.TripStopOrder
Join dbo.TripStop ON dbo.TripStopOrder.TripStopID = dbo.TripStop.TripStopID
Where OrderID = ''and StopTypeCode ='Drop'
Once I find this record I need to grab the TripStopId and pass it into the Update statement.
Not sure how to this...can I use a temp table then run another Select statement to pick up the TripStopID?
Update dbo.TripStop SET ArrivalDate='',DepartureDate=''
Where TripStopID = ''
End
Commit
Any ideas or suggestions would be greatly appreciated. ~Newbie~

You can assign the value to a variable such as #TripStopId:
DECLARE #TripStopId INT
Select #TripStopid = TripStopId
From dbo.TripStopOrder
Join dbo.TripStop ON dbo.TripStopOrder.TripStopID = dbo.TripStop.TripStopID
Where OrderID = ''and StopTypeCode ='Drop'
Then you can use it in your UPDATE statement.
Update dbo.TripStop SET ArrivalDate='',DepartureDate=''
Where TripStopID = #TripStopId

Instead of doing the SELECT and then the UPDATE, just change your WHERE clause in your UPDATE statement:
WHERE TripStopID = (SELECT T.TripStopID FROM TripStopOrder O
INNER JOIN TripStop T ON O.TripStopID = T.TripStopID
WHERE OrderID = #OrderID AND StopTypeCode = 'Drop')

Related

trigger problems on sql

need to run a trigger that updated a column in my customers table. the idea is that once the customers table is updated the trigger needs to update a different column with a scalar. the scalar is calculated by a function.
I don't know where is the issue but something is going very wrong.
create FUNCTION calculateVirtualCashForCustomer(#email varchar)
RETURNS float
AS BEGIN
DECLARE #virtualCashToAdd float
select #virtualCashToAdd= (B.Price*(cast(O.Quantity as float)))*0.1
from CUSTOMERS AS C JOIN BOXES AS B ON C.Email = B.Email JOIN ORDERS AS O ON O.BoxID = B.BoxID
where C.Email = #email
RETURN #virtualCashToAdd
End
CREATE TRIGGER updateVirtualCash
on CUSTOMERS
AFTER UPDATE
AS
DECLARE #Mail varchar(50)
begin
update CUSTOMERS
set [Virtual Cash] = [Virtual Cash] + (dbo.calculateVirtualCashForCustomer(#Mail))
where #Mail= (select Email from dbo.Top10byMoney)
end
I think that the issue is in where #Mail= (select Email from dbo.Top10byMoney) of the trigger. you can try add top 1 in select, so to compare only with a selected value
Example:
CREATE TRIGGER updateVirtualCash
on CUSTOMERS
AFTER UPDATE
AS
DECLARE #Mail varchar(50)
SET #Mail= (select Email from dbo.Top10byMoney)
begin
update CUSTOMERS
set [Virtual Cash] = [Virtual Cash] + (dbo.calculateVirtualCashForCustomer(#Mail))
where Email=#Mail
end
for solve the values null problem, you can use ISNULL
set [Virtual Cash] = ISNULL([Virtual Cash],0) + ISNULL(dbo.calculateVirtualCashForCustomer(#Mail),0)

Set Value From Action Update, Delete, Inserted in Stored Procedure SQL

I have created my stored procedure, but I am confused how to set one column of from my table.
This is separate of my code:
CREATE PROC [dbo].[SP_Gabungan]
#REPORT_DT DATE
AS
BEGIN
DECLARE #action NVARCHAR(10),
#insCount INT = (SELECT COUNT (*) FROM INSERTED),
#delCount INT = (SELECT COUNT (*) FROM DELETED)
SELECT
#REPORT_DT AS REPORT_DATE,
FD.BRANCH_CODE AS [BRANCH],
#action AS [ID_OPERATIONAL], -- I want to set this value as 1(if there is a new input data, 2
-- (if there is updated data), 3 (if there is deleted data) from
-- from another field
BR.REGULATOR_BRANCH as [RG_BRANCH]
FROM
[DBO].[F_RR_FUNN] FD
LEFT JOIN
[DBO].[MS_BRANCH] BR ON BR.BRANCH_CD = FD.BRANCH_CODE
WHERE
FD.GROUP_PRODUCT = 'CA'
AND Y17sa = '1'
AND FD.REPORT_DATE = #REPORT_DT
END
How do I set column ID_OPERASIONAL as 1 (if there is a new data from another field), 2 for exists updated data from another field, 3 for deleted data from another field in a stored procedure.
ERROR from this code is:
Invalid object name 'INSERTED'
The problem the ERROR shows is that you cannot use deleted/inserted tables in stored procedures but just accessible in triggers.
If you want to have the count of inserted records or deleted records in a table there are two ways for doing this which the easiest one is:
Create you stored procedure like this:
CREATE PROC [dbo].[SP_Gabungan]
#REPORT_DT DATE,#DeletedCount INT , #InsertedCount Int
AS
BEGIN
...
Create a Trigger after insert and delete (so you can have inserted/deleted tables)
Then get the count just like you did in your code:
DECLARE #action nvarchar (10),
#insCount int = (SELECT COUNT (*) FROM INSERTED),
#delCount int = (SELECT COUNT (*) FROM DELETED)
Call your stored procedure in the Trigger and pass the #insCount and #delCount as inputs
EXEC [dbo].[SP_Gabungan]
#REPORT_DT = GETDATE() , #InsertedCount = #insCount , #DeletedCount = #delCount
A similar question is this for more other ways like temp tables or...
How use inserted\deleted table in stored procedure?
Also the link below is a question asking defining a trigger for both delete and insert so you can use both deleted/inserted tables together
SQL Trigger on Update, Insert, Delete on non-specific row, column, or table
Second way which is better when you are doing all these process a lot, is to get the log of your inserts or updates or deletes so you dont use triggers which reduce performance of your process.
(If usefull I can recommend some ideas for saving table logs)
CREATE PROC [dbo].[SP_Gabungan]
#REPORT_DT DATE
,#DeletedCount INT
,#InsertedCount INT
,#UpdateCount INT
AS BEGIN
DECLARE #action INT
SET #action = CASE
WHEN #InsertCount <> 0 THEN 1
WHEN #UpdateCount <> 0 THEN 2
WHEN #DeletedCount <> 0 THEN 3
END
SELECT
#REPORT_DT AS REPORT_DATE,
FD.BRANCH_CODE AS [BRANCH],
#action AS [ID_OPERATIONAL],
BR.REGULATOR_BRANCH as [RG_BRANCH]
FROM
[DBO].[F_RR_FUNN] FD
LEFT JOIN
[DBO].[MS_BRANCH] BR ON BR.BRANCH_CD = FD.BRANCH_CODE
WHERE
FD.GROUP_PRODUCT = 'CA'
AND Y17sa = '1'
AND FD.REPORT_DATE = #REPORT_DT END
CREATE TRIGGER [YourTriggerName]
AFTER INSERT/UPDATE/DELETE ON [db].[tablename]
FOR EACH ROW
BEGIN
DECLARE
#insCount int = (SELECT COUNT (*) FROM New), -- New in MySQL is same as inserted,deleted,updated
#delCount int = (SELECT COUNT (*) FROM Old),
#upCount int = (SELECT COUNT (*) FROM New),
EXEC [dbo].[SP_Gabungan]
#REPORT_DT = GETDATE()
,#DeletedCount = #delCount
,#InsertedCount = #insCount
,#UpdateCount = #upCount
END

How to create procedure with multiple string select query in sql?

I want to create procedure with multiple string select query.I want to insert data to table variable and join that temp table with other table.
I don't want to create temp table as real tables. I want to insert data to memory temp table.
Here is my procedure,
CREATE PROCEDURE sp_TempBatch
AS
DECLARE #TempBatchSerial TABLE
(
ID int,
Name nvarchar(200),
StockType nvarchar(50),
ItemNo nvarchar(50)
)
DECLARE #TempQuery as nvarchar(MAX)='',
#VendorQuery as nvarchar(MAX)=''
BEGIN
SET #TempQuery='SELECT ID,Name,'
IF StockType = '1'
BEGIN
SET #TempQuery += ' ''Batch'' as StockType,'
END
ELSE
BEGIN
SET #TempQuery += ' ''Serial'' as StockType,'
END
SET #TempQuery += 'ItemNo INTO #TempBatchSerial
FROM Stock'
EXEC (#TempQuery)
SET #VendorQuery+=' SELECT #TempBatchSerial.* FROM #TempBatchSerial
INNER JOIN Vendor
ON #TempBatchSerial.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey'
EXEC (#VendorQuery)
END
When execute procedure show error message of Must declare the table variable "#TempBatchSerial"
You have to refer to #tempBatchSerial via an Alias
That's the only way #tempTables can be referred or linked to.
SELECT T.* FROM #TempBatchSerial T
INNER JOIN Vendor
ON T.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey
If that doesn't work you can try to put the #tempTable in the #vendorQuery text.

How to execute a Stored Procedure on the results of a SQL Server CTE

I have a CTE which returns DISTINCT ID's. I want to execute a scalar function on each of the Id's returned.
WITH cte (reqID) as
(SELECT DISTINCT pol.ReqID FROM
LOG_PackingListItems pli
JOIN
v_PO_LN pol on pol.PO_ID = pli.PoId
WHERE
pli.PackingListHeaderID = 1)
EXEC dbo.spUpdateLOG_ReqCompleteCheck reqID -- Error "Incorrect Syntax near EXEC"
The EXEC line is what I want to make work but I get a syntax error. Not sure if what I want to do is possible or if I do in fact have a syntax error. Any ideas?
EDIT:
I'm adding the code for the Stored Procedure since I am now using a Table-Valued Parameter as suggested by realnumber3012
EDIT:
I have changed my CTE code so it populates a Table-Type as realnumber has suggested. I now get an error when executing spUpdateLOG_ReqCompleteCheck "Subquery returns more than one value."
DECLARE #ReqIdTVP as ReqIdType;
DELETE FROM #ReqIDTVP;
with cte (reqID) as
(select distinct pol.ReqID from
LOG_PackingListItems pli
join
v_PO_LN pol on pol.PO_ID = pli.PoId
where
pli.PackingListHeaderID = #PackingListHeaderID)
INSERT INTO #ReqIdTVP
SELECT * FROM cte
EXEC dbo.spUpdateLOG_ReqCompleteCheck #ReqIdTVP
Sproc code :
Alter PROCEDURE spUpdateLOG_ReqCompleteCheck
(#ReqIdTVP ReqIdType READONLY )
AS
BEGIN
DECLARE #TotalOrd int
DECLARE #TotalRx int
DECLARE #ReqID char(8)
SET #ReqID = (SELECT ReqID FROM #ReqIdTVP)
SET #TotalOrd = (SELECT ISNULL(SUM(ORD_QTY),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
SET #TotalRx = (SELECT ISNULL(SUM(TotalRxSite),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
IF #TotalRx >= #TotalOrd
BEGIN
DECLARE #curDate datetime
SET #CurDate = ISNULL(#CurDate,GetDate())
SET NOCOUNT ON;
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
END
END
Seems that the only thing your stored proc does is to update a logging table: (it only changes state via this statement and doesn't return anything????
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
How about splitting the logic out and write a function (inline if possible that will evaluate the condition you are looking for (didn't really understand what you are doind there) -- run the function on the results of the CTE (wrapping it in another CTE if you want) with the CROSS APPLY OPERATOR.
You'd end up with a result set that looks like [ReqId], [UpdateLog] (where updateLog is a BIT)
Then simply do a set based upadete JOINING to the results:
UPDATE l SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
FROM
LOG_ReqHeader AS l
JOIN <CTE> AS c ON c.[ReqID] = l.[ReqID]
WHERE
c.[UpdateLog] = 0x1
Does this make any sense?

UPDATE Select Statement with Multiple Joins

I am trying to update data in a Contacts_CSTM table based on data in a Project_CSTM table. This is the query I'm using, but I get an error: "Conversion failed when converting from a character string to uniqueidentifier"
ALTER PROCEDURE Insurance_Check_Expiration
#ID_C AS NVARCHAR (55) = ID_C
AS
BEGIN
SET NOCOUNT ON
IF EXISTS(SELECT * FROM CONTACTS_CSTM WHERE ID_C = #ID_c)
Update contacts_cstm set insurance_expired_label_c = 'INSURANCE EXPIRED'
WHERE DRIVERS_LICENSE_NUMBER_C IS NOT NULL AND #ID_C=
(SELECT cc.id_c
FROM PROJECT_CSTM PC
JOIN PROJECT P
ON P.ID = PC.ID_C
JOIN PROJECT_RELATION PR
ON PR.PROJECT_ID = P.ID
JOIN CONTACTS C
ON C.ID = PR.RELATION_ID
JOIN CONTACTS_CSTM CC
ON CC.ID_C = C.ID
WHERE CC.ID_C = #ID_C AND INSURANCE_EXPIRED_C ='1')
Thanks.
For one, you're setting the value of #ID_C to a value (ID_C) which is obviously not a valid GUID.
This is the functional equivalent of what you did, run it and you'll get the same error.
CREATE PROCEDURE Insurance_Check_Expiration
#ID_C AS NVARCHAR (55) = ID_C
AS
BEGIN
DECLARE #A UNIQUEIDENTIFIER
SET #A = #ID_C
END
exec Insurance_Check_Expiration
EDIT: Here's a functional example based on the OP's comments:
CREATE TABLE GUIDExample (ID_C UNIQUEIDENTIFIER)
GO
CREATE PROC GuidExample_Insert #ID_C UNIQUEIDENTIFIER
AS
BEGIN
SELECT #ID_C
END
GO
CREATE TRIGGER GUID_Example ON GUIDExample
AFTER INSERT
AS
DECLARE #ID_C UNIQUEIDENTIFIER
SELECT #ID_C = ID_C
FROM Inserted
EXEC GuidExample_Insert #ID_C
GO
DECLARE #SampleGUID UNIQUEIDENTIFIER
SET #SampleGUID = NEWID()
INSERT GUIDExample (ID_C)
VALUES(#SampleGUID)