SQL Update Stored Procedure involving Subqueries - sql

I have a few table's in my DB.
I am trying to update the rota table using a SQL stored procedure. I want the user to be able to type in, for example;
Name: Adam Brookes
Shift: Middle Day
On Call: Secondary
and using a subquery have it look up the id's of those and place them into the rota table. At the moment I am testing in Postman where I can define the 'date' and 'datekey' manually.
My Stored Procedure currently looks like this;
ALTER PROCEDURE [dbo].[RotaUpdateItems]
#date_key int,
#date date,
#user_id varchar(max),
#shift_type_id int,
#type_call_id int
AS
BEGIN
SET NOCOUNT ON;
UPDATE rota
SET date = #date,
user_id = (
SELECT user_id
FROM staff s
WHERE s.first_name LIKE 'ABC%'
),
shift_type_id = (
SELECT shift_type_id
FROM shifts h
WHERE h.shift_type LIKE 'ABC%'
),
type_call_id = (
SELECT type_call_id
FROM on_call c
WHERE c.type_of_call LIKE 'ABC%')
WHERE date_key = #date_key
END
I have referenced this question to get the LIKE 'ABC%' code to see if that would help convert "Primary" into '1', but this did not fully answer my question
I also researched this answer from John to see if a join is necessary when running an update query but this did not fully answer my question.

Related

Stored Procedure Output Value Not Updating

