SQL Server 2014 stored procedure is slow - sql

I have a stored procedure to calculate receipt and up to today I didn't have any problems with it until I had to execute it in a database with 100'000 rows. It's much too slow and runs for at least 3 hours, and it's not finished yet..
Is there a way to optimize this ?
Here the code:
Declare #sousTotal numeric(16,2),
#TotalTx1 numeric(18,4),
#TotalTx2 numeric(18,4),
#TotalTx3 numeric(18,4),
#Taux1 numeric(18,4),
#Taux2 numeric(18,4),
#Taux3 numeric(18,4),
#totalEscompte numeric(16,2),
#totalFacture numeric(16,2),
#MontantPaiement numeric(16,2)
Begin
BEGIN TRANSACTION;
BEGIN TRY
select top 1 #Taux1 = TauxTaxe1,#Taux2 = TauxTaxe2 ,#Taux3 = TauxTaxe3 from tbFactureEntete where ID = #IdFacture and IDCompagnie = #IDCie
select #sousTotal =sum(sousTotal),#TotalTx1 = sum(totalTx1),#TotalTx2 = sum(totalTx2),#TotalTx3 = sum(totalTx3),
#totalEscompte = sum(totalEscompte ),#totalFacture = sum(totalFacture) from(
select SUM(isnull(A.TotalLigne,0)) AS sousTotal ,
case taxe1 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux1 / 100
end AS totalTx1,
case taxe2 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux2 / 100
end AS totalTx2,
case taxe3 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux3 / 100
end AS totalTx3,
sum(isnull(MontantEscompte,0)) as totalEscompte ,sum(isnull(TotalLigne,0)) + case taxe1 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux1 / 100
end +
case taxe2 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux2 / 100
end +
case taxe3 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux3 / 100
end as totalFacture
from tbfactureDetail A
where IdFacture = #IdFacture and A.IDCompagnie = #IDCie
group by taxe1,taxe2,taxe3) as AA
select #MontantPaiement = SUM(MontantPaiement) from tbFacturePaiement
where IdFacture = #IdFacture
update tbFactureEntete
set Total_AvantTaxe = #sousTotal,
totalTaxe1 = #TotalTx1,
totalTaxe2 = #TotalTx2,
totalTaxe3 = #TotalTx3,
TotalEscompte = isnull(#totalEscompte,0),
TotalFacture = isnull(#totalFacture,0),
TotalPaiementCR = isnull(#MontantPaiement,0) ,
TotalSolde = isnull(#totalFacture,0) - isnull(#MontantPaiement,0)
where ID = #IdFacture and IDCompagnie = #IDCie
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF ##TRANCOUNT > 0
COMMIT TRANSACTION;
return
End
Thanks again!!

Depending on the cardinality of IdFacture and IDCompagnie in table tbfactureDetail, an index would help things along if one is missing.
if there are many different values of IdCompagnie for the many different values of IDFacture
CREATE NONCLUSTERED INDEX IX_NewIdx_Name
ON tbfactureDetail (IdFacture,IdCompagnie)
If there are relatively few IdCompagnie per IDfacture, you could use an Include.
CREATE NONCLUSTERED INDEX IX_NewIdx_Name
ON tbfactureDetail (IdFacture)
INCLUDE (IdCompagnie)
I think this is mathematically the same and a bit more optimal for the code.
BEGIN TRY
select top 1 #Taux1 = TauxTaxe1
, #Taux2 = TauxTaxe2
, #Taux3 = TauxTaxe3
from tbFactureEntete
where ID = #IdFacture and IDCompagnie = #IDCie
select #sousTotal =sum(isnull(A.TotalLigne,0))
, #TotalTx1 = sum(taxe1 * isnull(A.TotalLigne,0) * #Taux1 / 100)
, #TotalTx2 = sum(taxe2 * isnull(A.TotalLigne,0) * #Taux2 / 100)
, #TotalTx3 = sum(taxe3 * isnull(A.TotalLigne,0) * #Taux3 / 100)
, #totalEscompte = sum(isnull(MontantEscompte,0) )
, #totalFacture =
sum(taxe1 * isnull(A.TotalLigne,0) * #Taux1 / 100) +
sum(taxe2 * isnull(A.TotalLigne,0) * #Taux2 / 100) +
sum(taxe3 * isnull(A.TotalLigne,0) * #Taux3 / 100)
from tbfactureDetail A
where IdFacture = #IdFacture and A.IDCompagnie = #IDCie
select #MontantPaiement = SUM(MontantPaiement)
from tbFacturePaiement
where IdFacture = #IdFacture
update tbFactureEntete
set Total_AvantTaxe = #sousTotal
, totalTaxe1 = #TotalTx1
, totalTaxe2 = #TotalTx2
, totalTaxe3 = #TotalTx3
, TotalEscompte = isnull(#totalEscompte,0)
, TotalFacture = isnull(#totalFacture,0)
, TotalPaiementCR = isnull(#MontantPaiement,0)
, TotalSolde = isnull(#totalFacture,0) - isnull(#MontantPaiement,0)
where ID = #IdFacture and IDCompagnie = #IDCie
END TRY

Related

Two fast queries, slow when combined

I have this massive query that I am trying to add a left join to. The addition is commented out.
The main query runs < 4 sec, 32,000 rows.
The commented part runs < 1 sec, 51,000 rows.
But, when I combine them i.e join the second query, the whole thing runs in 15 sec.
There are already 2 massive joins in the original query (50,000 rows both), so I don't get why this join is special.
PS: I might also be doing other suboptimal things, please criticize.
select
*,
case
when t2.status = 1 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.04, 2)
when t2.status = 2 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.03, 2)
when t2.status = 3 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.02, 2)
when t2.status = 4 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.01, 2)
else 0
end as bonus
from (
select *,
case
when t1.gratis = 1 then 10
when t1.price_vat = 0 or t1.price = 0 then
case
when t1.stock > 0 or soldLast180DaysQty > 0 then -1
when t1.stock = 0 then 12
end
when t1.buyprice = 0 then
case
when t1.stock > 0 then -1
when t1.stock = 0 then 12
end
when soldLast180DaysQty < 0 then 1
when t1.age_days < 60 then 9
when t1.last_import <= 180 then
case
when t1.soldLast180DaysQty <= t1.stock then 0
when t1.soldLast180DaysQty > t1.stock then 7
when t1.stock = 0 then 5
end
when t1.last_import >= 180 and t1.stock = 0 then
case
when soldLast180DaysQty > 0 then 10
when soldLast180DaysQty = 0 then 11
end
when t1.last_import >= 180 then
case
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) < 0.3 and t1.stock_retail / t1.stock >= 0.9 then 5
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0 and 0.1 then 1
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.1 and 0.2 then 2
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.2 and 0.3 then 3
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.3 and 0.4 then 4
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.4 and 0.7 then 0
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) >= 0.9 then 6
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.8 and 0.9 then 7
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.7 and 0.8 then 8
end
end as status,
round(t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) * 100, 0) as ratio
from (
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
si.anvat as vat,
si.ansaleprice as price_vat,
round(si.anrtprice, 2) as price,
cenovnik.clientPrice, -- <---------------------- This part
round(si.anbuyprice, 2) as buyprice,
concat(round(anpricesupp, 2), ' ', acpurchcurr) as fakturna,
round(si.anrtprice - si.anbuyprice, 2) as profit,
case
when si.anrtprice is not null and si.anrtprice > 0 and si.anbuyprice is not null and si.anbuyprice > 0
then round((si.anrtprice / si.anbuyprice - 1) * 100, 0)
end as margin,
cast(si.acfieldsa as nvarchar(12)) as [group],
cast(rtrim(si.acClassif2) as nvarchar(16)) as category,
cast(rtrim(ss.acsubject) as nvarchar(7)) as supplier_code,
cast(left(ss.acname2, 30) as nvarchar(30)) as supplier_name,
rtrim(si.acclassif) as rebate,
si.anFieldNA as webActive,
si.anfieldNF as gratis,
case
when si.acpicture is not null then 'true'
else 'false'
end as picture,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse = '00051'), 0) as stock_warehouse,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse <> '00051'), 0) as stock_retail,
isnull((select sum(anstock) from the_stock where acident = si.acident), 0) as stock,
isnull((select sum(anReserved) from the_stock where acident = si.acident), 0) as stock_reserved,
isnull((select sum(anvalue) from the_stock where acident = si.acident), 0) as stock_value,
(
select isnull(datediff(day, max(m.addate), getdate()), 9999)
from the_moveitem mi
left join the_move m
on mi.ackey = m.ackey
where mi.acident = si.acident and m.acDocType in ('1900', '1000', '6800', '1A00')
) as last_import,
isnull(round(soldLast180Days.soldLast180DaysQty, 0), 0) soldLast180DaysQty,
isnull(round(soldLast180Days.soldLast180DaysCogs, 0), 0) soldLast180DaysCogs,
isnull(round(soldLast180Days.soldLast180DaysRevenue, 0), 0) soldLast180DaysRevenue,
isnull(round(soldLast180Days.soldLast180DaysProfit, 0), 0) soldLast180DaysProfit,
datediff(day, si.adtimeins, getdate()) as age_days
from the_setitem si
/*
left join (
SELECT
si.acident sku,
case
when dogovoren.anPrice is null and matrica.anRebate is null then si.anRTPrice
when dogovoren.anPrice is not null then dogovoren.anPrice
when dogovoren.anPrice is null then si.anRTPrice * (1 - matrica.anRebate/100)
end as clientPrice
FROM tHE_SetItem si
left join (
select acident, anPrice
from vHE_SetSubjPriceItemExtToday
where acsubject = '1111'
) dogovoren
on dogovoren.acident = si.acident
left join (
select acClassif, anRebate
from vHE_SetSubjTypePriceCateg
where acSubjType = (select acsubjtypebuyer from tHE_SetSubj where acsubject = '1111')
) matrica
on si.acClassif = matrica.acClassif
) cenovnik
on cenovnik.sku = si.acident
*/
left join tHE_SetSubj ss
on ss.acsubject = si.acsupplier
left join (
select
mi.acident,
sum(mi.anQty) soldLast180DaysQty,
sum(mi.anQty * mi.anStockPrice) soldLast180DaysCogs,
sum(mi.anPVVATBase) soldLast180DaysRevenue,
sum(mi.anPVVATBase - mi.anQty * mi.anStockPrice) soldLast180DaysProfit
from the_moveitem mi
left join the_move m
on m.ackey = mi.ackey
where m.acDocType in ('3000', '3050', '3190', '3800', '3550', '3X10', '3950', '3500', '3510', '6700', '3A00', '3210', '3220', '3230', '3240', '3450', '3250', '3260', '3270', '3540', '3460', '3280', '3290', '3310', '3320', '3440', '3330', '3340', '3350', '3360', '3370', '3380', '3390', '3410', '3470', '3420', '3430', '3480', '3490', '3520', '3530', '3560', '3610', '2540', '2740', '2730'
) and m.addate >= getdate() - 180
group by mi.acident
) soldLast180Days
on soldLast180Days.acIdent = si.acident
) t1
) t2
where
t2.status < 11
order by
t2.status asc,
t2.stock_value desc
I am using SQL Server if it's relevant.
Not really an answer - but when I've had this problem I've just created temporary tables. In SQL Server you prefix the table name with # and they will get deleted when your session ends.
You might realise your nested table t1 as a temporary table #t1
CREATE TABLE #t1 (id INT, code NVARCHAR(7), etc...)
INSERT INTO #t1
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
etc..
SELECT * FROM .... #t1 ...
Replace all references to t1 with #t1

