error in IF ELSE statement in SQL [duplicate] - sql

This question already has an answer here:
Drop temp table within IF ELSE statement
(1 answer)
Closed 7 years ago.
I have the following stored procedure, But seems like the #Temp table is creating troubles in it. I get following error
There is already an object named '#Temp' in the database.
I guess somethings wrong with my IF ELSE
Here is the stored procedure:
create procedure spGetHOSalesReport
#DateFrom datetime,#DateTo datetime,#EmbossLine varchar(20),#CountryID int,#status char(2)
AS
Set #DateTo = #DateTo +1
if(#status = 'E1')
begin
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
into #Temp
from TempPOS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where
PT.[ID] not in (Select distinct isnull(TransactionID,0) from Testcards)
and (PT.TransactionDate >= #DateFrom) and (PT.TransactionDate < #DateTo)
and (PT.TransactionTypeID = 6) and (PT.BatchNumber = 0) and (Pt.SequenceNumber =-1)
select T.*, ' '+ C.EmbossLine+' ' as 'EmbossLine', C.EmbossLine as 'EmbossLine1',
isnull(C.FirstName,'') +' '+ isnull(C.LastName,'') 'EmbossName',C.FirstName,C.LastName,City.CityName,Country.CountryName,Country.CurrencyName, PM.MerchantID, PM.MerchantName1, C.AccountNumber, C.VehicleNumber, C.ExpiryDate ,
case C.Status when 'E0' then 'Authorized' when 'E1' then 'Pending' end 'Status'
from #Temp T
inner join Card C on C.EmbossLine= T.EmbossLine
inner join Terminal on Terminal.TerminalID = T.TerminalID
inner join Merchant PM on PM.MerchantID = Terminal.MerchantID
inner join City on City.CityID = PM.CityID
inner join Country on Country.CountryID = PM.CountryID
where C.Status <>'E3'
and C.CardID not in (Select distinct isnull(CardID,0) from Testcards)
and (C.EmbossLine like '%'+#EmbossLine+'%' or #EmbossLine like '-999')
and (PM.CountryID = #CountryID or #CountryID ='-999')
and (C.Status = #status)
order by T.TransactionDate, MerchantName1, T.BatchNumber, T.SequenceNumber
End
Else
Begin
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
into #Temp
from POS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where PT.[ID] not in (Select distinct isnull(TransactionID,0) from Testcards) and (PT.TransactionDate >= #DateFrom) and (PT.TransactionDate < #DateTo)
and (PT.TransactionTypeID = 6) and (PT.BatchNumber = 0) and (Pt.SequenceNumber =-1)
select T.*, ' '+ C.EmbossLine+' ' as 'EmbossLine', C.EmbossLine as 'EmbossLine1',
isnull(C.FirstName,'') +' '+ isnull(C.LastName,'') 'EmbossName',C.FirstName,C.LastName,City.CityName,Country.CountryName,Country.CurrencyName, PM.MerchantID, PM.MerchantName1, C.AccountNumber, C.VehicleNumber, C.ExpiryDate ,
case C.Status when 'E0' then 'Authorized' when 'E1' then 'Pending' end 'Status'
from #Temp T
inner join Card C on C.EmbossLine= T.EmbossLine
inner join Terminal on Terminal.TerminalID = T.TerminalID
inner join Merchant PM on PM.MerchantID = Terminal.MerchantID
inner join City on City.CityID = PM.CityID
inner join Country on Country.CountryID = PM.CountryID
where C.Status <>'E3'
and C.CardID not in (Select distinct isnull(CardID,0) from Testcards)
and (C.EmbossLine like '%'+#EmbossLine+'%' or #EmbossLine like '-999')
and (PM.CountryID = #CountryID or #CountryID ='-999')
and (C.Status = #status)
order by T.TransactionDate, MerchantName1, T.BatchNumber, T.SequenceNumber
End
drop table #Temp

You cannot have two statements in the same procedure that creates a temp table with the same name. This is a leftover from SQL 6.5 which did not have deferred name resolution.
And in any case, it only makes sense if the tables are created exactly the same, else your procedure will behave very funky.
So instead of using SELECT INTO, use CREATE TABLE + INSERT.
UPDATE
According to the selected way from comment:
Second option: First create temp table and insert
First let's create the temp table. For that you should modify your procedure like:
create procedure spGetHOSalesReport
#DateFrom datetime,#DateTo datetime,#EmbossLine varchar(20),#CountryID int,#status char(2)
AS
BEGIN -- begin procedure
SET #DateTo = #DateTo +1
if object_id('tempdb..#Temp') is not null drop table #Temp
create table #Temp
( TransactionID int
, BatchNumber ... ( your type of field )
, SequenceNumber ...
, TransactionDate ...
, TerminalID int
, TotalAmount ...
, TransactionTypeID int
, TransactionType ...
, EmbossLine ...
, PreBalanceAmount ...
, PostBalanceAmount ...
, RefTxnID int
, SettlementDate ...
, PaidCash ...
, CreditAmount ...
, DiscountAmount ...
, RefPAN ...
, Remarks ...
, SupervisorCard ...
, StoreID int
)
if(#status = 'E1')
.......
I do not know which data type has these fields, so, you have to do yourself. Then edit insert into temp table in first case and similar in another case:
insert into #Temp
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
from TempPOS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where ...
In the end of procedure you can add:
End -- end of your if
if object_id('tempdb..#Temp') is not null drop table #Temp
END -- end of procedure
But the simplest way is create two different temp tables:
if(#status = 'E1')
begin
if object_id('tempdb..#Temp1') is not null drop table #Temp1
Select PT.[ID] 'TransactionID', PT.BatchNumber, ...
into #Temp1
from TempPOS_Transactions PT
inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
.....
end
else
begin
if object_id('tempdb..#Temp2') is not null drop table #Temp2
Select PT.[ID] 'TransactionID', PT.BatchNumber, ...
into #Temp2
from POS_Transactions PT
inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
....
end
Also, you can write just two select without creating temp table in this case

Related

Error creating function with temporary tables

I am creating a function that contains a temporary table, it is a bit difficult for me to use the function with a temporary table, I totally do not know if it is allowed within a function since I am new to the new one.
The function I am trying to create is the following:
CREATE FUNCTION FunctionTest (
#Anio int=null,
#Mes int=Null,
#Meses int=6
)
RETURNS #Tabla TABLE (
AnioMes INT,
Viaje VARCHAR(30),
IdPorte INT,
Carga VARCHAR(20),
Peso numeric(32, 16)
)
AS
BEGIN
Declare #AnioMes varchar(8),
#AnioMes6 varchar(8)
if #Anio is null
Select #Anio = YEAR(GETDATE()),
#Mes = MONTH(GETDATE())
Select #AnioMes = (case when #Mes=12 then #Anio+1 else #Anio end *100 + Case when #Mes=12 then 1 else #Mes+1 end)*100 + 1
Select #AnioMes6 = convert(varchar(8), DATEADD(mm, -#Meses, #AnioMes), 112 )
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
into #Temp
FROM BDNEW.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
if #AnioMes6 < '20160101'
insert #Temp
SELECT Year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
FROM BDOLD.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
Delete #Temp
where viaje in (
select MAX(Viaje)
from #Temp
group by IdPorte
having COUNT(IdPorte) > 1
)
Select AnioMes,
Viaje,
IdPorte,
Carga,
Peso,
from #Temp
GROUP BY AnioMes,IdPorte Viaje, Carga, Peso
ORDER BY AnioMes,IdPorte
RETURN
END
If you notice I am making use of a temporary table called #Temp.
As an error message when trying to compile the function I get the following error message:
Cannot access temporary tables from within a function.
That is why I mentioned earlier if you can really make use of temporary tables in a function.
I appreciate anyone who can give me guidance on how to handle this function.
You either use
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
Or
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
Not both:
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
And also you can't use temp tables in functions.

Avoid function in where clause,due to that its causing performance issue?

Whenever I'm executing the procedure I got performance issue, where do I need to change the procedure to increase the performance?
I have called table function in where clause I need to optimize this procedure without using string.
CREATE PROC proc_productwise_report #cmp_id VARCHAR(max), #unitcode VARCHAR(max), #gr_code VARCHAR(max), #store_code VARCHAR(max), #from_dt VARCHAR(20), #to_dt VARCHAR(20)
AS
BEGIN
SELECT sh.cmp_id, d.unitcode, d.store_code, st.item_code AS product, d.item_code, im.item_desc, SUM(charge_qty) AS challan_qty
FROM ps_invenstatic sh
INNER JOIN ps_invenstaticdet st ON sh.cmp_id = st.cmp_id
AND sh.sys_no_id = st.sys_no_id
AND sh.doc_id = st.doc_id
AND sys_doc_type = 'PSCH'
INNER JOIN ps_invenissu h ON sh.cmp_id = h.cmp_id
AND sh.doc_type = h.ref_doc_type
AND sh.doc_no = h.ref_doc_no
AND h.prod_code = st.item_code
INNER JOIN ps_invenissudet d ON h.cmp_id = d.cmp_id
AND h.sys_no_id = d.sys_no_id
AND h.doc_id = d.doc_id
INNER JOIN ps_itemmas im ON sh.cmp_id = im.cmp_id
AND im.item_code = d.item_code
WHERE sh.cmp_id IN (
SELECT *
FROM utilfn_split(#cmp_id, ',')
)
AND d.unitcode IN (
SELECT *
FROM utilfn_split(#unitcode, ',')
)
AND im.gr_code IN (
SELECT *
FROM utilfn_split(#gr_code, ',')
)
AND d.store_code IN (
SELECT *
FROM utilfn_split(#store_code, ',')
)
AND h.doc_dt BETWEEN convert(DATETIME, #from_dt, 103)
AND convert(DATETIME, #to_dt, 103)
AND sh.Stat_Code <> 'CA'
GROUP BY sh.cmp_id, d.unitcode, d.store_code, st.item_code, d.item_code, im.item_desc
END
I need to avoid function in where clause and resolve the performance issue.
You can build temporary tables in your stored procedure with the result of the SPLIT and INNER JOIN those temporary tables in your main query.
CREATE PROC proc_productwise_report #cmp_id VARCHAR(max), #unitcode VARCHAR(max),
#gr_code VARCHAR(max), #store_code VARCHAR(max), #from_dt VARCHAR(20), #to_dt VARCHAR(20)
AS
BEGIN
SELECT *
INTO #cmp_ids
FROM utilfn_split(#cmp_id, ',');
SELECT *
INTO #unitcodes
FROM utilfn_split(#unitcode, ',');
SELECT *
INTO #gr_codes
FROM utilfn_split(#gr_code, ',');
SELECT *
INTO #store_codes
FROM utilfn_split(#store_code, ',');
SELECT
sh.cmp_id
, d.unitcode
, d.store_code
, st.item_code AS product
, d.item_code
, im.item_desc
, SUM(charge_qty) AS challan_qty
FROM ps_invenstatic sh
INNER JOIN ps_invenstaticdet st
ON sh.cmp_id = st.cmp_id
AND sh.sys_no_id = st.sys_no_id
AND sh.doc_id = st.doc_id
AND sys_doc_type = 'PSCH'
INNER JOIN ps_invenissu h
ON sh.cmp_id = h.cmp_id
AND sh.doc_type = h.ref_doc_type
AND sh.doc_no = h.ref_doc_no
AND h.prod_code = st.item_code
INNER JOIN ps_invenissudet d
ON h.cmp_id = d.cmp_id
AND h.sys_no_id = d.sys_no_id
AND h.doc_id = d.doc_id
INNER JOIN ps_itemmas im
ON sh.cmp_id = im.cmp_id
AND im.item_code = d.item_code
INNER JOIN #cmp_ids tci on sh.cmp_id = tci.[value]
INNER JOIN #unitcodes tuc on d.unitcode = tuc.[value]
INNER JOIN #gr_codes tgr on im.gr_code = tgr.[value]
INNER JOIN #store_codes tsc on d.store_code = tsc.[value]
WHERE h.doc_dt BETWEEN convert(DATETIME, #from_dt, 103)
AND convert(DATETIME, #to_dt, 103)
AND sh.Stat_Code <> 'CA'
GROUP BY sh.cmp_id
, d.unitcode
, d.store_code
, st.item_code
, d.item_code
, im.item_desc
END
Use table-valued parameters instead of CSV strings. Alternatively in your proc
create temp tables (table variables) first.
declare #tunitcode table (id int); -- you type may be different
insert #tunitcode(id)
select *
from utilfn_split(#unitcode, ',');
.. AND d.unitcode IN (
SELECT * FROM #tunitcode)
..

Best way get complex sql data(Performance issue)

Hi i have a timeLogs table having with columns(id,startTime,EndTime,User_Id,Client_Id,Project_Id,Task_Id,TotalHours)
I need output Having columns(Client,Project,Task,NoOfResources,TotalTime) with projectids,taskids,datefrom ,datetill filters Sample output and table structure are shown below
Here User_Id ,Client_Id,Task_Id,Project_Id are foreign keys with users,clients,tasks,projects
Here # of resources is user count
I am doing it through a stored procedure:
ALTER procedure [dbo].[GetProjectUtilizationReport]
(#DateFrom datetime =null,
#DateTill datetime = null,
#TaskTypeIds nvarchar(max) = null,
#TaskIds nvarchar(max) = null,
#UserIds nvarchar(max) = null,
#ProjectIds nvarchar(max) = null)
AS
BEGIN
CREATE TABLE #TempTable(id int,
ProjectId int,
ClientId int,
UserId int,
TaskId int,
TotalHours numeric(18,2),
StartTime datetime,
TaskTypeId int)
--- create a temp table with data dump
INSERT INTO #TempTable(Id, ProjectId, ClientId, UserId, TaskId, TotalHours, StartTime, TaskTypeId)
SELECT
tl.id,Project_Id, Client_Id,
User_Id, Task_Id, TotalHours,
StartTime, TaskType_Id
FROM
TimeLogs tl
JOIN
Tasks t ON tl.Task_Id = t.Id
--apply filter to temp table
IF (#DateFrom IS NOT NULL)
DELETE FROM #TempTable
WHERE StartTime < #DateFrom
IF (#DateTill IS NOT NULL)
DELETE FROM #TempTable
WHERE StartTime > #DateTill
IF (#TaskTypeIds IS NOT NULL)
DELETE FROM #TempTable
WHERE TaskTypeId NOT IN (SELECT Item FROM dbo.SplitString(#TaskTypeIds, ','))
IF (#TaskIds IS NOT NULL)
DELETE FROM #TempTable
WHERE TaskId NOT IN (SELECT Item FROM dbo.SplitString(#TaskIds, ','))
IF (#UserIds IS NOT NULL)
DELETE FROM #TempTable
WHERE UserId NOT IN (SELECT Item FROM dbo.SplitString(#UserIds, ','))
IF (#ProjectIds IS NOT NULL)
DELETE FROM #TempTable
WHERE ProjectId NOT IN (SELECT Item FROM dbo.SplitString(#ProjectIds, ','))
--finaly select data
SELECT
p.Name as Project, c.Name as Client,
tl.TaskId, t.Name as Task,
SUM(TotalHours) as Totalhours,
COUNT(DISTINCT tl.UserId) as NoOfResources,
c.Id as ClientId
FROM
#TempTable tl
JOIN
Tasks t ON tl.TaskId = t.Id
JOIN
Clients c ON c.Id = tl.ClientId
JOIN
Projects p ON tl.ProjectId = p.Id
GROUP BY
tl.TaskId, c.id, c.Name, p.Name, t.Name
--drop temp table
DROP TABLE #TempTable
END
I think there may be a much better approach - something like an view etc but I don't have any ideas.
May to put data in other table on insert etc.
Please put your suggestion show that i can get results as fast as posible.
I often try to avoid #tables where I can.
SELECT c.Name AS Client, p.Name AS Project, t.Name AS Task, COUNT(DISTINCT tl.User_Id) AS NoOfResources, SUM(TotalHours) AS Totalhours
FROM TimeLogs tl
INNER JOIN Tasks t ON tl.Task_Id =t.Id
INNER JOIN Clients c ON c.Id =tl.Client_Id
INNER JOIN Projects p ON tl.Project_Id =p.Id
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#UserIds, ''), ',')) users ON users.Item = tl.User_Id OR #UserIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#TaskTypeIds, ''), ',')) tasktypes ON tasktypes.Item = tl.TaskType_Id OR #TaskTypeIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#TaskIds, ''), ',')) tasks ON tasks.Item = tl.Task_Id OR #TaskIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#ProjectIds, ''), ',')) projects ON projects.Item = tl.Project_Id OR #ProjectIds IS NULL
WHERE (#DateFrom IS NULL OR StartTime < #DateFrom)
AND (#DateTill IS NULL OR StartTime > #DateTill)
GROUP BY c.Id, c.Name, p,Id, p.Name, t.Id, t.Name

Can we make join between two stored procedures in SQL Server

I have this stored procedure:
CREATE PROCEDURE [dbo].[TestPackageAccept]
AS
BEGIN
SELECT A.Id,
a.PackageNumber,
a.Size,
a.Code,
a.TestPackageOrder,
B.status as LineCheckState,
B.ReportNumber as LineCheckReportNumber,
B.SubmitDateTime as LineCheckSubmitDateTime,
c.status as CleaningState,c.ReportNumber as CleanReportNumber,
c.SubmitDateTime as CleanSubmitDateTime,
c.status as ReInstatement,
d.ReportNumber as ReInstatementReportNumber,
d.SubmitDateTime as ReInstatementSubmitDateTime,
E.status as Flushing,
e.ReportNumber as FlushingReportNumber,
e.SubmitDateTime as FlushingSubmitDateTime,
f.status as Drying,
f.ReportNumber as DryingReportNumber,
f.SubmitDateTime as DryingSubmitDateTime,
m.status as PAD,
m.ReportNumber as PADReportNumber,
m.SubmitDateTime as PADSubmitDateTime,
n.status as Mono,
n.ReportNumber as MonoReportNumber,
n.SubmitDateTime as MonoSubmitDateTime,
p.status as Variation,
p.ReportNumber as VariationReportNumber,
p.SubmitDateTime as VariationSubmitDateTime
FROM TestPackages A
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'LineCheck')) B
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Clean')) C
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Reinstatment'))D
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Flushing')) E
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Drying')) F
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Test')) G
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'PADTest')) M
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Mono')) N
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Variation')) P
END;
And this
CREATE PROCEDURE [dbo].[TestPackageProgress]
AS
BEGIN
SELECT PackageId,
packagenumber,
count(*) as [Total],
sum(case [WeldStatus] when 'Accept' then 1 end) as Accept,
sum(case [WeldStatus] when 'accept' then 0 else 1 end) as Remain,
ROUND(CONVERT(float,sum(case [WeldStatus] when 'Accept' then 1 end))/CONVERT(float,count(*)) * 100,2) as PercentProgress
FROM [SPMS2].[dbo].[JointHistory]
WHERE PackageId is not null
GROUP BY PackageId,PackageNumber;
END;
Can I make a join between these two stored procedure's result sets on first.id = second.packageid?
You can put result sets from both SP into temp tables and then join them:
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
--Here you add all columns from SP output with there datatypes
)
Then you can:
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
The same way for second SP, then join:
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid
Don't forget to DROP temp tables:
DROP TABLE #PackageAccept
DROP TABLE #PackageProgress
The full batch will be like:
IF OBJECT_ID(N'#PackageAccept') IS NOT NULL
BEGIN
DROP TABLE #PackageAccept
END
ELSE
BEGIN
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
)
END
IF OBJECT_ID(N'#PackageProgress') IS NOT NULL
BEGIN
DROP TABLE #PackageProgress
END
ELSE
BEGIN
CREATE TABLE #P (
PackageId INT,
packagenumber INT,
[Total] INT,
Accept INT,
Remain INT
--etc
)
END
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
INSERT INTO #PackageProgress
EXEC [dbo].[TestPackageProgress]
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid

SQL Server 2008 - Update SQL Help Needed

First and foremost, the SQL is handled dynamically by the server, therefore some items in my WHERE clause may look odd to you, please disregard these as they are not an issue.
Per my clients request, they needed to UNION in two other conditions to my update report (/Patients without a Patient Visit/) and (/Patients without a Appointment/). I need help adding in the patients of these two subsets into my final update query. In its present state, it's only adding in the #Temp patients and I need to incorporate the additional patients.
Any help is GREATLY appreciated.
My current SQL update -
DECLARE #Inactive INT
DECLARE #Active INT
DECLARE #PatientProfileId INT
SELECT
#Inactive = MedlistsId
FROM
Medlists
WHERE
TableName = 'PatientProfileStatus'
AND Code = 'I'
SELECT
#Active = MedlistsId
FROM
Medlists
WHERE
TableName = 'PatientProfileStatus'
AND Code = 'A'
CREATE TABLE #Temp
(
PatientName VARCHAR(120) ,
PatientProfileId INT ,
RecentId INT ,
Recent DATETIME
)
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
MAX(pv.PatientVisitId) AS RecentId ,
MAX(pv.Visit) AS Recent
FROM
PatientVisit pv
INNER JOIN PatientProfile pp ON pv.PatientProfileId = pp.PatientProfileId
AND pp.PatientStatusMId = #Active
WHERE
pp.PatientProfileId IN ( SELECT
a.OwnerId
FROM
Appointments a
INNER JOIN PatientProfile pp ON a.OwnerId = pp.PatientProfileId
AND a.ApptKind = 1
AND pp.PatientStatusMId = #Active
GROUP BY
a.OwnerId ,
a.ApptKind
HAVING
MAX(a.ApptStart) < '07/30/2005' )
GROUP BY
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) ,
pp.PatientProfileId
HAVING
MAX(pv.Visit) < '07/30/2005'
/*Patients without a Appointment*/
IF 1 = 1
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
NULL AS RecentId ,
NULL AS Recent
FROM
PatientProfile pp
LEFT JOIN ( SELECT * FROM Medlists WHERE TableName = 'PatientProfileStatus' ) ml1 ON pp.PatientStatusMId = ml1.MedlistsId
LEFT JOIN Appointments a ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
LEFT JOIN PatientVisit pv ON a.PatientVisitId = pv.PatientVisitId
WHERE
ml1.Code = 'A'
AND a.ownerid IS NULL
AND --Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
/*Patients without a Patient Visit*/
IF 0 = 1
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
NULL AS RecentId ,
NULL AS Recent
FROM
PatientProfile pp
LEFT JOIN PatientVisit pv ON pv.PatientProfileid = pp.PatientProfileid
LEFT JOIN ( SELECT * FROM Medlists WHERE TableName = 'PatientProfileStatus' ) ml1 ON pp.PatientStatusMId = ml1.MedlistsId
WHERE
ml1.Code = 'A'
AND pv.patientprofileid IS NULL
AND --Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
DECLARE curPatient CURSOR FORWARD_ONLY READ_ONLY LOCAL
FOR
SELECT
t.PatientProfileId
FROM
#Temp t
JOIN PatientProfile pp ON t.PatientProfileId = pp.PatientProfileId
JOIN PatientVisit pv ON pp.PatientProfileId = pv.PatientProfileId
AND pv.PatientVisitId = t.RecentId
WHERE
--Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
OPEN curPatient
FETCH NEXT FROM curPatient INTO #PatientProfileId
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE
PatientProfile
SET
PatientStatusMId = #Inactive ,
pstatus = 'I'
FROM
PatientProfile P
INNER JOIN #Temp t ON t.PatientProfileID = P.PatientProfileID
WHERE
p.PatientProfileId = #PatientProfileId
FETCH NEXT FROM curPatient INTO #PatientProfileId
END
CLOSE curPatient
DEALLOCATE curPatient
DROP TABLE #Temp
This will limit to patients WITH an appointment
LEFT JOIN Appointments a
ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
This will limit to patients WITH a Visit
LEFT JOIN PatientVisit pv
ON pv.PatientProfileid = pp.PatientProfileid
Try
LEFT OUTER JOIN Appointments a
ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
Where a.Ownerid is null
LEFT OUTER JOIN PatientVisit pv
ON pv.PatientProfileid = pp.PatientProfileid
Where pv.PatientProfileid is null