Everyone.
I have created a stored procedure in SQL Server 2016 that has the purpose of giving the of the total number of sales recommendations [#Recommendation in Recommendations table] in my table that contain this string: '____Document DOB in sales record' past any given date. I want to put this result into a temporary table as well.
Helpful Table Info:
Reference Table where I am grabbing the data: Recommendations
The relevant fields in the Recommendations table are #Recommendation, and #SalesProcessTime
The #Recommendation field is a VARCHAR(255), and #SalesProcessTime is a DATETIME
Regardless of what I change the date to - or even if I make it =, >=, etc - the same numeric value is displayed.
If you need anything else, please don't hesitate to ask me.
USE [Test_Database]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
--IF OBJECT_ID('tempdb..DocDOB') IS NOT NULL DROP TABLE #DocDOB
DECLARE #NumRecs INT;
-- Count of the number of recommendations
SELECT #NumRecs = COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
CREATE TABLE ##RefCount (NumberOfRecs INT);
INSERT INTO ##RefCount
SELECT #NumRecs
END
EXEC usp_SalesRefCount
SELECT * FROM ##DocDOB
Why are you using a global temporary table at all? Why not just return the results from the procedure directly? eg:
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
DECLARE #NumRecs INT;
SELECT #NumRecs = COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
SELECT #NumRecs NumRecs
END
You are inserting data into a global temporary table "##RefCount" and selecting from another one "##DocDOB", so the result will never change.
Anyway, as #DavidBrowne said, you should just return the result directly
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
SELECT COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
END
Also, another idea, maybe get that date as a parameter, so you don't have to update the stored procedure when you need to select by another date
CREATE PROCEDURE usp_SalesRefCount
#selectDate DateTime
AS
BEGIN
SELECT COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > #selectDate
END

Need to log identifiers from select query recordset along with date/time stamp

I would like to log all records generated by a sql select statement in an SSRS report into a table for later reference at the time the report is run.
One idea is to append the unique ID to the reference table and then perform the full query with the additional data for the full record set, but i feel like there is probably a better way.
One way would be to use a STORED PROCEDURE for your SSRS report instead of hard coding the query in the RDL. Then, you could leverage the OUTPUT clause and log the query execution, and return the results. The proc would look something like this:
create procedure myProc (#param1 int)
as
begin
declare #resultTable table (id int, c1 char(4), c2 char(4))
insert into myloggingtable
output INSERTED.id, INSERTED.c2, INSERTED.c3 into #resultTable
select
id,
c1,
c2,
RunDateTime = getdate(),
from SomeTable
where id = #param1
select * from #resultTable
end
Here, I would have an auto-incremented key on the myloggingtable and the RunDateTime would be logged as the execution time.

Find the status change

I have a master table , say mast_tbl, where every change on this table goes as a different entry into hst_mast_tbl. There is col in both the tables which talks about status change. Now if I want to track the number of records for which only the status has changed in the past 10 days, how can I achieve it in a simplest way?
To use lag function, sometimes there might be more column getting updated in master table so more than 1 record in my history table. So how can I achieve the same.
Thanks in advance.
Have you tried using triggers? If you are using SQL Server this might help you.
You can utilize the trigger by using FOR UPDATE when certain column is edited on your table you could say
CREATE TRIGGER [dbo].[trg_update] ON [dbo].[tbl_trans]
WITH EXECUTE AS CALLER
FOR UPDATE
AS
BEGIN
DECLARE #transaction VARCHAR(15)
DECLARE #action VARCHAR(10)
DECLARE #ref_id INT
DECLARE #trail_date DATETIME
SELECT
#transaction = '<your table here>',
#action = 'Update',
#ref_id = i.trans_id,
#trail_date = GETDATE()
FROM INSERTED i
INSERT INTO tbl_auditTrail (audit_trans,action,ref_id,trail_date)
VALUES (#transaction,#action,#ref_id,#trail_date)
END
GO
something like this.

I am trying to run a query based on the results from a stored procedure

First, here is the code for sp_GetWorkQByUserName:
ALTER PROCEDURE [dbo].[sp_GetWorkQByUserName]
( #UserName varchar(50),
#StartDate datetime,
#EndDate datetime )
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT SpotId FROM tblSpotCount WHERE StoreNum = EXECUTE sp_GetUserLocationCodes(#UserName)
ORDER BY SpotDt ASC
END
I know my SELECT DISTINCT statement is wrong, but I wrote it like that to help show what I'm trying to do. I want to run this stored procedure based on the results from the sp_GetUserLocationCodes with a parameter of #UserName.
From what I can tell, my problem lies in how I'm calling sp_GetUserLocationCodes.
Question: how can I run a SELECT DISTINCT query on tblSpotCount.SpotId based on the results from the sp_GetUserLocationCodes stored procedure?
You cannot use a stored procedure directly in a query. You can, however, insert the results of a stored procedure into a temporary table and use that in your query:
CREATE TABLE #storeLocations
(
-- appropriate column names and data types go here
)
INSERT INTO #storeLocations (put column list here)
EXECUTE sp_GetUserLocationCodes(#UserName)
SELECT DISTINCT SpotId
FROM tblSpotCount
WHERE EXISTS (SELECT 1
FROM #storeLocations
WHERE #storeLocations.StoreNum = tblSpotCount.StoreNum)
ORDER BY SpotDt ASC
DROP TABLE #storeLocations

Dynamically Select from different DB's based on input to sproc

I'm trying to alter a stored procedure in our DB from a hard-coded select from 1 specific DB to be able to select from any of our DB's based on an id that's passed into the sproc. Here's the stub of what the sproc is doing for us:
ALTER PROCEDURE [dbo].[GetByAdId]
(
#AdId int,
#UserCompanyId int
)
AS
SET NOCOUNT ON
SELECT
[User].[UserId],
UserMappings.IsActive,
IsAccountOwner = ( SELECT Count(*) FROM DB1_SetUp.dbo.ad Adv WHERE Adv.AdID = UserMappings.AdID AND Adv.PrimaryAccountOwnerID = [User].[UserId] )
FROM
[User] INNER JOIN UserMappings ON
(
UserMappings.UserID = [User].UserID
AND UserMappings.AdID = #AdId
AND UserMappings.UserCompanyId = #UserCompanyId
)
Basically the "IsAccountOwner" variable is hardcoded to select from DB1_SetUp every time, but we have a number of SetUp db's for different groups, so like DB2_SetUp, DB3_SetUp, etc. The UserCompanyId variable being passed into the sproc functions like a group Id and can be used to point to the particular SetUp DB I want it to select from, but I'm not sure how to do this. I basically wanted something on the ilk of:
SELECT * FROM (
CASE #UserCompanyId
WHEN 3 THEN 'DB3_SetUp'
WHEN 4 THEN 'DB4_SetUp'
)
Is there a clean way to do this, or will I have to setup this sproc on each group DB and call the specific one over on each DB?
I've done this in the past by dynamically building the SQL I wanted to execute (based on parameters passed in) and then executing the SQL using sp_executesql
see: http://msdn.microsoft.com/en-us/library/ms188001.aspx