The multi-part identifier "iis.sourceId" could not be bound - sql-server

Any suggstion/ solution for this problem ?
The multi-part identifier "iis.sourceId" could not be bound.
ALTER PROCEDURE [dbo].[InstrumentSourceSnapSelector]
#searchedString nvarchar(100) = null
, #at datetime
AS
BEGIN
DECLARE #sql as nvarchar(4000)
DECLARE #ParmDefinition nvarchar(500);
SET #at=dateadd(MILLISECOND, -datepart(MILLISECOND, #at), isnull(#at,getdate())) --on tronque les ms
CREATE TABLE #TEMP
(
SourceId UNIQUEIDENTIFIER,
instrumentIdentifierId UNIQUEIDENTIFIER,
instrumentId UNIQUEIDENTIFIER,
vacationId UNIQUEIDENTIFIER,
MaxReqTime DATETIME
)
INSERT INTO #TEMP
SELECT
SourceId,
instrumentIdentifierId,
instrumentId,
vacationId,
max(requestTime) as MaxReqTime
FROM
(instrumentSourceSnap inst
INNER JOIN
VacationTask T
ON inst.vacationTaskId = T.id)
GROUP BY
SourceId,instrumentIdentifierId, instrumentId, vacationId
SELECT DISTINCT
iss.id
, i.name AS Name
, s.name AS sourceName
, d.name AS identifier
, ii.value AS identifierValue
, v.name AS Vacation
FROM
instrumentSourceSnap iss
INNER JOIN #TEMP T
ON
T.sourceId = iis.sourceId AND
T.instrumentIdentifierId = iis.instrumentIdentifierId AND
T.instrumentId = iis.instrumentId AND
T.MaxReqTime = iis.ReuqestTime
INNER JOIN vacationTask vt ON vt.id = iss.vacationTaskId
INNER JOIN vacation v ON v.id = vt.vacationId
INNER JOIN instrument i ON i.id = iss.instrumentId
INNER JOIN source s ON s.id = iss.sourceId
INNER JOIN instrumentIdentifier ii ON ii.instrumentId=i.id
INNER JOIN identifier d ON d.Id=ii.identifierId
INNER JOIN instrumentSource si ON si.instrumentId = i.id and si.sourceId = s.id
END
GO

Just like the comments said, replaced all iis with iss as iss is the alias for instrunmentSourceSnap.
ALTER PROCEDURE [dbo].[InstrumentSourceSnapSelector]
#searchedString nvarchar(100) = null
, #at datetime
AS
BEGIN
DECLARE #sql as nvarchar(4000)
DECLARE #ParmDefinition nvarchar(500);
SET #at=dateadd(MILLISECOND, -datepart(MILLISECOND, #at), isnull(#at,getdate())) --on tronque les ms
CREATE TABLE #TEMP
(
SourceId UNIQUEIDENTIFIER,
instrumentIdentifierId UNIQUEIDENTIFIER,
instrumentId UNIQUEIDENTIFIER,
vacationId UNIQUEIDENTIFIER,
MaxReqTime DATETIME
)
INSERT INTO #TEMP
SELECT
SourceId,
instrumentIdentifierId,
instrumentId,
vacationId,
max(requestTime) as MaxReqTime
FROM
(instrumentSourceSnap inst
INNER JOIN
VacationTask T
ON inst.vacationTaskId = T.id)
GROUP BY
SourceId,instrumentIdentifierId, instrumentId, vacationId
SELECT DISTINCT
iss.id
, i.name AS Name
, s.name AS sourceName
, d.name AS identifier
, ii.value AS identifierValue
, v.name AS Vacation
FROM
instrumentSourceSnap iss
INNER JOIN #TEMP T
ON
T.sourceId = iss.sourceId AND
T.instrumentIdentifierId = iss.instrumentIdentifierId AND
T.instrumentId = iss.instrumentId AND
T.MaxReqTime = iss.ReuqestTime
INNER JOIN vacationTask vt ON vt.id = iss.vacationTaskId
INNER JOIN vacation v ON v.id = vt.vacationId
INNER JOIN instrument i ON i.id = iss.instrumentId
INNER JOIN source s ON s.id = iss.sourceId
INNER JOIN instrumentIdentifier ii ON ii.instrumentId=i.id
INNER JOIN identifier d ON d.Id=ii.identifierId
INNER JOIN instrumentSource si ON si.instrumentId = i.id and si.sourceId = s.id
END
GO

