Stored Procedure not inserting records - sql

I have a stored procedure that attempts to insert records from a function into a table. When I run the stored procedure, it completes successfully, but does not insert any records into the table. If I highlight the Insert code, it works. I am quite new to all this and would appreciate any help please.
The Stored Procedure is:
ALTER PROCEDURE [dbo].[DataQualityDashboard_UpdatePart1]
AS
DECLARE #StartDate date
DECLARE #EndDate date
SET #StartDate = '2017-01-01'
SET #EndDate = '2017-01-31'
Insert into [iCS.Warehouse3].[dbo].[DashboardData]
Select
MetricID
, FirstDateofMonth
, Numerator
, Denominator
From [iCS.Warehouse3].[KPI].[DataQualityEthnicityOutpatientsWCFT]
(#StartDate, #EndDate)
Commit;
The Function it calls upon is [iCS.Warehouse3].[KPI].[DataQualityEthnicityOutpatientsWCFT], which is below.
ALTER FUNCTION [KPI].[DataQualityEthnicityOutpatientsWCFT]
(
#StartDate date
, #EndDate date
)
RETURNS TABLE
AS
RETURN
(
WITH EthnicityOutpatients (XCN, EthnicGroup, FirstDateOfMonth, MetricID)
AS
(
SELECT
o.XCN
,p.EthnicGroup
,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) as FirstDateOfMonth
,1 as MetricID
FROM [iCS.Warehouse3].[OP].[Appointments] o
Inner Join [iCS.Warehouse3].[lk].[Patient] p
on o.[XCN] = p.[XCN]
Inner Join [iCS.Warehouse3].[lk].[Calendar] cal
on o.AppointmentDate = cal.TheDate
Inner Join [iCS.Warehouse3].[dbo].[LocationLK] l
on o.ClinicLocation = l.Location
WHERE o.AppointmentDate >= #StartDate and o.AppointmentDate <= #EndDate
and o.AppointmentStatus = 'A'
and o.Specialty not in ('NR', 'NPH')
and l.WCFTorSatellite = 'WCFT'
)
SELECT
FirstDateOfMonth
, MetricID
, COUNT(CASE WHEN EthnicGroup is null THEN 1 END) as Numerator
, COUNT (XCN) as Denominator
FROM EthnicityOutpatients
GROUP BY
FirstDateOfMonth
, MetricID
)
The table it should be inserting records into is [iCS.Warehouse3].[dbo].[DashboardData].
It has four fields: MetricID, Date, Numerator and Denominator.
Any help would be greatly appreciated please.
Thanks in advance, Andrew.

Related

SQL query to check availability on an event table