SQL query taking longer time to execute

I'm trying to execute the query. It take 32 min to execute. I have tried NOLOCK but only optimized it with 3 min.
the query is given below:-
SELECT PO.payday, PO.facility, PO.department, PO.workcenter, PO.shift, PO.team, PO.orderno, PO.fg_productno,
PO.sfg_productno, NoCarton = '1', NoPack = 5, NoCigarette = PO.nocigarette, VNC.sampleid, VNC.comment,
VNC.createdby, SampleDateTime = dbo.AF_GetUTCToLocal(VNC.UTCStartDate),
SampleTime = Cast(CONVERT(CHAR(10), VNC.utcstartdate, 101) AS DATETIME), VNC.ncgroup, VNC.productcomponent,
VNC.nc, VNC.ncname, VNC.weightingfactor, VNC.ConsumerSensitive, VNC.[lowunits], VNC.[low %], VNC.[highunits],
VNC.[high %], VNC.vqi, VNC.deepcontrol,
--Modification done for CHE10045964
PO.ResourceClassName
FROM
(SELECT PayDay = WCS.payday, Facility = R.facility, Department = R.department, WorkCenter = R.workcenter,
Shift = WCS.workperiod, Team = SD.teamid, OrderNo = WO.orderno,
FG_ProductNo = P.productno + Isnull('.' + P.productrevision, ''),
SFG_ProductNo = CASE
WHEN UCHSC.attribute_ != P.productno
THEN UCHSC.attribute_
ELSE NULL
END,
WO.actualstartdate, WO.actualcompletiondate,
NoCigarette = dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK') ,
RC.Name as ResourceClassName
FROM order_header OH
INNER JOIN dbo.wip_order WO ON OH.orderno = WO.orderno
INNER JOIN dbo.order_detail OD ON OD.orderno = WO.orderno
INNER JOIN dbo. product P ON WO.productid = P.id
INNER JOIN dbo.resource_ R ON R.resourcename = WO.resourcename AND R.resourcetype = WO.resourcetype
Inner Join dbo.Resource_Class RC ON R.ResourceClassID = RC.ID
INNER JOIN dbo.work_center_work_schedule WCS ON WO.oawipentityid = WCS.id
INNER JOIN at_work_center_work_schedule_detail SD ON WCS.id = SD.workcenterworkscheduleid
LEFT JOIN dbo.unit_characteristic UCHSC ON UCHSC.unitid = OD.unitid
AND UCHSC.characteristic = 'ZPPPI_SPA_CIGARETTE'
WHERE OH.ordertype = 23
GROUP BY WCS.payday, R.facility, R.department, R.workcenter, WCS.workperiod, SD.teamid,
WO.orderno, P.productno + Isnull('.' + P.productrevision, ''),
CASE
WHEN UCHSC.attribute_ != P.productno THEN UCHSC.attribute_
ELSE NULL
END,
WO.actualstartdate, WO.actualcompletiondate,
dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK'),
RC.Name
) PO INNER JOIN
(
SELECT NC.orderno, NC.sampleid, NC.comment, NC.deepcontrol, NC.createdby, NC.utcstartdate, NC.ncgroup, NC.productcomponent,
NC.nc, NC.ncname, NC.weightingfactor, NC.ConsumerSensitive, NC.[lowunits], NC.[low %], NC.[highunits], NC.[high %],
VQI = Round(NC.weightingfactor * ( Log (1 + [low %] / 3.0 + [high %]) ), 0),
--Added By Sukanya Biswas(CHE10045964)
NC.WorkCenter
FROM (SELECT orderno, b.sampleid, b.comment, b.deepcontrol, b.utcstartdate, b.ncgroup, b.productcomponent,
b.nc, b.ncname, b.weightingfactor, b.ConsumerSensitive, b.createdby,
[LowUnits] = Isnull(b.[1], 0),
[Low %] = CASE CONVERT(NVARCHAR(1),b.deepcontrol) + b.ncgroup
WHEN '0Bundle' THEN CASE WHEN (Isnull(b.[1], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 100 END
WHEN '1Bundle' THEN CASE WHEN (Isnull(b.[1], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 100 END
WHEN '0Pack' THEN CASE WHEN (Isnull(b.[1], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * NoofCigarette END
WHEN '1Pack' THEN CASE WHEN (Isnull(b.[1], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * NoofCigarette END
WHEN '0Cigarette' THEN CASE WHEN (Isnull(b.[1], 0) * 5 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 5 END
WHEN '1Cigarette' THEN CASE WHEN (Isnull(b.[1], 0) * 1 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 1 END
WHEN '0Filter' THEN CASE WHEN (Isnull(b.[1], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 10 END
WHEN '1Filter' THEN CASE WHEN (Isnull(b.[1], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 10 END
ELSE Isnull(b.[1], 0)
END, [HighUnits] = Isnull(b.[2], 0),
[High %] = CASE CONVERT(NVARCHAR(1),b.deepcontrol) + b.ncgroup
WHEN '0Bundle' THEN CASE WHEN (Isnull(b.[2], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 100 END
WHEN '1Bundle' THEN CASE WHEN (Isnull(b.[2], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 100 END
WHEN '0Pack' THEN CASE WHEN (Isnull(b.[2], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * NoofCigarette END
WHEN '1Pack' THEN CASE WHEN (Isnull(b.[2], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * NoofCigarette END
WHEN '0Cigarette' THEN CASE WHEN (Isnull(b.[2], 0) * 5 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 5 END
WHEN '1Cigarette' THEN CASE WHEN (Isnull(b.[2], 0) * 1 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 1 END
WHEN '0Filter' THEN CASE WHEN (Isnull(b.[2], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 10 END
WHEN '1Filter' THEN CASE WHEN (Isnull(b.[2], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 10 END
ELSE Isnull(b.[2], 0)
END ,
--Added By Sukanya Biswas(CHE10045964)
B.WorkCenter
FROM (SELECT D .orderno, SampleID = DTS.id,
--Added By Sukanya Biswas(CHE10045964)
DL.WorkCenter,
Comment = CASE Isnull(DTS.comment_, '')
WHEN '' THEN 'N/A'
ELSE DTS.comment_
END, UTCStartDate = DTS.actualstartdate, NC.ncgroup, NC.productcomponent, NC.nc, NC.ncname,
NC.weightingfactor, NC.ConsumerSensitive,
Severity = Isnull(QD.qualitydefectseverityid, 0),
QD.noofdefects, DTS.createdby, DeepControl = DTS.overridesumresults,
NoofCigarette = dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK')
FROM dbo.disposition D
INNER JOIN dbo.disposition_line DL ON D .disposition = DL.disposition
--Inner Join dbo.Work_Center WC ON DL.Workcenter = WC.Workcenter
INNER JOIN dbo.disposition_test DT ON DT.disposition = D .disposition
AND DT.linesequenceno = DL.linesequenceno
INNER JOIN dbo.disposition_test_sample DTS ON DTS.dispositiontestid = DT.id
LEFT JOIN quality_defect QD ON QD.dispositiontestsampleid = DTS.id
INNER JOIN dbo.AV_RPT_VSI_Nonconformity NC ON Isnull(QD.defectreasoncode, '00.00.00') = NC.nc
LEFT JOIN ORDER_DETAIL OD ON OD.ORDERNO=D.ORDERNO
WHERE DL.linecode = 'VQ'
) A
PIVOT (Sum(a.noofdefects)
FOR severity IN ([1],[2]))
B)
NC
As per your query filter and columns needed, please make index on respected columns.
By default SQL will create clustered index on your primary key, but you may create some other unclustered index on your table to make your execution faster.
You may find this link for your reference or Google it there are hundreds of article available on Internet for same.
"https://learn.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-2017"

SQL Server case in where clause conditionally

select *
from someTable
where currencyid = #currencyid --CaseA
or (Currencyid in (8,11) or (#Currencyid = 0)) --CaseB
How to modify such query so that when #currencyid = 0 the condition will be set on ONLY CaseB while others set as CaseA?
For example:
if #currencyid = 0 then the end query to be executed is
select *
from someTable
where currencyid = (Currencyid in (8,11) or (#Currencyid = 0))
if #currencyid = 8 then the end query to be executed is
select *
from someTable
where currencyid = #currencyid
SELECT *
FROM someTable
WHERE (currencyid = #Currencyid AND #Currencyid != 0)
OR (Currencyid IN (8, 11) AND #Currencyid = 0)
--OPTION(RECOMPILE)

how to set default value in a output parameter

in my following query i want to set 0, 0, 0 in #TMarks, #OMarks, #Percentage respectively if the select statement used with them returns nothing
create procedure [dbo].[TestRecordSelectMInfo]
#GRNo varchar(4),
#SessionId numeric(1),
#TestTypeId numeric(1),
#TMarks int output,
#OMarks numeric(4) output,
#Percentage numeric(4) output,
#Grade varchar(4) output
as
begin
SELECT Subjects.Subject, Marks.TotalMarks, Marks.PassingMarks, TestRecord.Marks, Result = case when TestRecord.Marks = 'A' then 'A' else case when cast(TestRecord.Marks as numeric) < Marks.PassingMarks then 'F' else 'P' end end FROM Subjects INNER JOIN Marks ON Subjects.SubjectId = Marks.SubjectId INNER JOIN TestRecord ON Subjects.SubjectId = TestRecord.SubjectId AND Marks.TestTypeId = TestRecord.TestTypeId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRno
set #TMarks = (select sum(Marks.TotalMarks) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks )
set #OMarks = (select sum(cast(TestRecord.Marks as numeric)) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks)
set #Percentage = #OMarks / #TMarks * 100;
set #Grade = case
when #Percentage < 50
then
'NIL'
else
case
when #Percentage < 60
then
'C'
else
case
when #Percentage < 70
then
'B'
else
case
when #Percentage < 80
then
'A'
else
case
when #Percentage <= 100
then
'A+'
else
'FAIL'
end
end
end
end
end
end
GO
EDIT: An aggregate without a group by returns null for an empty set. You could work around this with insull:
select #TMarks = IsNull(sum(Marks.TotalMarks),0)
from Marks
inner join TestRecord
on Marks.TestTypeId = TestRecord.TestTypeId
and Marks.SubjectId = TestRecord.SubjectId
where TestRecord.SessionId = #SessionId
and TestRecord.TestTypeId = #TestTypeId
and TestRecord.GRNo = #GRNo
and TestRecord.Marks <> 'A'
and cast(TestRecord.Marks as numeric) > Marks.PassingMarks

SQL Stored procedure if (#variable = 0) doesn't work

I've created a Stored procedure with some variables and a nested if statement.
When I call the Stored procedure from my program and check the returned dataset for the returned values, my dataset is empty while there should be records in it. After some testing I noticed when the statement if (#PoolID = 0) is tested and #PoolID is 0, it won't go trough the if statement... So whenever I set the variable poolid to 0 in my code I get the results from the else statement...
Anybody who knows what's going wrong?
Thx
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Pool_select]
#PartnerCode nvarchar(8),
#GebrID int,
#PoolID int,
#Bevoegdheid int
AS
IF (#PoolID = 0)
BEGIN
IF (#Bevoegdheid < 3)
BEGIN
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID
END
ELSE
BEGIN
SELECT *
FROM racpPool p
WHERE standaardpool = 1
and partnercode = #PartnerCode
END
END
ELSE
BEGIN
IF (#Bevoegdheid < 3)
BEGIN
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID and
p.PoolID = #PoolID
END
ELSE IF (#Bevoegdheid >= 3)
BEGIN
SELECT *
FROM racpPool p
WHERE PoolID = #PoolID
END
END
You could rewrite it as one single select of 4-part UNION ALL.
I also notice that your conditions are not comprehensive, not sure if that is intentional.
In the 2nd branch of #PoolID = 0 , the tests are specifically #Bevoegdheid < 3 and #Bevoegdheid >= 3 (instead of ELSE ) which will do nothing if #Bevoegdheid IS NULL
The optimizer will only run the branch that fits the criteria marked with <<<
ALTER PROCEDURE [dbo].[Pool_select]
#PartnerCode nvarchar(8),
#GebrID int,
#PoolID int,
#Bevoegdheid int
-- WITH RECOMPILE -- << may need this
AS
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID
AND #PoolID = 0 and #Bevoegdheid < 3 --- <<<
UNION ALL
SELECT *, NULL
FROM racpPool p
WHERE standaardpool = 1
and partnercode = #PartnerCode
AND #PoolID = 0 and IsNull(#Bevoegdheid,4) >= 3 --- <<<
UNION ALL
SELECT
p.*,
pr.poolrecht
FROM racpPool p, racpPoolrecht pr
WHERE
p.poolid = pr.poolid and
p.PartnerCode = #PartnerCode and
pr.poolrecht > 0 and
p.actief = 1 and
pr.GebrID = #GebrID and
p.PoolID = #PoolID
AND Isnull(#PoolID,-1) <> 0 AND #Bevoegdheid < 3 --- <<<
UNION ALL
SELECT *, NULL
FROM racpPool p
WHERE PoolID = #PoolID
AND Isnull(#PoolID,-1) <> 0 AND #Bevoegdheid >= 3 --- <<<