Related

Using DECLARE while creating a VIEW?

The literature says that the declare statement is not compatible with creating a View. How do I get around it?
My declare statement looks like:
DECLARE #risk_5 TABLE (Code VARCHAR(100));
INSERT INTO #risk_5 (Code) VALUES ('AA'),('BB'),('CC');
and is then used within a select statement:
SELECT
id,
CASE
WHEN a.[10_2_1_Country] IN (SELECT Code from #risk_5)
THEN '3'
END AS Risk_Country5
FROM x
The recommendation is to pack the declare into a CTE or a stored procedure.
With both these recommendations though, I do not understand how to connect the two? What am I missing?
If you need to use variable try to use stored procedures, if you write a select query in the stored procedure you can get the data too. And you can use declare inside.
I use this way in my solution e.g.
CREATE PROCEDURE [dbo].[GetLoadSiteMass]( #month INT,
#year int,
#storageId int,
#parent nvarchar(50),
#materialSourceId nvarchar(100),
#complexIds nvarchar(50))
AS
BEGIN
DECLARE #MonthPrev int
DECLARE #YearPrev int
SET #MonthPrev = CASE WHEN #Month = 1 THEN 12 ELSE #Month - 1 END
SET #YearPrev = CASE WHEN #Month = 1 THEN #Year - 1 ELSE #Year END
declare #WagonLoadSiteId int
set #WagonLoadSiteId = (select top 1 CarriageLoadSiteId from CarriageLoadSite where LoadSiteType = 2);
DECLARE #loadSide nvarchar(10), #result decimal(18,3)
SET #loadSide=cast( #storageId as nvarchar(50));
WITH CarriageLoadSiteTreeView (
[CarriageLoadSiteId],RootId,RootName,[Code], Name, ParentID, [LoadSiteType],IsDelete,
CodeSAP,DepartmentId, Capacity, MinLimit, MaxLimit, LoadSitePlaceTypeId) AS
(
SELECT [CarriageLoadSiteId],
[CarriageLoadSiteId] RootId,
Name RootName,
[Code],
Name,
ParentID,
[LoadSiteType],
[IsDelete],
CodeSAP,
DepartmentId,
Capacity,
MinLimit,
MaxLimit,
LoadSitePlaceTypeId
FROM CarriageLoadSite WITH(NOLOCK)
WHERE ISNULL(ParentID,0) =isnull(#storageId,0) AND Isdelete!=1
UNION ALL
SELECT d.[CarriageLoadSiteId],
q.RootId RootId,
RootName RootName,
d.[Code],
d.Name,
d.ParentID,
d.[LoadSiteType],
d.[IsDelete],
d.CodeSAP,
d.DepartmentId,
d.Capacity,
d.MinLimit,
d.MaxLimit,
d.LoadSitePlaceTypeId
FROM CarriageLoadSite AS d WITH(NOLOCK)
INNER JOIN CarriageLoadSiteTreeView AS q ON d.ParentID = q.[CarriageLoadSiteId] WHERE d.IsDelete!=1
)
SELECT
ComplexId,
RootId Id,
cast(RootId as nvarchar(8))+'|Sclad'+IIF(RootId=max(R.CarriageLoadSiteId),'|finish','') [Uid],
RootName CarriageLoadSiteName,
ROUND(SUM(AMOUNT-movement-consumption)/1000,3) Amount,
cast(1 as bit) hasChildren,
T.FullPathId Path,
UparentId=IIF(#parent is null,'',#parent),
[Type]=0,
Petal = IIF(RootId=max(R.CarriageLoadSiteId),'|Sclad|finish','')
FROM (
SELECT
RootId
,RootName
,t.CarriageLoadSiteId
,t.MaterialId
,YEAR(t.Period) [Year]
,MONTH(t.Period) [Month]
,round( case when (t.Amount=0 or t.Amount is null) and (tt.Type=0 or [TypeAmountCarriage]=1 )then carr.[CertifNetto]else t.Amount end ,0 )[Amount]
,t.UnitId
, CarriageId
, tt.TurnoverTypeId
,round(dbo.GetMovementByTurnOverWithTempValue(t.turnoverid),5) movement
,dbo.GetConsumptionByTurnOver(t.turnoverid) consumption
,0 stockBegin
,round(t.Amount,0 ) CommingAmount
,case when (t.Amount=0 or t.Amount is null) and tt.Type=0 then 1 else 0 end [IsNotConfirmed]
,[TypeAmountCarriage]
,M.ComplexId
FROM Turnover t WITH(NOLOCK)
INNER JOIN TurnoverType tt ON tt.TurnoverTypeId = t.TurnoverTypeId
INNER JOIN CarriageLoadSiteTreeView l ON l.CarriageLoadSiteId = t.CarriageLoadSiteId
INNER JOIN [Carriages] carr on carr.[CarriagesID]=t.[CarriageId]
INNER JOIN Material M on M.MaterialID=t.MaterialId
WHERE YEAR(t.Period) = #Year AND
MONTH(t.Period) = #Month AND
l.LoadSiteType = 0 AND
tt.type in (0,5,4) AND
isclear=0 AND
M.MaterialSourceID in (select value from string_split(#materialSourceId, ','))
UNION ALL
SELECT RootId
,RootName
,s.CarriageLoadSiteId
,s.MaterialId
,#Year [Year]
,#Month [Month]
,round(s.Amount,0)
,s.UnitId
,CarriageId
,[TurnoverTypeId]
,round(dbo.GetMovementByStock(s.StockId),5) movement
,dbo.GetConsumptionByStock(s.StockId) consumption
,round(s.Amount,0)-s.spendStock
,0
,0 [IsNotConfirmed]
,[TypeAmountCarriage]
,M.ComplexId
FROM Stock s
INNER JOIN CarriageLoadSiteTreeView l ON l.CarriageLoadSiteId = s.CarriageLoadSiteId
INNER JOIN Material M on M.MaterialID=s.MaterialId
WHERE s.[Year] = #YearPrev AND
s.[Month] = #MonthPrev AND
s.[Type] = 0 AND
l.LoadSiteType = 0 AND
amount >0 AND
isclear=0 AND
M.MaterialSourceID in (select value from string_split(#materialSourceId, ','))
) as R
INNER JOIN CariageLoadSiteTree T on T.CarriageLoadSiteId=RootId
INNER JOIN string_split(#complexIds, ',') MM ON CAST(MM.value AS int) = R.ComplexId
WHERE AMOUNT-movement-consumption>10
GROUP BY RootName,RootId,ComplexId, T.FullPathId
ORDER BY RootName

Pivot with Dynamic sql as Parameter

I am not sure if this is the way to go though but I would like to know if there is someway to have a stored procedure and pass in a queries to get the values to pivot. I'm not sure if this is a good idea, so sorry if this is a stupid question, but it would be great to pass in a query instead of hard coding every single pivot you want. I have an example of the pivot Stored Procedure that I have coded. This also includes the grand totals for rows and columns.
Don't know if I should add the code as well?
Hope this makes sense.
Please see my stored procedure code below:
CREATE PROCEDURE [dbo].[PivotNoAgentPerc_SP]
AS
DECLARE #columnHeaders VARCHAR (MAX)
SELECT #columnHeaders = COALESCE(#columnHeaders + ', ','')+ QUOTENAME(granteddate)
FROM
(
SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate
FROM ccbsm_ccbsm_salemanagement AS BondSales
LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c
LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id AND accounts_1.deleted = 0
LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id AND ConsultantUser.deleted = 0
LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus
WHERE BondSales.deleted = 0
AND ProvincialArea.SAD_Province = 'Coastal'
AND BondSalesStatus.AuditedStatus = 1
AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
) AS B
ORDER BY B.granteddate
/* GRAND TOTAL COLUMN */
DECLARE #GrandTotalCol NVARCHAR (MAX)
SELECT #GrandTotalCol =
COALESCE (#GrandTotalCol + 'ISNULL ([' + CAST (granteddate AS VARCHAR) +'],0) + ', 'ISNULL([' + CAST(granteddate AS VARCHAR)+ '],0) + ')
FROM
(
SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate
FROM ccbsm_ccbsm_salemanagement AS BondSales
LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c
LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id AND accounts_1.deleted = 0
LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id AND ConsultantUser.deleted = 0
LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus
WHERE BondSales.deleted = 0
AND ProvincialArea.SAD_Province = 'Coastal'
AND BondSalesStatus.AuditedStatus = 1
AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
) AS B
ORDER BY B.granteddate
SET #GrandTotalCol = LEFT (#GrandTotalCol, LEN (#GrandTotalCol)-1)
/* GRAND TOTAL ROW */
DECLARE #GrandTotalRow NVARCHAR(MAX)
SELECT #GrandTotalRow =
COALESCE(#GrandTotalRow + ',ISNULL(SUM([' + CAST(granteddate AS VARCHAR)+']),0)', 'ISNULL(SUM([' + CAST(granteddate AS VARCHAR)+']),0)')
FROM
(
SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate
FROM ccbsm_ccbsm_salemanagement AS BondSales
LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c
LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id AND accounts_1.deleted = 0
LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id AND ConsultantUser.deleted = 0
LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus
WHERE BondSales.deleted = 0
AND ProvincialArea.SAD_Province = 'Coastal'
AND BondSalesStatus.AuditedStatus = 1
AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
)AS B
ORDER BY B.granteddate
/* MAIN QUERY */
DECLARE #FinalQuery NVARCHAR (MAX)
SET #FinalQuery = 'SELECT *, ('+ #GrandTotalCol + ')
AS [Grand Total] INTO #temp_MatchesTotal
FROM
(SELECT
ISNULL(ConsultantUser.user_name,''Total'') AS [Consultant],
EOMONTH(BondSales.granteddate,0) AS [Month Granted],
COALESCE(CAST(CAST(SUM(CASE WHEN accounts_1.name = ''No Agent Channel'' THEN 1 ELSE 0 END) AS DECIMAL)/COUNT(BondSales.name) AS decimal(5,2)), 0) AS NoAgentPerc
FROM ccbsm_ccbsm_salemanagement AS BondSales
LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c
LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id AND accounts_1.deleted = 0
LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id AND ConsultantUser.deleted = 0
LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus
WHERE BondSales.deleted = 0
AND ProvincialArea.SAD_Province = ''Coastal''
AND BondSalesStatus.AuditedStatus = 1
AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
GROUP BY EOMONTH(BondSales.granteddate, 0), ConsultantUser.user_name
) A
PIVOT
(
SUM(NoAgentPerc)
FOR [Month Granted]
IN ('+#columnHeaders +')
) B
ORDER BY [Consultant]
SELECT * FROM #temp_MatchesTotal
UNION ALL
SELECT ''Grand Total'','+ #GrandTotalRow +', ISNULL (SUM([Grand Total]),0)
FROM #temp_MatchesTotal
DROP TABLE #temp_MatchesTotal'
EXECUTE(#FinalQuery)
Sorry if the code is long but I just wanted to show you exactly what I an talking about
I have done this is in procedure and it is working fine. Compare your example to below code
You have to write Dynamic sql query
Example :
declare #s date
declare #e date
declare #dates varchar(MAX)
set #s=DATEADD(DAY,-1,#startdate)
set #e=#enddate
IF OBJECT_ID('tempdb.#DATES') IS NOT NULL
DROP TABLE #DATES
CREATE TABLE #DATES
(
ID INT PRIMARY KEY IDENTITY(1,1),
Date VARCHAR(MAX)
)
WHILE (#s<#e)
BEGIN
INSERT INTO #DATES (Date)
select CONCAT( '[',DATEADD(DAY ,1, #s),']')
set #s=DATEADD(DAY ,1, #s)
END
SELECT #dates= STUFF((
SELECT ',' + SPACE(1) + Date
FROM #DATES
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '')
--AS [Dates]
------------------------Getting RDW Datewise--------------------------------------
declare #queryRDW VARCHAR(MAX)
set #queryRDW='
select * from (
SELECT SUM(RecordValue)/60 RecordValue,RecordType ,Computationdate ,t2.ProjectResourceId,t1.ResourceCode,t1.ResourceName
FROM tblProjectResource t1 INNER JOIN tblDeploymentWorkbook t2 on t1.ProjectResourceId=t2.ProjectResourceId
WHERE
RecordType=''RDW'' and t2.SubCategoryId IN (1)
GROUP BY
RecordType, Computationdate,t2.ProjectResourceId,t1.resourceCode,t1.ResourceName
HAVING
Computationdate >= '''+Cast(#startdate as varchar)+''' and Computationdate <= '''+Cast(#enddate as varchar)+'''
)tab
PIVOT(
SUM(RecordValue) for ComputationDate in ( '+#dates+')
)t
Order By ResourceName
'
exec (#queryRDW)

How to optimise this stored procedure?

I have the stored procedure below and I am having two issues with it
It is running very slowly, and
It is returning a blank result set
The idea for the stored procedure is to do a sequence check to find if any account numbers have not been assigned.
Step 1 loops through all the branches and builds up the tempdetails table.
After that it creates the list of all the numbers that have been used and uses that to delete everything that exists to leave a list of those accountnumbers that do not exist,
But een though I know there are missing account numbers, aside from the exceptionally long tun time it is returning a blank result set.
Anyone have any ideas what is going wrong with it?
Thanks
ALTER PROCEDURE [dbo].[PracticeFindMissingSequenceDetail]
#pracId VARCHAR(128),
#Prefix VARCHAR(256)
AS
BEGIN
DECLARE #TempDetails TABLE (SequenceCheck VARCHAR(24),
Prefix VARCHAR(4),
BranchName VARCHAR(256),
RisStatus VARCHAR(256),
Rislink VARCHAR(256)
);
DECLARE #Branchlist TABLE (BranchId INTEGER,
BranchName VARCHAR(256),
BranchPrefix VARCHAR(4),
PrefixLength INT,
SequenceLength INT
);
DECLARE #TempPatNo TABLE (Patno VARCHAR(24));
DECLARE #BranchName VARCHAR(256),
#BranchPrefix VARCHAR(256),
#PrefixLength INT,
#BranchId INT,
#SequenceLength INT,
#rangestart INTEGER,
#rangeend INTEGER,
#rangenow INTEGER,
#startDate DATETIME,
#Patno VARCHAR(128),
#FormatZeroes VARCHAR(3),
#CurrentLength INT,
#RangeString VARCHAR(256);
INSERT INTO #Branchlist (BranchId, BranchName, BranchPrefix, PrefixLength, SequenceLength)
SELECT
b.id, b.name, b.prefix, PrefixLength, SequenceLength
FROM
Branch b
INNER JOIN
Practice pr ON pr.id = b.practiceid
INNER JOIN
[Sequence] s ON s.id = b.id
WHERE
pr.APIKey = #pracID
AND b.inactive = 0
AND b.prefix = #Prefix
/* insert values for each branch into table*/
DECLARE BranchPointer CURSOR FOR
SELECT BranchID FROM #Branchlist
OPEN BranchPointer
FETCH NEXT FROM BranchPointer INTO #BranchId
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #BranchPrefix = (SELECT BranchPrefix
FROM #Branchlist
WHERE BranchId = #BranchId)
SELECT #PrefixLength = (SELECT PrefixLength
FROM #Branchlist
WHERE BranchId = #BranchId)
SELECT #SequenceLength = (SELEct SequenceLength
FROM #Branchlist
WHERE BranchId = #BranchId)
/* Set the starting date from the sequence */
SELECT #startDate = (SELECT MIN(MinimumSequenceDate)
FROM [Sequence] s
WHERE s.id = #BranchId)
/*get the earliest number in the sequence from the startdate*/
SELECT #rangestart = (SELECT MIN(SUBSTRING(v.bookingnumber, 3, LEN(bookingnumber)))
FROM Visit v
INNER join Branch b ON b.id = v.branchid
INNER join Practice pr ON pr.id = b.practiceid
WHERE pr.APIKey = #pracId
AND LEFT(v.bookingnumber, 2) = #Prefix
AND v.date >= #startDate
AND v.branchid = #BranchId);
/*get the latest number in the sequence from the startdate*/
SELECT #rangeend = (SELECT MAX(SUBSTRING(v.bookingnumber, 3, LEN(bookingnumber)))
FROM Visit v
INNER JOIN Branch b ON b.id = v.branchid
INNER JOIN Practice pr ON pr.id = b.practiceid
WHERE pr.APIKey = #pracId
AND LEFT(v.bookingnumber, 2) = #Prefix
AND v.date >= #startDate
AND v.branchid = #BranchId);
SET #RangeNow = #rangestart
WHILE #rangenow < #rangeend
BEGIN
/*check if leading zeroes are needed in the number and add them if needed*/
SET #RangeString = CAST(#RangeNow AS VARCHAR(256))
SET #CurrentLength = LEN(#rangenow)
IF #prefixlength + #currentlength < #SequenceLength
WHILE #CurrentLength + #PrefixLength < #SequenceLength
BEGIN
SET #RangeString = '0' + #RangeString;
SET #currentlength = LEN(#RangeString);
END;
/*Insert full sequence into temporary table*/
INSERT INTO #TempDetails (SequenceCheck, Prefix, BranchName)
SELECT #Prefix + #RangeString, #Prefix, #BranchName
SET #rangenow =#rangenow+1
END;
FETCH NEXT FROM BranchPointer INTO #BranchName
END
CLOSE BranchPointer
DEALLOCATE BranchPointer
/*delete existing sequence numbers from table*/
INSERT INTO #TempPatNo (PatNo)
SELECT BookingNumber
FROM Visit v1
INNER JOIN Branch b1 ON b1.id = v1.branchid
INNER JOIN Practice pr1 ON pr1.id = b1.practiceid
WHERE pr1.APIKey = #pracId
DELETE #TempDetails
WHERE sequencecheck IN (SELECT patNo FROM #TempPatNo)
/*Insert the status and link for error messages*/
UPDATE #tempDetails
SET RisStatus = (SELECT Status
FROM RISErrors r
INNER JOIN Practice pr ON pr.id = r.PracticeId
WHERE pr.APIKey = #pracId
AND VisitNumber = SequenceCheck
AND r.id = (SELECT MAX(r1.id)
FROM RISErrors r1
INNER JOIN Practice pr1 ON pr1.id = r1.PracticeId
WHERE pr1.APIKey = #pracId
AND VisitNumber = SequenceCheck)),
RisLink = 'http://billing.cryanic.co.za/Clinton/RISErrors?searchquery=' + SequenceCheck
/*return missing numbers into sequence control callong procedure*/
SELECT DISTINCT SequenceCheck, RisStatus, Rislink
FROM #TempDetails
END
After reading your procedure, I made some assumptions:
there is a one-to-one relationsship between sequence and branch
the visits are the details of a sequence
the BranchName and BranchPrefix aren't needed.
I recommend to not do lookups by BranchID but instead retrieve the values from the cursor query. The table BranchList isn't needed, you can base the cursor on the query directly. Also, the TempPatNo table can be avoided.
Here's what I have come up with:
ALTER PROCEDURE [dbo].[PracticeFindMissingSequenceDetail]
#pracId VARCHAR(128),
#Prefix VARCHAR(256)
AS
BEGIN
DECLARE #TempDetails TABLE (
BranchID INT,
SequenceCheck VARCHAR(24),
RisStatus VARCHAR(256),
Rislink VARCHAR(256)
);
DECLARE
#PrefixLength INT,
#BranchId INT,
#SequenceLength INT,
#rangestart INTEGER,
#rangeend INTEGER,
#rangenow INTEGER,
#startDate DATETIME;
/* insert values for each branch into table*/
DECLARE BranchPointer CURSOR FOR
SELECT b.id, PrefixLength, SequenceLength, s.MinimumSequenceDate
FROM Branch b
INNER JOIN Practice pr ON pr.id = b.practiceid
INNER JOIN [Sequence] s ON s.id = b.id
WHERE pr.APIKey = #pracID
AND b.prefix = #Prefix
AND b.inactive = 0
OPEN BranchPointer
FETCH NEXT FROM BranchPointer INTO #BranchId, #PrefixLength, #SequenceLength, #startDate
WHILE ##FETCH_STATUS = 0
BEGIN
/*get the earliest and latest number in the sequence from the startdate*/
SELECT
#rangestart = MIN(SUBSTRING(v.bookingnumber, 3, LEN(v.bookingnumber))),
#rangeend = MAX(SUBSTRING(v.bookingnumber, 3, LEN(v.bookingnumber)))
FROM Visit v
WHERE v.branchid = #BranchId
AND v.date >= #startDate
AND LEFT(v.bookingnumber, 2) = #Prefix;
SET #RangeNow = #rangestart
WHILE #rangenow < #rangeend
BEGIN
/*Insert full sequence into temporary table*/
INSERT INTO #TempDetails (BranchID, SequenceCheck)
SELECT #BranchId,
#Prefix + REPLICATE('0', #SequenceLength-#PrefixLength-LEN(#rangenow)) + CAST(#RangeNow AS VARCHAR(256));
SET #rangenow =#rangenow+1
END;
FETCH NEXT FROM BranchPointer INTO #BranchId, #PrefixLength, #SequenceLength, #startDate
END
CLOSE BranchPointer
DEALLOCATE BranchPointer
/*delete existing sequence numbers from table*/
DELETE FROM #TempDetails
FROM #TempDetails t
INNER JOIN Visit v ON t.BranchID = v.branchid
WHERE t.SequenceCheck = v.BookingNumber
/*Insert the status and link for error messages*/
UPDATE #tempDetails
SET RisStatus = (SELECT Status
FROM RISErrors r
INNER JOIN Practice pr ON pr.id = r.PracticeId
WHERE pr.APIKey = #pracId
AND VisitNumber = SequenceCheck
AND r.id = (SELECT MAX(r1.id)
FROM RISErrors r1
INNER JOIN Practice pr1 ON pr1.id = r1.PracticeId
WHERE pr1.APIKey = #pracId
AND VisitNumber = SequenceCheck)),
RisLink = 'http://billing.cryanic.co.za/Clinton/RISErrors?searchquery=' + SequenceCheck
/*return missing numbers into sequence control callong procedure*/
SELECT DISTINCT SequenceCheck, RisStatus, Rislink
FROM #TempDetails
END

Why UNION used in a stored procedure in derived table?

I am not author of the stored procedure and I am wondering why they used UNION in SELECT statement when selecting from the derived table ...
If I comment out the whole UNION ALL SELECT statement, I get the same result with the same basically performance.
So I am just wonder why it is there? What kind of trick does it makes?
Below is the whole stored procedure in case I am missing something
ALTER PROCEDURE [dbo].[rptActivityLog] --'1/1/2016', '2/3/2016'
(#DateFrom datetime = null,
#DateTo datetime = null,
#UserGuid uniqueidentifier = null,
#CurrentUserGuid uniqueidentifier = NULL)
AS
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #UserID SMALLINT
SELECT #UserID = UserID
FROM tblUsers
WHERE (UserGUID = #UserGuid)
DECLARE #ValidOfficeGuids TABLE (OfficeGuid uniqueidentifier primary key)
--if user is in tblUserQuotingOffice then use only that Office
--otherwise they will have access to all offices
IF EXISTS (SELECT OfficeGuid
FROM tblUserQuotingOffice
WHERE UserGuid = #CurrentUserGuid)
BEGIN
INSERT INTO #ValidOfficeGuids
SELECT OfficeGuid
FROM tblUserQuotingOffice
WHERE UserGuid = #CurrentUserGuid
END
ELSE
BEGIN
INSERT INTO #ValidOfficeGuids
SELECT OfficeGUID
FROM tblClientOffices
END
DECLARE #compareDateFrom DATETIME
set #compareDateFrom = CAST(CONVERT(VARCHAR(50), #DateFrom, 101) AS DATETIME)
declare #compareDateTo datetime
set #compareDateTo = DateAdd(ms, -2, DateAdd(d, 1, CAST(CONVERT(VARCHAR(50), DATEADD(day, 7, #DateTo), 101) AS DATETIME)))
--First get the log entries
declare #logResults table
(
ID int primary key not null
, IdentifierGuid uniqueidentifier
)
insert into #logResults
select
l.ID
, l.IndentifierGuid
from
tblLog l
where
l.ActionDate between #compareDateFrom and #compareDateTo
and l.IndentifierGuid is not null
select
distinct
T.UserName
, T.ControlNo
, T.InsuredPolicyName
, Replace(Replace(T.[Action],Char(10),''),Char(13),'') as [Action]
, T.ActionDate
, T.LineName as LOB
from
(
select
u.UserName
, q.ControlNo
, q.InsuredPolicyName
, l.[Action]
, l.ActionDate
, ll.LineName
, l.UserID
from
#logResults r
inner join tblLog l on r.ID = l.ID
inner join tblUsers u on l.UserID = u.UserID
inner join tblQuotes q on r.IdentifierGuid = q.QuoteGUID
inner join lstLines ll on q.LineGUID = ll.LineGUID
-- WHY DO WE USE BELOW UNION STATEMENT??????????????????????????????????
union
select
u.UserName
, q.ControlNo
, q.InsuredPolicyName
, l.[Action]
, l.ActionDate
, ll.LineName
, l.UserID
from
#logResults r
inner join tblLog l on r.ID = l.ID
inner join tblUsers u on l.UserID = u.UserID
inner join tblQuotes q on r.IdentifierGuid = q.ControlGUID
inner join lstLines ll on q.LineGUID = ll.LineGUID
) T
WHERE IsNull(#UserID, T.UserID) = T.UserID
order by
T.ActionDate
There is a difference in the join with tblQuotes, looks like the union is meant to union two different datasets (one for QuoteGUIDs and one for ControlGUIDs)

but give me error that invalid object name #temp2

Alter procedure spMRI_TAG_try
#DocNum int
as
declare #cnt int
declare #count int
declare #cardname nvarchar(100)
declare #Docdate datetime
declare #itemCode nvarchar(50)
declare #Dscription nvarchar(100)
declare #Quantity numeric(19,6)
declare #ManBtchNum char(1)
declare #SalPackUn numeric(19,6)
declare #ExpDate datetime
begin
set #cnt = 1
select #Count = pdn1.Quantity/OITM.SalPackUn from pdn1 inner join OITM on pdn1.ItemCode=OITM.ItemCode
while #cnt <= #count
insert into #temp2 values(#cardname,#DocDate,#itemcode,#Dscription,#Quantity,#ManBtchNum,#SalPackUn,#ExpDate)
select #cardname = a.CardName,#DocDate=a.DocDate,#itemcode=b.ItemCode,#Dscription=b.Dscription,#Quantity=b.Quantity,#ManBtchNum=c.ManBtchNum,#SalPackUn=c.SalPackUn,#ExpDate=d.ExpDate
from OPDN a inner join PDN1 b on a.DocEntry = b.DocEntry inner join OITM c on c.ItemCode = b.ItemCode inner join OBTN d on c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
set #cnt=#cnt+1
end
select * from #temp2
but gives me an invalid object name #temp2 error.
Create temp table before your while loop:
create table #temp2 (Cardname ...)
while #cnt <= #count
insert into #temp2 values(#cardname,#DocDate,#itemcode,#Dscription,#Quantity,#ManBtchNum,#SalPackUn,#ExpDate)
select #cardname = a.CardName,#DocDate=a.DocDate,#itemcode=b.ItemCode,#Dscription=b.Dscription,#Quantity=b.Quantity,#ManBtchNum=c.ManBtchNum,#SalPackUn=c.SalPackUn,#ExpDate=d.ExpDate
Two points here:
Not sure why you are using looping - Try set based approaches. You can solve most of the problems in set based queries
You can create temp tables using select * into #temp2... Check for that syntax in msdn
To be honest your SP is a one big messed up code :)
I suggest you to rewrite it like this:
ALTER PROCEDURE spMRI_TAG_try
#DocNum int
AS
--Drop table if it exists
IF OBJECT_ID(N'#temp2') IS NOT NULL DROP TABLE #temp2
--create table
CREATE TABLE #temp2 (
cardname nvarchar(100),
Docdate datetime,
itemCode nvarchar(50),
Dscription nvarchar(100),
Quantity numeric(19,6),
ManBtchNum char(1),
SalPackUn numeric(19,6),
ExpDate datetime
)
--Make the insertion
INSERT INTO #temp2
SELECT a.CardName,
a.DocDate,
b.ItemCode,
b.Dscription,
b.Quantity,
c.ManBtchNum,
c.SalPackUn,
d.ExpDate
FROM OPDN a
INNER JOIN PDN1 b
ON a.DocEntry = b.DocEntry
INNER JOIN OITM c
ON c.ItemCode = b.ItemCode
INNER JOIN OBTN d
ON c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
--output
SELECT *
FROM #temp2
No need a while loop (I can not even understand how you will switch through the rows, in your solution it will write the same row the '#count' times), you can write all data directly in temp table.
You get error because of there is no #temp2 table on the moment you are trying to insert, also there is no checking if the table already exists.
As was noted in answer by Kannan Kandasamy, the one more way is to use SELECT * INTO #temp2, it can be achieved this way:
ALTER PROCEDURE spMRI_TAG_try
#DocNum int
AS
IF OBJECT_ID(N'#temp2') IS NOT NULL DROP TABLE #temp2
SELECT a.CardName,
a.DocDate,
b.ItemCode,
b.Dscription,
b.Quantity,
c.ManBtchNum,
c.SalPackUn,
d.ExpDate
INTO #temp2
FROM OPDN a
INNER JOIN PDN1 b
ON a.DocEntry = b.DocEntry
INNER JOIN OITM c
ON c.ItemCode = b.ItemCode
INNER JOIN OBTN d
ON c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
SELECT *
FROM #temp2

Resources