I tried to write a SQL query to get results with some parameters, but when I send parameters, it doesn't work. It always returns the last query in if else condition statement.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_RealEstatesList]
#TransCode NVARCHAR(5),
#CatUrl NVARCHAR(255) = NULL,
#ForSaleItem BIT = NULL,
#NewItem BIT = NULL,
#ItemOfDay BIT = NULL,
#Random BIT = NULL,
#Top INT = NULL
AS
SET NOCOUNT ON
SET XACT_ABORT ON
SET FMTONLY OFF
BEGIN TRAN
IF (OBJECT_ID('tempdb..#TempTable') IS NOT NULL)
BEGIN
DROP TABLE #TempTable
END
SELECT
R.[ID],
RT.[Title],
R.[Price],
R.[NewItem],
R.[ForSaleItem],
R.[ItemOfDay],
R.[Url],
(SELECT TOP 1 CC.Url
FROM [dbo].[Category] CC
JOIN [dbo].[LinkTypes] LLT ON LLT.[MainID] = CC.ID
JOIN [dbo].[Links] LL ON LL.[LinkTypeID] = LLT.[ID]
JOIN [dbo].[RealEstates] RR ON RR.[ID] = LL.LinkID
WHERE LLT.[LinkedTypeID] = 17
AND LLT.[MainTypeID] = 1
AND RR.ID = R.[ID]) AS 'CatUrl',
(SELECT TOP 1
(SELECT TOP 1 XC.Url
FROM Category XC
JOIN [dbo].[LinkTypes] LLT ON LLT.[MainID] = XC.ID
JOIN [dbo].[Links] LL ON LL.[LinkTypeID] = LLT.[ID]
WHERE LLT.[LinkedTypeID] = 1
AND LLT.[MainTypeID] = 1
AND LL.LinkID = CC.ID)
FROM [dbo].[Category] CC
JOIN [dbo].[LinkTypes] LLT ON LLT.[MainID] = CC.ID
JOIN [dbo].[Links] LL ON LL.[LinkTypeID] = LLT.[ID]
JOIN [dbo].[RealEstates] RR ON RR.[ID] = LL.LinkID
WHERE LLT.[LinkedTypeID] = 17
AND LLT.[MainTypeID] = 1
AND RR.ID = R.[ID]) AS 'PCatUrl'
INTO
#TempTable
FROM
[dbo].[RealEstates] R
JOIN
[dbo].[RealEstatesT] RT ON R.[ID] = RT.[RealEsID]
JOIN
[dbo].[LinkTypes] LT ON LT.[MainTypeID] = 17
JOIN
[dbo].[Links] L ON L.[LinkTypeID] = LT.[ID]
JOIN
[dbo].[Translation] TR ON TR.[ID] = RT.[TransID]
WHERE
R.[Active] = 1
AND R.[Deleted] = 0
AND RT.[Deleted] = 0
AND LT.[LinkedTypeID] = 5
AND LT.[MainID] = R.[ID]
AND TR.[ShortName] = #TransCode
GROUP BY
R.[ID], RT.[Title], R.[Price], R.[NewItem], R.[ForSaleItem], R.[ItemOfDay], R.[Url]
if (#Top = null or #Top = 0)
begin
set #Top = 100000;
end
if(#NewItem != null)
begin
select TOP (#Top) [ID],[Title],[Price],[NewItem],[ForSaleItem],[CatUrl],[PCatUrl],[ItemOfDay],[Url]
from #TempTable
where NewItem = #NewItem
order by case when #Random = 1 then NEWID() end
end
else if(#ForSaleItem != null)
begin
select TOP (#Top) [ID],[Title],[Price],[NewItem],[ForSaleItem],[CatUrl],[PCatUrl],[ItemOfDay],[Url]
from #TempTable
where ForSaleItem = #ForSaleItem
order by case when #Random = 1 then NEWID() end
end
else if(#CatUrl != null)
begin
select TOP (#Top) [ID],[Title],[Price],[NewItem],[ForSaleItem],[CatUrl],[PCatUrl],[ItemOfDay],[Url]
from #TempTable
where CatUrl = #CatUrl or PCatUrl = #CatUrl
order by case when #Random = 1 then NEWID() end
end
else if(#ItemOfDay != null)
begin
select TOP (#Top) [ID],[Title],[Price],[NewItem],[ForSaleItem],[CatUrl],[PCatUrl],[ItemOfDay],[Url]
from #TempTable
where ItemOfDay = #ItemOfDay
order by case when #Random = 1 then NEWID() end
end
else
begin
select TOP (#Top) [ID],[Title],[Price],[NewItem],[ForSaleItem],[CatUrl],[PCatUrl],[ItemOfDay],[Url]
from #TempTable
order by case when #Random = 1 then NEWID() end
end
COMMIT
Transcode and Random parameters work well but CatUrl, ForSaleItem, NewItem, ItemOfDay parameters does not work. It always returns the last query in if else condition statement.
Hope you can help. I'm waiting for your answers.
edit :
I changed all my null checks like "NULLIF(#Top, '') IS NULL" and now if statements works well.
Related
I want to simplify the below given procedure especially I want to remove most of the where clause filters such as IN and exists clauses.
For that, I have used a CTE and also declare a temp table and used it to get the select query that was talking long time since it was in where in clause. I would appreciate if you could show me some tricks in order to simplify this query.
ALTER PROCEDURE dbo.GetMappingBranchScenarios
#Mapping INT
#UserId INT= NULL
#BranchId INT = NULL
SELECT
BS.BranchId,
NULLIF( CC.Code, '' ) AS Code,
BS.BranchName,
BS.Active
FROM
Branch BS
LEFT OUTER JOIN
Code CC ON CC.BranchId = BS.BranchId
LEFT OUTER JOIN
BranchRule BRE ON BRE.MappingId = #Mapping
AND BRE.BranchId = BS.BranchId
WHERE
(BS.Active = 1
OR EXISTS (SELECT * FROM BranchRule BRE
WHERE BRE.BranchId = BS.BranchId
AND BRE.BranchId > 0
AND BRE.MappingId = #MappingId))
AND (#UserId IS NULL
OR BS.BranchId IN (SELECT BranchId
FROM branch2mapping.dbo.ListBranch(#UserId))
OR EXISTS (SELECT 1 FROM dbo.SecondaryMapping
WHERE Id = #UserId AND Admin = 1))
AND BS.BranchId = (CASE WHEN BranchId is NULL THEN BS.BranchID ELSE #BranchId END)
AND CC.Code = (CASE WHEN #Code IS NULL THEN CC.Code ELSE #Code END)
ORDER BY
CC.Code ASC
What I have done so far :
IF OBJECT_ID('tempdb..#Temp', 'U') IS NOT NULL
DROP TABLE #Temp
CREATE TABLE #Temp (BranchId INT)
SELECT BranchId
FROM branch2mapping.dbo.ListBranch(#UserId)
;WITH CTE AS
(
SELECT
BS.BranchId,
NULLIF(CC.Code, '' ) AS Code,
BS.BranchName, BS.Active
FROM
Branch BS
LEFT OUTER JOIN
Code CC ON CC.BranchId = BS.BranchId
LEFT OUTER JOIN
BranchRule BRE ON BRE.MappingId = #Mapping
AND BRE.BranchId = BS.BranchId
)
SELECT *
FROM CTE
WHERE
(CTE.Active = 1
OR EXISTS (SELECT * FROM BranchRule BRE
WHERE BRE.BranchId = CTE.BranchId
AND BRE.BranchId > 0
AND BRE.MappingId = #MappingId))
AND (#UserId IS NULL
OR BS.BranchId IN (SELECT * FROM #Temp)
OR EXISTS (SELECT 1 FROM dbo.SecondaryMapping
WHERE Id = #UserId AND Admin = 1)
)
AND BS.BranchId = (CASE WHEN BranchId is NULL THEN CTE.BranchID ELSE #BranchId END)
AND CTE.Code = (CASE WHEN #Code IS NULL THEN CTE.Code ELSE #Code END)
ORDER BY
CTE.Code ASC
Thank you for all your help.
Could you try if this is faster and still returning the same values with different filtering criteria?
ALTER PROCEDURE dbo.GetMappingBranchScenarios
#Mapping INT
#UserId INT= NULL
#BranchId INT = NULL
DECLARE #IsRuleExists BIT;
DECLARE #IsUrerADmin BIT;
IF EXISTS
(
SELECT 1
FROM Branch BS
INNER JOIN BranchRule BRE
ON BRE.BranchId = BS.BranchId
AND BRE.BranchId > 0
AND BRE.MappingId = #MappingId
)
BEGIN;
SET #IsRuleExists = 1;
END;
IF EXISTS
(
SELECT 1
FROM dbo.SecondaryMapping
WHERE Id = #UserId AND Admin = 1
) OR #UserId IS NULL
BEGIN;
SET #IsUrerADmin = 1;
END;
CREATE TABLE #Branches
(
[BranchId] INT
);
INSERT INTO #Branches ([BranchId])
SELECT BranchId
FROM branch2mapping.dbo.ListBranch(#UserId);
SELECT
BS.BranchId,
NULLIF( CC.Code, '' ) AS Code,
BS.BranchName,
BS.Active
FROM Branch BS
LEFT OUTER JOIN Code CC
ON CC.BranchId = BS.BranchId
WHERE
(
BS.Active = 1 OR #IsRuleExists = 1
)
AND
(
#IsUrerADmin = 1
OR
BS.BranchId IN (SELECT BranchId FROM #Branches)
)
AND BS.BranchId = (CASE WHEN BranchId is NULL THEN BS.BranchID ELSE #BranchId END)
AND CC.Code = (CASE WHEN #Code IS NULL THEN CC.Code ELSE #Code END)
ORDER BY CC.Code ASC;
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
How can I print an error message from this procedure if the employee (server) hasn't served anyone? Are try - catch blocks the only way to handle this?
I was thinking that if/else condition test followed by Print message suits my requirement.
Stored procedure:
if OBJECT_ID('customers_served', 'u') is not null
drop procedure customers_served;
go
create procedure customers_served
#employee_id int
as
set nocount on;
select
c.customer_id, c.cust_lastname,
(sum(c.cust_total_guests)) as total_guests
from
customers c
join
seating s on c.customer_id = s.customer_id
join
table_assignment ta on s.table_id = ta.table_id
join
employees e on ta.employee_id = e.employee_id
where
#employee_id = e.employee_id
group by
c.customer_id, c.cust_lastname;
/* if total_guests = 0 print message the employee has served 0 guests */
Test procedure:
exec customers_served
#employee_id = 5;
I modified your script to this.
use dbServers;
if OBJECT_ID('customers_served', 'u') is not null
drop procedure customers_served;
go
create procedure customers_served
#employee_id int
as
set nocount on;
declare #totalGuests int;
set #totalGuests = (
select(sum(c.cust_total_guests))
from customers c
join seating s on c.customer_id = s.customer_id
join table_assignment ta on s.table_id = ta.table_id
join employees e on ta.employee_id = e.employee_id
where #employee_id = e.employee_id
)
if #totalGuests = 0 OR #totalGuests IS NULL
BEGIN
print 'This server did not serve any guests'
END
else
BEGIN
select #totalGuests AS 'total_quests'
END
/* test procedure*/
exec customers_served
#employee_id = 5;
Following snippet of code might help:
declare #r int
select #r = (sum(c.cust_total_guests)) as total_guests
from customers c
join seating s on c.customer_id = s.customer_id
join table_assignment ta on s.table_id = ta.table_id
join employees e on ta.employee_id = e.employee_id
where #employee_id = e.employee_id
group by c.customer_id, c.cust_lastname;
if #r = 0
begin
-- do what ever you wish
end
else
begin
select c.customer_id, c.cust_lastname, (sum(c.cust_total_guests)) as
total_guests
from customers c
join seating s on c.customer_id = s.customer_id
join table_assignment ta on s.table_id = ta.table_id
join employees e on ta.employee_id = e.employee_id
where #employee_id = e.employee_id
group by c.customer_id, c.cust_lastname;
end
end
Rather than double querying, you can simply test ##ROWCOUNT after your query to determine if any results were returned, and print your message if ##ROWCOUNT = 0.
I want to show some data in a report by using a stored procedure:
ALTER PROCEDURE [dbo].[usp_GetThirtyDaysSims]
(
#DateFrom DATETIME = NULL,
#DateTo DATETIME = NULL,
#O2QuarterStartDate INT = NULL,
#AreaId INT = NULL,
#StoreId INT = NULL,
#O2MonthStartDate INT = NULL,
#TransactionType NVARCHAR(1000)
)
AS
BEGIN
DECLARE #O2Quarter AS INT
DECLARE #O2Year AS INT
DECLARE #O2Month AS INT
IF (#AreaId = 0 OR #AreaId = 999999999)
BEGIN
SET #AreaId = NULL
END
IF (#StoreId = 0 OR #StoreId = 999999999)
BEGIN
SET #StoreId = NULL
END
IF (#O2QuarterStartDate = 0 OR #O2QuarterStartDate = 999999999)
BEGIN
SET #O2QuarterStartDate = NULL
END
IF (#O2MonthStartDate = 0 OR #O2MonthStartDate = 999999999)
BEGIN
SET #O2MonthStartDate = NULL
END
IF(#O2QuarterStartDate IS NOT NULL)
BEGIN
SELECT #O2Quarter = O2Quarter,#O2Year = O2Year
FROM DimDate
WHERE DateKey=#O2QuarterStartDate
SELECT #DateFrom = MIN([Date]),#DateTo = MAX([Date])
FROM DimDate
WHERE O2Quarter=#O2Quarter AND O2Year=#O2Year
END
IF(#O2MonthStartDate IS NOT NULL)
BEGIN
PRINT #O2MonthStartDate
SELECT #O2Month=O2Month, #O2Quarter = O2Quarter,#O2Year = O2Year
FROM DimDate
WHERE DateKey=#O2MonthStartDate
SELECT #DateFrom = MIN([Date]),#DateTo = MAX([Date])
FROM DimDate
WHERE O2Month=#O2Month AND O2Quarter=#O2Quarter AND O2Year=#O2Year
END
SELECT Area,StoreName,SUM(Tariff) SumOfTariff, COUNT(1) NoOfSimsSold
FROM [dbo].[ufn_GetThirtyDaysSimsData](#DateFrom,#DateTo) FT
INNER JOIN DimDate DD ON FT.TransactionDateId = DD.DateKey
WHERE (#DateFrom IS NOT NULL AND DD.[Date] >= #DateFrom)
AND (#DateTo IS NOT NULL AND DD.[Date] <= #DateTo)
AND (FT.AreaId = #AreaId OR #AreaId IS NULL)
AND (FT.StoreId = #StoreId OR #StoreId IS NULL)
AND (FT.TransactionType = #TransactionType OR #TransactionType IS NULL)
GROUP BY Area,StoreName
ORDER BY Area,StoreName
END
When I filter by using the 7 filters above, data is not showing on the report but there are no errors either - why might this be?
Make sure your function is table-based. You don't need to add the date parameters in the WHERE clause because you are already passing those in the function. Test your query by running it first in SSMS.
Here is a simplified version of the query:
SELECT Area, StoreName, SUM(Tariff) SumOfTariff, COUNT(1) NoOfSimsSold
FROM [dbo].[ufn_GetThirtyDaysSimsData](#DateFrom,#DateTo) FT
INNER JOIN DimDate DD ON FT.TransactionDateId = DD.DateKey
WHERE FT.AreaId = #AreaId
AND FT.StoreId = #StoreId
AND FT.TransactionType = #TransactionType
GROUP BY Area, StoreName
ORDER BY Area, StoreName
what is the problem with the #temp variable?
create function dbo.getNumOfReviews2 (#email varchar(40))
returns int
as begin
declare #numOfReviews int
select #numOfReviews = count(*)
from dbo.Reviews
where email = #email
group by Email
return #numOfReviews
end
CREATE TRIGGER setDiscount
ON dbo.[Contains]
FOR INSERT
AS
DECLARE #OrderID int
DECLARE #ProductID int
DECLARE #Size VarChar(15)
DECLARE #temp int
IF CURSOR_STATUS('global','C_CURSOR')>=-1
BEGIN
DEALLOCATE C_CURSOR
END
DECLARE C_CURSOR CURSOR
FOR SELECT ProductID,OrderID,Size
FROM INSERTED
BEGIN
OPEN C_CURSOR
FETCH NEXT FROM C_CURSOR INTO #ProductID,#OrderID,#Size
WHILE (##FETCH_STATUS=0)
BEGIN
#temp = dbo.getNumOfReviews2(select BillingEmail from dbo.Orders where OrderID=#OrderID)
IF (SELECT COUNT(*)
FROM dbo.[Contains]
WHERE OrderID = #OrderID) > 5 or (SELECT sum(Quantity) FROM dbo.[Contains] WHERE OrderID=#OrderID) > 10 or
( #temp )> 5
UPDATE [Contains]
SET [Savings%] = [Savings%] + 0.05
WHERE OrderID = #OrderID and ProductID = #ProductID and Size = #Size
FETCH NEXT FROM C_CURSOR INTO #ProductID,#OrderID,#Size
END
END
Use select to call scalar function
correct way to do this would be
select #temp = dbo.getNumOfReviews2(BillingEmail)
from dbo.Orders
where OrderID=#OrderID
Note: It is not advisable to write big logic inside a trigger. Triggers should be simple and fast otherwise your DML operations will be slow. Moreover you have used a CURSOR which should be avoided at any cost. Rewrite the code using SET based approach.
Here is a SET based approach code
;WITH cte
AS (SELECT c1.orderid
FROM dbo.[contains] c1
INNER JOIN inserted i1
ON i1.orderid = c1.orderid
GROUP BY orderid
HAVING Count(*) > 5
OR Sum(quantity) > 5
OR #temp > 5)
UPDATE C
SET [savings%] = [savings%] + 0.05
FROM [contains] C
INNER JOIN inserted I
ON I.orderid = C.orderid
AND I.productid = C.productid
AND I.size = C.size
AND EXISTS (SELECT 1
FROM cte c1
WHERE c1.orderid = c.orderid)
CREATE OR REPLACE COVID19VMS_VACCINESHOT_T1
BEFORE INSERT OR UPDATE ON VACCINENEXTSHOTDATE
FOR EACH ROW
BEGIN
IF :NEW.VACCINESHOTDATE := 1
:NEW.VACCINEXTSHOTDATE := to_date(VACCINESHOTDATE +28)
END IF;
IF :NEW.VACCINESHOTDATE :=2
:NEW.VACCINENEXTSHOTDATE IS NULL
END IF
END