I have a table of events with the columns Room Number and Date
I want to check availability in a certain room so I tried creating a temp calendar table just to compare, but I know I'm doing something wrong with my left join so I need some pointers to help me achieve my goal: only show the dates where there is no event in the specific room.
This is my query so far:
IF OBJECT_ID('tempdb..#calendarTable') IS NOT NULL
DROP TABLE #calendarTable;
GO
CREATE TABLE #calendarTable (
"DayID" INT
,"DayDate" DATE
,PRIMARY KEY (DayID)
)
DECLARE #startDate AS DATE
DECLARE #baseDate DATE
,#offSet INT
,#numberOfLoops INT
SET #startDate = GETDATE() /*'20150101'*/
SET #baseDate = #startDate
SET #offSet = 0
SET #numberOfLoops = DATEDIFF(DAY, #baseDate, DATEADD(MONTH, 24, #baseDate)) /*365*/
WHILE (#offSet < #numberOfLoops)
BEGIN
INSERT INTO #calendarTable (
"DayID"
,"DayDate"
)
SELECT (#offSet + 1)
,DATEADD(DAY, #offSet, #baseDate)
SET #offSet = #offSet + 1
END
SELECT TOP (500)
DayDate
,a.Arrangement_Number
,a.Activity
,a.Room_Number
FROM #calendarTable
left outer join [Events] as a ON DayDate = (convert(varchar(10), a.[Date],120))
where Room_Number = 53
order by DayDate asc

Array like function for a statement

I have a statement that returns a single number for a date. What I want to do is to be able to execute the statement across a range of dates and get a value for each date.
select dbo.GetItemMTDIssues(inmastx.fac, inmastx.fpartno, inmastx.frev, '6-01-2019')
as MTDiss from inmastx where fpartno='ANF-10-6313-102'
This is how the results look for a single date that I'm getting with my current statement. 6-01-2019
|MTDiss|
600
This is the expected results that I want over a range of dates like 6-01-2019 - 6-05-2019
|MTDiss|
600
450
375
700
300
Also including the function if it's helpful.
CREATE FUNCTION [dbo].[GetItemMTDIssues]
(#fac char(20), #partno char(25), #rev char(3), #currentdate datetime)
returns numeric (15,5)
as
begin
declare #returnval as numeric (15,5)
set #returnval =
isnull(
(select sum(fQty)
from intran
where ftype = 'I'
and month(fdate) = month(#currentdate)
and year(fdate) = year(#currentdate)
and fac = #fac
and fpartno = #partno
and fcpartrev = #rev)
,0.0) * -1
return #returnval
end
You would need first to create the range, and the below t-sql will do that.
declare #startDate datetime='6-01-2019'
declare #endDate datetime='6-05-2019'
;with DateRange as (
select #startDate [date]
union all
select DATEADD(day,1,[date]) [date] from DateRange where [date]<#endDate
)
select * from DateRange
we can test it and see the result to confirm that this is the range we want.
note:if you need to jump by month or number of days other that go day by day you only need to change the code in the DATEADD.
Now we would need to update your function to take the start and end of the range and let it use all the range dates , I think something like the below will help:-
CREATE FUNCTION [GetItemMTDIssuesRange]
(
#fac char(20), #partno char(25), #rev char(3), #startDateRange datetime, #EndDateRange datetime
)
RETURNS TABLE
AS
RETURN
(
with DateRange as (
select #startDateRange [date]
union all
select DATEADD(day,1,[date]) [date] from DateRange where [date]<#EndDateRange
)
--select * from DateRange
select (isnull(sum(fQty),0.0) * -1) MTDiss
from intran
inner join DateRange on year(fdate) = year(DateRange.[date]) and month(fdate) = month(DateRange.[date])
where ftype = 'I'
and fac = #fac
and fpartno = #partno
and fcpartrev = #rev
group by DateRange.[date]
)
GO
Please check it.
if you dont want to change the function this below may help too:-
declare #startDate datetime='6-01-2019'
declare #endDate datetime='6-05-2019'
;with DateRange as (
select #startDate [date]
union all
select DATEADD(day,1,[date]) [date] from DateRange where [date]<#endDate
)
select dbo.GetItemMTDIssues(inmastx.fac, inmastx.fpartno, inmastx.frev, DateRange.[date])
as MTDiss from inmastx,DateRange
where fpartno='ANF-10-6313-102'

How to pass multiple values one by one for a Parameter in an SQL Query and union the results?

I have an SQL Statement which accepts a parameter #EndDate as DateTime. I want to be able to pass several values for #EndDate one by one and then Union the results of all the Queries. I have tried using CTE for this but it is of no use. I want to pass several Dates for #EndDate. Any help would be greatly appreciated.
My Query is:
DECLARE #EndDate as DateTime
SET #EndDate = '2018/02/25'
SELECT
CONVERT(VARCHAR, #EndDate, 101) [R_Date]
,[Name]
[Type]
FROM [dbo].[S_Table]
This is Sample query how u can loop through multiple dates. A while loop should select all rows into one table, do not need to perform union all
DECLARE #table TABLE (
day INT
,Month INT
,DATE DATE
)
DECLARE #startdate DATE = '2018/02/25'
DECLARE #enddate DATE = cast(getdate() AS DATE)
WHILE #startdate <= #enddate
BEGIN
SELECT #startdate = dateadd(dd, 1, #startdate)
INSERT #table (
day
,Month
,DATE
)
SELECT day(#startdate)
,MONTH(#startdate)
,#startdate
END
SELECT *
FROM #table;
In your logic for passing multiple values into query , you can store result set into temporal table, which holds looped records
DECLARE #table TABLE (
[R_Date] DATE
,Name VARCHAR(155)
,Value VARCHAR(155)
)
DECLARE #enddate DATE = '2018/02/25'
DECLARE #enddate1 DATE = cast(getdate() AS DATE)
WHILE #enddate <= #enddate1
BEGIN
SELECT #enddate = dateadd(dd, 1, #enddate)
INSERT #table (
R_Date
,Name
,Value
)
SELECT CONVERT(VARCHAR, #EndDate, 101) [R_Date]
,[Name] [Type]
FROM [dbo].[S_Table]
WHERE DATE = #enddate
-------More filters
END
SELECT *
FROM #table;

Use a WITH in an SQL function?

I'm trying to make a function but I do not know how to get the WITH in it. Here is my code.
CREATE FUNCTION CubicVolume (#StartDate date, #EndDate date) RETURNS #TableDays TABLE
(Days int)
AS
BEGIN
INSERT #TableDays
WITH Dates AS (
SELECT #StartDate AS DayInQuestion
UNION ALL
SELECT DATEADD(Day, 1, DayInQuestion) AS DayInQuestion
FROM Dates AS Dates
WHERE (DayInQuestion < #EndDate)
)
SELECT DISTINCT count(Dates.DayInQuestion)
FROM Dates AS Dates LEFT OUTER JOIN
HEATHrs ON Dates.DayInQuestion = HEATHrs.StartDate
WHERE (CAST(DATEPART(weekday, Dates.DayInQuestion) AS int) BETWEEN 2 AND 6)
RETURN
END
You have to put the Common Table Expression (CTE) before the INSERT:
WITH Dates AS
(
SELECT #StartDate AS DayInQuestion
UNION ALL
SELECT DATEADD(Day, 1, DayInQuestion) AS DayInQuestion
FROM Dates AS Dates
WHERE (DayInQuestion < #EndDate)
)
INSERT #TableDays
SELECT DISTINCT count(Dates.DayInQuestion)
FROM Dates AS Dates LEFT OUTER JOIN
HEATHrs ON Dates.DayInQuestion = HEATHrs.StartDate
WHERE (CAST(DATEPART(weekday, Dates.DayInQuestion) AS int) BETWEEN 2 AND 6)

Number of entries per month

I have something similar to the following situation, probably not the best example but somewhat similar to what I really have. Let's say I have 4 tables that due to certain circumstances I can't change.
CREATE TABLE [Hospital] (
[HospitalID] INT IDENTITY NOT NULL,
[HospitalName] VARCHAR(MAX) NOT NULL
);
CREATE TABLE [Doctors] (
[DoctorID] INT IDENTITY NOT NULL ,
[HospitalID] INT NOT NULL,
[DoctorName] VARCHAR(MAX) NOT NULL
);
CREATE TABLE [Patient] (
[PatientID] INT IDENTITY NOT NULL ,
[DoctorID] INT NOT NULL
);
CREATE TABLE [PatientAppointment] (
[PatientID] INT IDENTITY NOT NULL,
[Date] DATETIME NOT NULL
);
I want to write a stored procedure that get's a year and a month as parameters and it is supposed to return [HospitalName] , [DoctorsName] and the number of patient appointments for that time period.
This is what I have now and I am stuck
CREATE PROCEDURE [dbo].[Procedure]
#year INT ,
#month INT
AS
SELECT COUNT([Date]) AS NumberOfAppointments FROM [PatientAppointment]
WHERE MONTH([Date]) = #month AND YEAR([Date]) = #year
SELECT [Hospital].HospitalName , [Doctors].DoctorName FROM [Doctors]
INNER JOIN [Hospital] ON [Hospital].HospitalID = [Doctors].DoctorID
RETURN 0
I can't figure out how to extract the info I need and I am limited to one stored procedure.
try this:
CREATE PROCEDURE [dbo].[Procedure]
#year INT ,
#month INT
AS
BEGIN
SELECT h.HospitalId, d.DoctorName, count(p.PatientId) as NumberOfAppointments
FROM Hospital h
INNER JOIN Doctors d
ON h.HospitalId = d.HospitalId
INNER JOIN Patient p
ON d.DoctorId = p.DoctorId
INNER JOIN PatientAppointment ap
ON p.PatientId = ap.PatientId
AND MONTH(ap.[Date]) = #month
AND YEAR(ap.[Date]) = #year
GROUP BY h.HospitalId, d.DoctorName
END
My answer is very similar to the one posted by Joachim but there is one VERY significant difference. This code is SARGable where the original query and the fine example already posted are not. Since you say you can't change the table structure I will refrain from suggesting changes....although you could greatly improve on these structures.
Create Procedure dbo.SomeBetterName
(
#Date date
) AS
select h.HospitalName
, d.DoctorName
, COUNT(pa.[Date]) as NumAppointments
from Hospital h
join Doctors d on h.HospitalID = d.HospitalID
join Patient p on p.DoctorID = d.DoctorID
join PatientAppointment pa on pa.PatientID = p.PatientID
where pa.Date >= dateadd(month, datediff(month, 0, #Date), 0)
and pa.Date < dateadd(month, datediff(month, 0, #Date) + 1, 0)
group by h.HospitalName
, d.DoctorName