Stored Procedure "spins" when executed from Visual Studio 2012 - sql-server

I have written 3 stored procedures and all run fine when executed in SQL Server. However, when I execute them in Visual Studio 2012 they just "spin", creating locks, etc. Any ideas?
Here is one of them. Another one is selecting values from an inline view based on the same SQL and not inserting into #temp
#StartDate As DateTime,
#EndDate As DateTime,
#EmployeeCode As VarChar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
select * into #temp
from
(SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e (nolock)
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec1 (nolock)
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec2 (nolock)
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_Live.dbo.OrganizationUnit ou (nolock)
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_Live.dbo.EmployeePremiumBucket epb (nolock)
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_Live.dbo.PayCode pc (nolock)
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_Live.dbo.PayGroupInstance pgi (nolock)
ON pgi.ID = epb.PayGroupInstanceID
WHERE
ec1.transactiondate between #StartDate and #EndDate
and epb.PaymentClassification = '1'
AND e.code = #EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue
UNION
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e (nolock)
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec1 (nolock)
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec2 (nolock)
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_History_Live.dbo.OrganizationUnit ou (nolock)
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_History_Live.dbo.EmployeePremiumBucket epb (nolock)
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_History_Live.dbo.PayCode pc (nolock)
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_History_Live.dbo.PayGroupInstance pgi (nolock)
ON pgi.ID = epb.PayGroupInstanceID
WHERE
ec1.transactiondate between #StartDate and #EndDate
and epb.PaymentClassification = '1'
AND e.code = #EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
AND ou.ArchiveTaskID =
(
SELECT MAX(ou2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.OrganizationUnit ou2 (NOLOCK)
WHERE ou2.ID = ou.ID
)
AND pc.ArchiveTaskID =
(
SELECT MAX(pc2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.PayCode pc2 (NOLOCK)
WHERE pc2.ID = pc.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue) as X
select EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code,
sum(hourvalue) as Hours
from #temp
group by EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
CODE
Order by CLOCK_OUT
END
Here is the other one.
#StartDate As DateTime,
#EndDate As DateTime,
#EmployeeCode As VarChar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
select EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code,
sum(hourvalue) as Hours
from
(
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec1
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec2
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_Live.dbo.OrganizationUnit ou
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_Live.dbo.EmployeePremiumBucket epb
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_Live.dbo.PayCode pc
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_Live.dbo.PayGroupInstance pgi
ON pgi.ID = epb.PayGroupInstanceID
WHERE ec1.transactiondate between #StartDate and #EndDate
and epb.PaymentClassification = '1'
AND e.code = #EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue
UNION
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec1
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec2
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_History_Live.dbo.OrganizationUnit ou
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_History_Live.dbo.EmployeePremiumBucket epb
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_History_Live.dbo.PayCode pc
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_History_Live.dbo.PayGroupInstance pgi
ON pgi.ID = epb.PayGroupInstanceID
WHERE ec1.transactiondate between #StartDate and #EndDate
and epb.PaymentClassification = '1'
AND e.code = #EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
AND ou.ArchiveTaskID =
(
SELECT MAX(ou2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.OrganizationUnit ou2 (NOLOCK)
WHERE ou2.ID = ou.ID
)
AND pc.ArchiveTaskID =
(
SELECT MAX(pc2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.PayCode pc2 (NOLOCK)
WHERE pc2.ID = pc.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue) as X
group by
EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code
order by date_of_shift, code
END

They are different execution environments. And yes, read Sommarskog's article already recommended. But I think main reason why these procedures will be slow (and not consistently) is the UNION operator. You should use UNION ALL.
Second, get rid of these (nolock) hints. They don't help you. If you really need that, you should use
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
at the beginning of your procedure. It does the same.

Related

how do i use a temporary date table combine with three other Tables to extract all customer info using T-SQL

i want to Write a query using the temporary date table to show rows for every customer for every month since the month they first purchased from us. The table should detail the customer ID, customer name, month, Date of first Purchase, Units Purchased that month, Value Purchased that month, Cumulative Units Purchased, Cumulative Value Purchased and the Days since last purchase and the last day of the month.
i've tried this code
select c.Id AS CustomerId
,c.FirstName+' '+c.LastName as CustomerName
,DATENAME(MM,d.OrderDate) AS MonthofFirstPurchase
--,sum(d.TotalAmount) AS CummulativeValue
,d.OrderDate AS DateOfFirstPurchase
,Datediff(dd,o.OrderDate,getdate()) as DateSinceLastPurchase
from[dbo].[Customer]c inner join [dbo].[Order] b on b.CustomerId = c.Id
join (select max(Id) as OrderId, min(Id) as minOrder,[CustomerId] from [dbo].[Order] group by [CustomerId])conn on c.Id = conn.[CustomerId]
join [dbo].[Order]o on o.[Id] = conn.OrderId
join [dbo].[Order]d on d.[Id] = conn.minOrder
--join [dbo].[OrderItem]b on = conn.OrderId
but i keep getting errors i am a beginner at this
Please note that I did not execute the query.
If you do not want that column please try the below query. I did not execute the query though
;WITH CTE_Temp
AS
(
SELECT max(Id) AS OrderId
, min(Id) AS minOrder
, [CustomerId]
FROM [dbo].[Order]
GROUP BY [CustomerId]
)
SELECT c.Id AS CustomerId
, c.FirstName + ' ' + c.LastName AS CustomerName
, DATENAME(MM, d.OrderDate) AS MonthofFirstPurchase
--,sum(d.TotalAmount) AS CummulativeValue
, d.OrderDate AS DateOfFirstPurchase
, Datediff(dd, o.OrderDate, getdate()) AS DateSinceLastPurchase
FROM [dbo].[Customer] c
INNER JOIN [dbo].[Order] b ON b.CustomerId = c.Id
INNER JOIN CTE_Temp conn ON c.Id = conn.[CustomerId]
INNER JOIN [dbo].[Order] o ON o.[Id] = conn.OrderId
INNER JOIN [dbo].[Order] d ON d.[Id] = conn.minOrder
If you need the sum(d.TotalAmount) AS CummulativeValue. Just try the query
;WITH CTE_Temp
AS
(
SELECT max(Id) AS OrderId
, min(Id) AS minOrder
, [CustomerId]
FROM [dbo].[Order]
GROUP BY [CustomerId]
),
CTE_TEMP1
AS
(
SELECT CTE_Temp.[CustomerId], sum(d.TotalAmount) TotalAmount AS CummulativeValue
FROM [dbo].[Order] d INNER JOIN CTE_Temp ON d.[Id] = CTE_Temp.minOrder
GROUP BY CTE_TEMP.[CustomerId]
)
SELECT c.Id AS CustomerId
, c.FirstName + ' ' + c.LastName AS CustomerName
, DATENAME(MM, d.OrderDate) AS MonthofFirstPurchase
,CTE_TEMP1.TotalAmount AS CummulativeValue
, d.OrderDate AS DateOfFirstPurchase
, Datediff(dd, o.OrderDate, getdate()) AS DateSinceLastPurchase
FROM [dbo].[Customer] c
INNER JOIN [dbo].[Order] b ON b.CustomerId = c.Id
INNER JOIN CTE_Temp conn ON c.Id = conn.[CustomerId]
INNER JOIN [dbo].[Order] o ON o.[Id] = conn.OrderId
INNER JOIN CTE_TEMP1 d ON d.CustomerId = c.id
I have modified the anser provided by Gopakumar and i came to the solution of the problem. The code below works perfectly well for its purpose
;WITH CTE_Temp
AS
(
SELECT max(Id) AS MaxOrder
, min(Id) AS MinOrder
, [CustomerId]
FROM [dbo].[Order]
GROUP BY [CustomerId]
),
CTE_TEMP1 AS(SELECT CTE_TEMP.CustomerId,sum([UnitQuantity]) AS UnitsPurchasedForMonth,sum(TotalAmount) AS ValueForMonth
from [dbo].[OrderItem]p left outer join [dbo].[Order] e on p.Id = e.Id
INNER JOIN CTE_Temp ON e.[Id] = CTE_Temp.minOrder GROUP BY CTE_TEMP.CustomerId),
CTE_TEMP2 AS(SELECT e.CustomerId,sum([UnitQuantity]) AS CummulativeUnitsPurchased,sum(TotalAmount) AS CummulativeValue
from [dbo].[OrderItem]p inner join [dbo].[Order] e on p.Id = e.Id group by e.CustomerId)
SELECT c.Id AS CustomerId
, c.FirstName + ' ' + c.LastName AS CustomerName
, DATENAME(MM, o.OrderDate) AS MonthofFirstPurchase
, o.OrderDate AS DateOfFirstPurchase
,d.ValueForMonth AS ValuePurchasedForMonth
,d.UnitsPurchasedForMonth
,e.CummulativeUnitsPurchased
,e.CummulativeValue
, Datediff(dd, a.OrderDate, getdate()) AS DateSinceLastPurchase
,EOMONTH(o.OrderDate) AS LastDayOfMonth
FROM [dbo].[Customer] c
INNER JOIN CTE_Temp conn ON c.Id = conn.CustomerId
INNER JOIN [dbo].[Order] o ON o.[Id] = conn.MinOrder
INNER JOIN CTE_TEMP1 d ON d.CustomerId = c.id
INNER JOIN [dbo].[Order] a on a.Id = conn.MaxOrder
inner join CTE_TEMP2 e on c.Id = e.CustomerId
you can edit as you like to get your results

SQL request. How to make it work faster?

I have sql request which take to much time to execute, any suggestions to make it faster?
DECLARE #Today DATETIME;
DECLARE #TwoWeeksAgo
DATETIME; SET #Today = GETDATE();
SET #TwoWeeksAgo = DATEADD(DAY, -14, GETDATE());
SELECT TOP ${selectSalesByMall} s.title, s.imageUrl, count(sv.saleid) as mostViewPeriod14Days, s.guid, br.title as brand, s.id as saleId, stm.mallId
FROM dbo.Sales s
INNER JOIN dbo.KEY_BrandcategoryToSale b_key ON s.id = b_key.saleId
INNER JOIN dbo.Brands br ON s.BrandId = br.Id
INNER JOIN dbo.SaleView sv ON s.id = sv.saleId
INNER JOIN dbo.SalesToMall stm ON s.id = stm.saleId
LEFT JOIN dbo.SaleView sv2 on sv2.id = sv.id and sv2.userId = ${user['userID']}
WHERE sv.Date
BETWEEN #TwoWeeksAgo
AND #Today
AND sv2.id IS NULL
AND s.isActive = 1
AND stm.mallId = ${user['mallId']}
AND br.id != ${user['favBrand']['brandId']}
AND s.id NOT IN (SELECT uess.saleID FROM dbo.UsersEmailsSalesSent uess WHERE uess.userID = ${user['userID']})
GROUP BY s.title, s.imageUrl, s.guid, br.title, s.id, stm.mallId
ORDER BY mostViewPeriod14Days DESC
one improvement could be changing the "not in" to "not exists":
DECLARE #Today DATETIME;
DECLARE #TwoWeeksAgo
DATETIME; SET #Today = GETDATE();
SET #TwoWeeksAgo = DATEADD(DAY, -14, GETDATE());
SELECT TOP ${selectSalesByMall} s.title, s.imageUrl, count(sv.saleid) as mostViewPeriod14Days, s.guid, br.title as brand, s.id as saleId, stm.mallId
FROM dbo.Sales s
INNER JOIN dbo.KEY_BrandcategoryToSale b_key ON s.id = b_key.saleId
INNER JOIN dbo.Brands br ON s.BrandId = br.Id
INNER JOIN dbo.SaleView sv ON s.id = sv.saleId
INNER JOIN dbo.SalesToMall stm ON s.id = stm.saleId
LEFT JOIN dbo.SaleView sv2 on sv2.id = sv.id and sv2.userId = ${user['userID']}
WHERE sv.Date
BETWEEN #TwoWeeksAgo
AND #Today
AND sv2.id IS NULL
AND s.isActive = 1
AND stm.mallId = ${user['mallId']}
AND br.id != ${user['favBrand']['brandId']}
AND
NOT EXISTS (SELECT uess.saleID FROM dbo.UsersEmailsSalesSent uess WHERE uess.userID = ${user['userID']} and s.id=uess.saleID)
GROUP BY s.title, s.imageUrl, s.guid, br.title, s.id, stm.mallId
ORDER BY mostViewPeriod14Days DESC

Create a view in SQL Server 2014 that combines three queries each with a different where statements

I am trying to create one output using a view that would combine the quotes from Query 2 with the quotes from Query 1 and the policies from Query 3 with the policies from Query 1. Query 1 is my main query ... 2 and 3 would be left joined.
Query 1:
SELECT
A.AgencyId,
SUM(A.Quotes) AS Quotes,
SUM(A.NB) AS Policies,
CONVERT(DATE, A.Date) AS Date,
C.WeekEndDate
FROM
dbo.Agent_Qts_Daily A
INNER JOIN
dbo.AgentList B ON A.AgencyID = B.AgencyID
LEFT JOIN
dbo.WE_DATES C ON A.Date = C.Date
WHERE
Year = '2016'
GROUP BY
A.AgencyID, A.Date, C.WeekEndDate
Query 2:
SELECT
B.AgencyID,
SUM(A.Quote_Cnt) AS Quotes,
CONVERT(DATE, A.DateRecd) AS Date,
C.WeekEndDate
FROM
dbo.TestData A
INNER JOIN
dbo.AgentList B ON A.AgtID = B.AGTID
LEFT JOIN
dbo.WE_DATES C ON A.DateRecd = C.Date
WHERE
A.FirmGroup <> 'ABC'
AND A.Source = 'DEF'
AND C.Year = '2016'
GROUP BY
B.AgencyID, A.DateRecd, C.WeekEndDate
Query 3:
SELECT
B.AgencyID,
SUM(A.sold_Cnt) AS Policies,
CONVERT(DATE, A.DateBound) AS Date,
C.WeekEndDate
FROM
dbo.TestData A
INNER JOIN
dbo.AgentList B ON A.AgtID = B.AGTID
LEFT JOIN
dbo.WE_DATES C ON A.DateBound = C.Date
WHERE
A.FirmGroup <> 'ABC'
AND A.sold_Cnt = '1'
AND A.Source = 'DEF'
AND C.Year = '2016'
GROUP BY
B.AgencyID, A.DateBound, C.WeekEndDate
You can do something like this or you can also use an sp to meet the same criteria
CREATE VIEW ViewName
AS
SELECT
A.AgencyId,
SUM(A.Quotes) AS Quotes,
SUM(A.NB) AS Policies,
CONVERT(DATE, A.Date) AS Date,
C.WeekEndDate
FROM
dbo.Agent_Qts_Daily A
INNER JOIN dbo.AgentList B ON A.AgencyID = B.AgencyID
LEFT JOIN dbo.WE_DATES C ON A.Date = C.Date
WHERE Year = '2016'
GROUP BY
A.AgencyID,
A.Date,
C.WeekEndDate
UNION ALL
SELECT
B.AgencyID,
SUM(A.Quote_Cnt) AS Quotes,
0 AS Policies,
CONVERT(DATE, A.DateRecd) AS Date,
C.WeekEndDate
FROM
dbo.TestData A
INNER JOIN dbo.AgentList B ON A.AgtID = B.AGTID
LEFT JOIN dbo.WE_DATES C ON A.DateRecd = C.Date
WHERE
A.FirmGroup <> 'ABC'
AND A.Source = 'DEF'
AND C.Year = '2016'
GROUP BY
B.AgencyID,
A.DateRecd,
C.WeekEndDate
UNION ALL
SELECT
B.AgencyID,
0 AS Quotes,
SUM(A.sold_Cnt) AS Policies,
CONVERT(DATE, A.DateBound) AS Date,
C.WeekEndDate
FROM
dbo.TestData A
INNER JOIN dbo.AgentList B ON A.AgtID = B.AGTID
LEFT JOIN dbo.WE_DATES C ON A.DateBound = C.Date
WHERE
A.FirmGroup <> 'ABC'
AND A.sold_Cnt = '1'
AND A.Source = 'DEF'
AND C.Year = '2016'
GROUP BY
B.AgencyID,
A.DateBound,
C.WeekEndDate

Stored procedure taking long time when it runs through SSIS package

I have a below procedure which uses 3 temp tables and finally insert into a table. I am using below sp as source (execute sql task) and loading into csv files. When i run this sp from SSMS it runs within 10 seconds, but when I Put into SSIS package it runs for 30 mins and keep on running. Could any of you optimize this SP for SSIS package?
create proc [etl].[payment_report]
#start_date datetime,
#end_date datetime
as
begin
truncate table extract.payment
select
a.bb_acct_id, a.customer_id,
pay.order_id Payment_Order_Id,
aoi.ord_prod_id Ord_Prod_Id,
pd.name, pd.quick_cd
into
#IntialOrders
from
(select *
from stg.payment (NOLOCK)
where order_id is not null) pay
inner join
stg.account a (NOLOCK) on pay.acct_id = a.acct_id
inner join
stg.acct_order ao (NOLOCK) on ao.order_id = pay.order_id
inner join
stg.acct_order_item aoi (NOLOCK) on aoi.order_id = ao.order_id
inner join
stg.ordered_product op (NOLOCK) on op.ord_prod_id = aoi.ord_prod_id
left join
stg.product p (NOLOCK) on p.prod_id = op.prod_id
left join
stg.product_def pd (NOLOCK) on pd.prod_def_id = p.prod_def_id
where
pay.received_date >= #start_date
and pay.received_date < #end_date
and pay.payment_id not in (select payment_id
from stg.op_renewal_history)
create clustered index Idx_Payment_Order_Id on #IntialOrders(Payment_Order_Id)
select
pay.payment_id, gwr.response
into
#gateway_response
from
stg.payment pay (NOLOCK)
inner join
stg.cc_transactions cct (NOLOCK) on cct.payment_id = pay.payment_id
inner join
stg.gateway_response gwr (NOLOCK) on cct.c_c_trans_id = gwr.cc_trans_id
where
pay.posting_status_id = 3
and pay.received_date >= #start_date
and pay.received_date < #end_date
and pay.received_date > '2015-04-15 00:00:00'
select
distinct a.bb_acct_id SP_ACCOUNT_ID
,a.customer_id CP_CUSTOMER_ID
,bu.description BUSINESS_UNIT
,pay.payment_id PAYMENT_ID
,pay.payment_amt AMOUNT
,'SEK' CURRENCY
,Substring(convert(char(19),pay.received_date,126), 1, (len(convert(char(19),pay.received_date,126))-0))+'Z' PAYMENT_DATE
,pt.display_name PAYMENT_METHOD
,post.description PAYMENT_STATUS
,pay.retries PAYMENT_RETRIES
,case when (pay.for_bill_id is not null or orh.op_id is not null) then 'Renewal' else 'OneTime' end as PAYMENT_TYPE
,case when pay.posting_status_id =3 then gwr.response else '' end as FAILURE_REASON
,case when op.ord_prod_id is null then ino.name else pd.name end SUBSCRIPTION_NAME
,case when op.ord_prod_id is null then ino.quick_cd else pd.quick_cd end SKU
,case when op.ord_prod_id is null then ino.Ord_Prod_Id else op.ord_prod_id end ORD_PROD_ID
,convert(char(19),GETDATE(),126)+'Z' EXPORT_TIME
,case when (pay.posting_status_id =3 and pay.retries = 3 ) then 'T' else 'F' end FAILED_EXTENDED_RETRY
into #payment
from stg.payment pay (NOLOCK)
left join #IntialOrders ino (NOLOCK) on
ino.Payment_Order_Id=pay.order_id
left join stg.account a (NOLOCK) on
a.acct_id = pay.acct_id
left join stg.business_unit bu (NOLOCK) on
a.bu_id=bu.bu_id
left join stg.payment_method pm (NOLOCK) on
pm.pay_method_id=pay.payment_method_id
left join stg.payment_type pt (NOLOCK) on
pt.id=pm.type_id
left join stg.posting_status post (NOLOCK) on
post.id=pay.posting_status_id
left join stg.op_renewal_history orh (NOLOCK) on
orh.payment_id = pay.payment_id
left join stg.ordered_product op (NOLOCK) on
op.ord_prod_id = orh.op_id
left join stg.product p (NOLOCK) on
p.prod_id = op.prod_id
left join stg.product_def pd (NOLOCK) on
pd.prod_def_id = p.prod_def_id
left join #gateway_reponse gwr (NOLOCK) on
gwr.payment_id = pay.payment_id
where
a.bu_id=1
and (a.acct_role_id is null or a.acct_role_id !=4)
and (pay.posting_status_id=2 or (pay.posting_status_id =3
and pay.retries = 3
and op.acct_status_id=3))
and pay.received_date >=#start_date
and pay.received_date < #end_date
and pay.received_date > '2015-04-15 00:00:00'
insert into extract.payment
(
SP_ACCOUNT_ID
,CP_CUSTOMER_ID
,BUSINESS_UNIT
,PAYMENT_ID
,AMOUNT
,CURRENCY
,PAYMENT_DATE
,PAYMENT_METHOD
,PAYMENT_STATUS
,PAYMENT_RETRIES
,PAYMENT_TYPE
,FAILURE_REASON
,SUBSCRIPTION_NAME
,SKU,ORD_PROD_ID
,EXPORT_TIME
,FAILED_EXTENDED_RETRY
)
select
cast(p.SP_ACCOUNT_ID as varchar(50)) SP_ACCOUNT_ID
,cast(p.CP_CUSTOMER_ID as varchar(50)) CP_CUSTOMER_ID
,cast(p.BUSINESS_UNIT as varchar(500)) BUSINESS_UNIT
,cast( p.PAYMENT_ID as varchar(50)) PAYMENT_ID, p.AMOUNT
,cast( p.CURRENCY as varchar(50)) CURRENCY
,cast( p.PAYMENT_DATE as varchar(50)) PAYMENT_DATE
,cast( p.PAYMENT_METHOD as varchar(50)) PAYMENT_METHOD
,cast(p.PAYMENT_STATUS as varchar(50)) PAYMENT_STATUS
,cast( p.PAYMENT_RETRIES as varchar(50)) PAYMENT_RETRIES
,cast(p.PAYMENT_TYPE as varchar(50)) PAYMENT_TYPE
,cast( p.FAILURE_REASON as varchar(4000)) FAILURE_REASON
,cast(p.SUBSCRIPTION_NAME as varchar(500)) SUBSCRIPTION_NAME
,cast(p.SKU as varchar(50)) SKU
,cast(p.ORD_PROD_ID as varchar(50)) ORD_PROD_ID
,cast( p.EXPORT_TIME as varchar(50)) EXPORT_TIME
,p.FAILED_EXTENDED_RETRY
from #payment p
order by p.PAYMENT_DATE
Drop table #IntialOrders
Drop table #gateway_reponse
Drop table #payment
END

SQL Select within Sub Query

Hi My query is as follows, and contains a subquery within it:
ALTER PROCEDURE [dbo].[POBalance] #PONumber NVARCHAR(50)
AS
BEGIN
SELECT CASE
WHEN X.STATUS = 'False'
THEN ( SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,CASE
WHEN A.partialflag = 'false'
THEN '0'
ELSE A.qty
END AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber
)
ELSE ( SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,C.qty AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber)
END
FROM tblPOHeader AS X
WHERE x.PONo = #PONumber
END
The error i get is :
Only one expression can be specified in the select list when the subquery is not
introduced with EXISTS.
What is wrong with my query..it seems my sub query is OK.
THanks in Advance
You can not select table in case clausule. You can do it just like that (I didn't test it):
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,CASE
WHEN A.partialflag = 'false'
THEN '0'
ELSE A.qty
END AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
INNER JOIN tblPOHeader X ON x.PONo = A.PONo
WHERE A.PONo = #PONumber and X.STATUS = 'False'
UNION ALL
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,C.qty AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
INNER JOIN tblPOHeader X ON x.PONo = A.PONo
WHERE A.PONo = #PONumber and X.STATUS <> 'False'
But I think tah X.STATUS is bit - if yes you should do it just like that:
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,CASE
WHEN A.partialflag = 'false'
THEN '0'
ELSE A.qty
END AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
INNER JOIN tblPOHeader X ON x.PONo = A.PONo
WHERE A.PONo = #PONumber and X.STATUS = 0
UNION ALL
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,C.qty AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
INNER JOIN tblPOHeader X ON x.PONo = A.PONo
WHERE A.PONo = #PONumber and X.STATUS <> 0
Are you actually looking for this?
ALTER PROCEDURE [dbo].[POBalance] #PONumber NVARCHAR(50)
AS
BEGIN
DECLARE #Status NVARCHAR(MAX)
SELECT #Status = X.STATUS
FROM tblPOHeader AS X WHEREx.PONo = #PONumber
IF #Status = 'False'
BEGIN
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,CASE
WHEN A.partialflag = 'false'
THEN '0'
ELSE A.qty
END AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber
END
ELSE
BEGIN
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,C.qty AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber
END
END
This code will store and then check the value of #Status and based on if the value is False or not then it will return the result set of one of the queries.
You cannot select multiple fields for one expression.Your alias makes it more visible.You select more than one value and give only one alias name!!
Please refer this
Only One Expression in case
And this one too
Another one here
When
select * from tblPOHeader where PONo = #PONumber
returns only one row you can do something like that
declare #STATUS nvarchar(200) = ( select STATUS from tblPOHeader where PONo = #PONumber)
if #STATUS = 'False'
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,CASE
WHEN A.partialflag = 'false'
THEN '0'
ELSE A.qty
END AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber
ELSE
SELECT A.Description
,C.qty AS POqty
,B.Qty AS PDQty
,C.qty AS Balance
,A.Unit
,A.Unitprice
,A.Partialflag
FROM tblPOdetails AS A
INNER JOIN tblPDdetails AS B ON A.id = B.id
INNER JOIN tblpodetailshistory AS C ON A.id = C.id
WHERE A.PONo = #PONumber

Resources