From Procedure to View - sql

Code below works perfect as procedure.
How can I transform or change the same code below so that it can work in View or as View code or View?
Can I drop View?
ALTER proc [dbo].[NewOne_1]
as
begin
set nocount on
if object_ID('TEMPDB..#TableA') <> ''
drop table # TableA
select
*
into # TableA
from vd_View po
if object_ID('TEMPDB..#FirstSDate') is not null
drop table #FirstSDate
select
Pt_id = Pat_Id,
Date_of_First_Shipment = min(DeliveryDate)
into #FSDate
from # TableA po
group by Pat_Id
if object_ID('TEMPDB..#LastSDate') is not null
drop table #LastShipDate
select
Pt_id = Pat_Id,
Date_of_Last_Shipment = max(DeliveryDate)
into #LastShipDate
from # TableA po
group by Pat_Id
SELECT PtData.Pat_No Progress_Pat_ID
,C_S = case when dbo.fn_GetBusinessDays(firstship.Date_of_First_Shipment,LastShip.Date_of_Last_Shipment) > 80 then 'Yes'
when dbo.fn_GetBusinessDays(firstship.Date_of_First_Shipment,LastShip.Date_of_Last_Shipment) <= 80 then 'No'
else ''
end
,P_Last_Name = PtData.P_LName
,PtData.DReg Reg
FROM dbo.tbld_PatSum PtData
inner join vd_PSum ps
on PtData.P = ps.P_ID
inner join S_M.dbo.Pat__c ps1
on PtData.Pt_ID = ps1.Id
left join #FirstShipDate firstship
on PtData.Pt_ID = firstship.Pt_Id
left join #LastShipDate LastShip
on PtData.Pt_ID = LastShip.Pt_Id
WHERE PtData.Pat_No IS NOT NULL
AND PtData.ActiveStatus<>'Gen Info'
set nocount off
end

I'm guessing that you're wanting to be able to use this to join with something else. You cannot put this into a view. However you may be able to put this in a table-valued function which would allow you to accomplish what I think you're after.

--just took your code (it's quite messy), the dbo.fn_GetBusinessDays function must be deterministic in order to work in a view
create view test as
SELECT
PtData.Pat_No Progress_Pat_ID
,C_S = case when dbo.fn_GetBusinessDays(firstship.Date_of_First_Shipment,LastShip.Date_of_Last_Shipment) > 80 then 'Yes'
when dbo.fn_GetBusinessDays(firstship.Date_of_First_Shipment,LastShip.Date_of_Last_Shipment) <= 80 then 'No'
else ''
end
,P_Last_Name = PtData.P_LName
,PtData.DReg Reg
FROM dbo.tbld_PatSum PtData
inner join vd_PSum ps
on PtData.P = ps.P_ID
inner join S_M.dbo.Pat__c ps1
on PtData.Pt_ID = ps1.Id
left join (
select
Pt_id = Pat_Id,
Date_of_First_Shipment = min(DeliveryDate)
from vd_View po
group by Pat_Id ) firstship
on PtData.Pt_ID = firstship.Pt_Id
left join (select
Pt_id = Pat_Id,
Date_of_Last_Shipment = max(DeliveryDate)
from vd_View po
group by Pat_Id ) LastShip
on PtData.Pt_ID = LastShip.Pt_Id
WHERE PtData.Pat_No IS NOT NULL
AND PtData.ActiveStatus<>'Gen Info'

Related

Returning values from different rows in a stored procedure as different values

I have a stored procedure:
`SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [ebs].[DB_Task_ONEYCRPRaport]
--#startDate DATE,
--#endDate DATE
AS
BEGIN
SELECT DISTINCT
CAST(A.ExternalMerchantId as varchar) "Merchant_guid", -- ok
CAST(C.CreatedOn AS DATE) "Purchase_date", --ok
CAST(C.CreatedOn AS TIME) "Purchase_hour", --ok
C.ContractNo "Funding_reference",--ok
APP.OrderNo "External_reference", --ok
A.CustomerInternalId "Customer_external_code",--ok
CASE WHEN I.TotalAmountToPay = 0 THEN '-' ELSE '+' END "Total_amount_symbol",--ok
CASE WHEN I.TotalAmountToPay = 0 THEN I.TotalAmountToRecover ELSE I.TotalAmountToPay END "Total_amount"
from ebs.Account as A
JOIN ebs.FTOS_CB_Contract AS C ON A.Accountid = C.CustomerId
JOIN ebs.FTOS_CB_BankAccount AS BA ON BA.FTOS_CB_BankAccountid = C.MainBankAccountId
JOIN ebs.FTOS_CB_BankAccountOperation AS BAO ON BAO.BankAccountId = BA.FTOS_CB_BankAccountid
JOIN Ebs.FTOS_CMB_Currency AS CU ON CU.FTOS_CMB_Currencyid = C.CurrencyId
JOIN ebs.FTOS_TPM_Invoice AS I ON I.BankAccountId = BA.FTOS_CB_BankAccountid
JOIN ebs.FTOS_TPM_InvoiceDetail AS ID ON ID.InvoiceId = I.FTOS_TPM_Invoiceid
JOIN ebs.FTOS_BNKAP_Application AS APP ON APP.ContractId = ID.ContractId
JOIN ebs.FTOS_CB_Payment AS P ON I.FTOS_TPM_Invoiceid=P.InvoiceId
JOIN ebs.FTOS_BP_BankingProduct AS BP ON BP.FTOS_BP_BankingProductid=(SELECT CO.ProductId from ebs.FTOS_CB_Contract AS CO where CO.FTOS_CB_Contractid = ID.ContractId)
JOIN ebs.FTOS_TPM_PreInvoiceDetail AS PID ON PID.ContractId = C.FTOS_CB_Contractid
left JOIN ebs.FTOS_ONEY_ICE_Repayment as R ON P.PaymentNo = R.PaymentNo
left JOIN ebs.FTOS_ONEY_ICE_Repayment_Details AS RD ON RD.FTOS_ONEY_ICE_Repaymentid = R.FTOS_ONEY_ICE_Repaymentid -- detalii plati efectuate
left JOIN ebs.FTOS_ONEY_ICE_Libra_ReceivedPayments AS RP ON RP.FTOS_CB_Contractid = C.FTOS_CB_Contractid --and DATEPART(week, C.CreatedOn) = DATEPART(week, GETDATE()) take current week results
END`
I have another table where commissions are stored, the problem is I don't know how to select them in my stored procedure if they are on separate columns:
Here is the test query:
SELECT PID.*
FROM [ebs].[FTOS_TPM_PreInvoiceDetail] as PID
WHERE PID.Name = 'name'
Basically for this example I want those values 20 and 5 to be selected in my stored procedures as two different values, how can I achieve that?
I tried created another stored procedure, but I think is a very bad idea.

SQL Server / T-SQL : query optimization assistance

I have this QA logic that looks for errors into every AuditID within a RoomID to see if their AuditType were never marked Complete or if they have two complete statuses. Finally, it picks only the maximum AuditDate of the RoomIDs with errors to avoid showing multiple instances of the same RoomID, since there are many audits per room.
The issue is that the AUDIT table is very large and takes a long time to run. I was wondering if there is anyway to reach the same result faster.
Thank you in advance !
IF object_ID('tempdb..#AUDIT') is not null drop table #AUDIT
IF object_ID('tempdb..#ROOMS') is not null drop table #ROOMS
IF object_ID('tempdb..#COMPLETE') is not null drop table #COMPLETE
IF object_ID('tempdb..#FINALE') is not null drop table #FINALE
SELECT distinct
oc.HotelID, o.RoomID
INTO #ROOMS
FROM dbo.[rooms] o
LEFT OUTER JOIN dbo.[hotels] oc on o.HotelID = oc.HotelID
WHERE
o.[status] = '2'
AND o.orderType = '2'
SELECT
t.AuditID, t.RoomID, t.AuditDate, t.AuditType
INTO
#AUDIT
FROM
[dbo].[AUDIT] t
WHERE
t.RoomID IN (SELECT RoomID FROM #ROOMS)
SELECT
t1.RoomID, t3.AuditType, t3.AuditDate, t3.AuditID, t1.CompleteStatus
INTO
#COMPLETE
FROM
(SELECT
RoomID,
SUM(CASE WHEN AuditType = 'Complete' THEN 1 ELSE 0 END) AS CompleteStatus
FROM
#AUDIT
GROUP BY
RoomID) t1
INNER JOIN
#AUDIT t3 ON t1.RoomID = t3.RoomID
WHERE
t1.CompleteStatus = 0
OR t1.CompleteStatus > 1
SELECT
o.HotelID, o.RoomID,
a.AuditID, a.RoomID, a.AuditDate, a.AuditType, a.CompleteStatus,
c.ClientNum
INTO
#FINALE
FROM
#ROOMS O
LEFT OUTER JOIN
#COMPLETE a on o.RoomID = a.RoomID
LEFT OUTER JOIN
[dbo].[clients] c on o.clientNum = c.clientNum
SELECT
t.*,
Complete_Error_Status = CASE WHEN t.CompleteStatus = 0
THEN 'Not Complete'
WHEN t.CompleteStatus > 1
THEN 'Complete More Than Once'
END
FROM
#FINALE t
INNER JOIN
(SELECT
RoomID, MAX(AuditDate) AS MaxDate
FROM
#FINALE
GROUP BY
RoomID) tm ON t.RoomID = tm.RoomID AND t.AuditDate = tm.MaxDate
One section you could improve would be this one. See the inline comments.
SELECT
t1.RoomID, t3.AuditType, t3.AuditDate, t3.AuditID, t1.CompleteStatus
INTO
#COMPLETE
FROM
(SELECT
RoomID,
COUNT(1) AS CompleteStatus
-- Use the above along with the WHERE clause below
-- so that you are aggregating fewer records and
-- avoiding a CASE statement. Remove this next line.
--SUM(CASE WHEN AuditType = 'Complete' THEN 1 ELSE 0 END) AS CompleteStatus
FROM
#AUDIT
WHERE
AuditType = 'Complete'
GROUP BY
RoomID) t1
INNER JOIN
#AUDIT t3 ON t1.RoomID = t3.RoomID
WHERE
t1.CompleteStatus = 0
OR t1.CompleteStatus > 1
Just a thought. Streamline your code and your solution. you are not effectively filtering your datasets smaller so you continue to query the entire tables which is taking a lot of your resources and your temp tables are becoming full copies of those columns without the indexes (PK, FK, ++??) on the original table to take advantage of. This by no means is a perfect solution but it is an idea of how you can consolidate your logic and reduce your overall data set. Give it a try and see if it performs better for you.
Note this will return the last audit record for any room that has either not had an audit completed or completed more than once.
;WITH cte AS (
SELECT
o.RoomId
,o.clientNum
,a.AuditId
,a.AuditDate
,a.AuditType
,NumOfAuditsComplete = SUM(CASE WHEN a.AuditType = 'Complete' THEN 1 ELSE 0 END) OVER (PARTITION BY o.RoomId)
,RowNum = ROW_NUMBER() OVER (PARTITION BY o.RoomId ORDER BY a.AuditDate DESC)
FROm
dbo.Rooms o
LEFT JOIN dbo.Audit a
ON o.RoomId = a.RoomId
WHERE
o.[Status] = 2
AND o.OrderType = 2
)
SELECT
oc.HotelId
,cte.RoomId
,cte.AuditId
,cte.AuditDate
,cte.AuditType
,cte.NumOfAuditsComplete
,cte.clientNum
,Complete_Error_Status = CASE WHEN cte.NumOfAuditsComplete > 1 THEN 'Complete More Than Once' ELSE 'Not Complete' END
FROM
cte
LEFT JOIN dbo.Hotels oc
ON cte.HotelId = oc.HotelId
LEFT JOIN dbo.clients c
ON cte.clientNum = c.clientNum
WHERE
cte.RowNum = 1
AND cte.NumOfAuditsComplete != 1
Also note I changed your
WHERE
o.[status] = '2'
AND o.orderType = '2'
TO
WHERE
o.[status] = 2
AND o.orderType = 2
to be numeric without the single quotes. If the data type is truely varchar add them back but when you query a numeric column as a varchar it will do data conversion and may not take advantage of indexes that you have built on the table.

SQL Server 2012 : Multiple Queries in One Stored Procedure

How do I create Stored Procedure on these queries and he output should show which check the anomaly was captured from, along with all the relevant data.
SELECT cm.Cust_id, cm.cust_ref_id4, cm.cust_ref_id3, cm.plan_group, cm.Company_name, cm.Cust_firstname, cm.Cust_lastname
COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID, c3.CompanyName FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID AND cm.cust_ref_id3 = c.pkCustomerID AND cm.cust_ref_id3 >= 1000000 AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN ('A','P','R','G') AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL ORDER BY cust_ref_id4;
and
SELECT [pkCustomerID],b.[pkContractID],[pkCustomerTypeID],[CustomerType],b.[ContractType] AS Contractype1,c.[ContractType]
AS Contractype2 FROM [CORE].[dbo].[Customers] a
JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (SELECT [pkContractID],[ContractType],[fkCustomerID] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE [ContractType] NOT LIKE 'Holdover%')b ON a.pkCustomerID=b.fkCustomerID
LEFT JOIN (SELECT [pkContractID],[fkCustomerID],[ContractType] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE ContractType LIKE 'Holdover%')c ON b.fkCustomerID=c.fkCustomerID WHERE [CustomerType] IN ('Customer','Former Customer') AND (b.ContractType IS NULL OR c.ContractType IS NULL)
You question is lacking a very important piece of information, the explanation of what you are trying to do. I took a shot in the dark here as a guess to what you might be looking for. BTW, I ran this through a formatter so it was legible.
SELECT 'Found in query1'
,cm.Cust_id
,cm.cust_ref_id4
,cm.cust_ref_id3
,cm.plan_group
,cm.Company_name
,cm.Cust_firstname
,cm.Cust_lastname
,COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID
,c3.CompanyName
FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID
AND cm.cust_ref_id3 = c.pkCustomerID
AND cm.cust_ref_id3 >= 1000000
AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN (
'A'
,'P'
,'R'
,'G'
)
AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL
SELECT 'Found in query 2'
,[pkCustomerID]
,b.[pkContractID]
,[pkCustomerTypeID]
,[CustomerType]
,b.[ContractType] AS Contractype1
,c.[ContractType] AS Contractype2
FROM [CORE].[dbo].[Customers] a
INNER JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (
SELECT [pkContractID]
,[ContractType]
,[fkCustomerID]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE [ContractType] NOT LIKE 'Holdover%'
) b ON a.pkCustomerID = b.fkCustomerID
LEFT JOIN (
SELECT [pkContractID]
,[fkCustomerID]
,[ContractType]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE ContractType LIKE 'Holdover%'
) c ON b.fkCustomerID = c.fkCustomerID
WHERE [CustomerType] IN (
'Customer'
,'Former Customer'
)
AND (
b.ContractType IS NULL
OR c.ContractType IS NULL
)

multiple errors in using with function in select statement

I'm having some problems with my select statement. When I try to execute it, it gives 3 errors
Must specify table to select from
An object or column name is missing or empty for SELECT INFO statements. verify each column
has a name. For other statements, look for empty alias names. Aliases defined...
Column name or number of supplied values does not match table definition.
WITH A AS
(SELECT ROW_NUMBER() OVER (ORDER BY
CASE
WHEN #pOrderBy = 'SortByName' THEN colPortAgentVendorNameVarchar
WHEN #pOrderBy = 'SortByCOuntry' THEN colCountryNameVarchar
WHEN #pOrderBy = 'SortByCity' THEN colCityNameVarchar
END,
colPortAgentVendorNameVarchar
) xRow, A.*
FROM
(
SELECT DISTINCT
V.colPortAgentVendorIDInt,
colPortAgentVendorNameVarchar = RTRIM(LTRIM(V.colPortAgentVendorNameVarchar)),
C.colCountryNameVarchar,
Y.colCityNameVarchar,
V.colContactNoVarchar,
V.colFaxNoVarchar,
V.colEmailToVarchar,
V.colWebsiteVarchar,
BR.colBrandIdInt,
PR.colPriorityTinyint,
colBrandCodeVarchar = RTRIM(LTRIM(BR.colBrandCodeVarchar))
FROM dbo.TblVendorPortAgent V
LEFT JOIN TblCountry C ON C.colCountryIDInt = V.colCountryIDInt
LEFT JOIN TblCity Y ON Y.colCityIDInt = V.colCityIDInt
LEFT JOIN tblBrandAirportPortAgent PR ON PR.colPortAgentVendorIDInt = V.colPortAgentVendorIDInt
AND PR.colIsActiveBit = 1
LEFT JOIN TblBrand BR ON BR.colBrandIdInt = PR.colBrandIdInt
AND BR.colIsActiveBit = 1
WHERE V.colIsActiveBit = 1
AND V.colPortAgentVendorNameVarchar LIKE '%'+ #pPortAgentVendor +'%'
AND (PR.colBrandIdInt = #pBrandID OR #pBrandID = 0)
) A
)
INSERT INTO #tempPortAgent
SELECT A.*, IsWithContract = CASE WHEN colContractIdInt IS NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END FROM A LEFT JOIN TblContractPortAgent B ON A.colPortAgentVendorIDInt = B.colPortAgentVendorIDInt
AND B.colIsActiveBit = 1
;WITH QQ AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY Q.colPortAgentVendorIDInt ORDER BY xRow,
ContractStatusOrder,
colDateCreatedDate DESC
)ContractRow,*
FROM
(
SELECT DISTINCT GG.*, B.colContractIdInt, B.colContractStatusVarchar, B.colDateCreatedDate ,
ContractStatusOrder = CASE WHEN B.colContractStatusVarchar = 'Approved' THEN 1 ELSE '2' END
FROM #tempPortAgent GG LEFT JOIN TblContractPortAgent B ON GG.colPortAgentVendorIDInt = B.colPortAgentVendorIDInt
AND B.colIsActiveBit = 1
) Q
)SELECT * INTO #tempPortAgentWithContract
SELECT * FROM #tempPortAgentWithContract
I don't really know where its showing, because the errors are saying that these are inside the select statements inside.
1- Use Select Into instead of Insert into select
SELECT A.*, IsWithContract = CASE WHEN colContractIdInt IS NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END
Into #tempPortAgent
FROM A
LEFT JOIN TblContractPortAgent B ON A.colPortAgentVendorIDInt = B.colPortAgentVendorIDInt
AND B.colIsActiveBit = 1
2- SELECT * INTO #tempPortAgentWithContract is incorrect syntax. you must use following format:
SELECT * INTO #tempPortAgentWithContract From QQ

SQL SP runs Slow

Hi
I am using an SP which takes 7 minutes in a server which has 7336 recrds
and 6seconds in another server which has 3500 records.
Can anybody help me to know why is it happening?
Thanks,
-Divya
THE SP:
SELECT WORKSHEET_ID
FROM PERSON PER
INNER JOIN PERSON EMPLEE
ON EMPLEE.PERSON_ID = PER.PERSON_ID
AND
dbo.FN_CHECKRPTSECURITY(EMPLEE.PERSON_ID, #p_SEC_ACCOUNT_ID) > 0
LEFT JOIN SEARCH_ASSIGNMENT_VW PERSON_ASGN
ON PERSON_ASGN.ASSIGNMENT_ID =
dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
LEFT JOIN LOOKUP EMPLEE_ASGN_STAT
ON EMPLEE_ASGN_STAT.TYPE_ = 'ASSIGNMMENT_STATUS_CODE'
AND EMPLEE_ASGN_STAT.CODE = PERSON_ASGN.ASGN_STAT_CODE
INNER JOIN
(SELECT w1.ASSIGNMENT_ID, w1.WORKSHEET_ID, w1.EFFECTIVE_DATE, w1.APPROVED_BY, w3.CREATED_BY
FROM WORKSHEET_PAYROLL_VW w1
INNER JOIN WORKSHEET w3
ON w3.WORKSHEET_ID = w1.WORKSHEET_ID
WHERE w1.EFFECTIVE_DATE = CASE
WHEN #p_MOST_RECENT_ONLY = 'Y'
THEN (SELECT MAX(w2.EFFECTIVE_DATE)
FROM WORKSHEET_PAYROLL_VW w2
WHERE w1.ASSIGNMENT_ID = w2.ASSIGNMENT_ID
AND (ISNULL(#p_WKS_EFFECTIVE_DATE,w2.EFFECTIVE_DATE) =w2.EFFECTIVE_DATE))
ELSE ISNULL(#p_WKS_EFFECTIVE_DATE,w1.EFFECTIVE_DATE)
END
)
PERSON_WKS
ON PERSON_WKS.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
INNER JOIN
(SELECT ASSIGNMENT_ID, VALUE
FROM ASSIGNMENT_HISTORY AH
WHERE FIELD_NAME ='HOME PAYROLL GROUP'
AND EFFECTIVE_DATE = (SELECT MAX(EFFECTIVE_DATE)
FROM ASSIGNMENT_HISTORY
WHERE ASSIGNMENT_ID = AH.ASSIGNMENT_ID
AND EFFECTIVE_DATE <=getDate()
AND FIELD_NAME = 'HOME PAYROLL GROUP')
)HOME_PAYROLL
ON HOME_PAYROLL.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
WHERE
(#p_SELECTED_PERSON_ONLY = 'N' OR EMPLEE.PERSON_ID = #p_PERSON_ID)
AND
(#p_ASGN_STAT_CODE IS NULL OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,1,1)
OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,2,1))
AND
(#p_POLICY_ID IS NULL OR PERSON_ASGN.PROGRAM_CODE = #p_POLICY_ID)
AND
(#p_HOME_COUNTRY_ID IS NULL OR PERSON_ASGN.HOMECOUNTRYID=#p_HOME_COUNTRY_ID)
AND
(#p_HOME_CITY_ID IS NULL OR PERSON_ASGN.HOMECITYID=#p_HOME_CITY_ID )
AND
(#p_HOME_COMPANY_ID IS NULL OR PERSON_ASGN.HOMEBUSINESSID=#p_HOME_COMPANY_ID )
AND
(#p_HOME_DIVISION_ID IS NULL OR PERSON_ASGN.HOMECOMPONENTID=#p_HOME_DIVISION_ID )
AND
(#p_HOST_COUNTRY_ID IS NULL OR PERSON_ASGN.HOSTCOUNTRYID=#p_HOST_COUNTRY_ID )
AND
(#p_HOST_CITY_ID IS NULL OR PERSON_ASGN.HOSTCITYID=#p_HOST_CITY_ID )
AND
(#p_HOST_COMPANY_ID IS NULL OR PERSON_ASGN.HOSTBUSINESSID=#p_HOST_COMPANY_ID )
AND
(#p_HOST_DIVISION_ID IS NULL OR PERSON_ASGN.HOSTCOMPONENTID=#p_HOST_DIVISION_ID )
AND
(#p_CREATED_BY IS NULL OR PERSON_WKS.CREATED_BY=#p_CREATED_BY )
AND
(#p_APPROVED_BY IS NULL OR PERSON_WKS.APPROVED_BY=#p_APPROVED_BY )
AND
(#p_payroll_code IS NULL OR HOME_PAYROLL.VALUE=#p_payroll_code )
ORDER BY PER.LAST_NAME ASC,
PER.FIRST_NAME ASC,
PERSON_WKS.EFFECTIVE_DATE DESC
The Function in the 5th line is the one which is running slow. rest of the part is running in 4secs
The FUNCTION:
BEGIN
DECLARE
#v_ASGN_COUNT INT,
#v_RESULT INT
SELECT #v_ASGN_COUNT = COUNT(ASSIGNMENT_ID) --to find out if this employee has any assignment
FROM ASSIGNMENT
WHERE EXPATRIATE_PERSON_ID = #p_PERSON_ID AND
ASGN_STAT_CODE IN ('PD','A','I')
IF(#v_ASGN_COUNT > 0) --yes assignment, check against SECURITY_ASSIGNMENT_VW
BEGIN
SELECT #v_RESULT = COUNT(ASSIGNMENT_ID)
FROM SECURITY_ASSIGNMENT_VW
WHERE SEC_ACCOUNT_ID = #p_SEC_ACCOUNT_ID AND
ASSIGNMENT_ID IN (SELECT ASSIGNMENT_ID
FROM ASSIGNMENT
WHERE EXPATRIATE_PERSON_ID = #p_PERSON_ID AND
ASGN_STAT_CODE IN ('PD','A','I'))
END
ELSE --no assignment, so check against SECURITY_PERSON_VW
BEGIN
SELECT #v_RESULT = COUNT(PERSON_ID)
FROM SECURITY_PERSON_VW
WHERE SEC_ACCOUNT_ID = #p_SEC_ACCOUNT_ID AND
PERSON_ID = #p_PERSON_ID
END
RETURN #v_RESULT
END
Do the schemas match exactly... in particular check for missing indexes.
Well to begin with you have scalar functions which will run significantly slower as the number of records increase becasue they process row-by-agonizing-row. Not only that you've used the functions in joins which is a horrible practice if you need performance. You have a bunch of OR conditions which tend to slowness. And while it is too hard to actually read the code you posted (please try to format and only use all caps for keywords), I would suspect that some of those conditions are not sargable.
To know what is actually happening check the Execution plan (SQL Server) or Explain Plan (mySQL and others I think) or the equivalent feature in your database. Likely you wil find table scans which of course are going to get significantly slower as the number of records increases.
You may also have a problem with parameter sniffing. Please google to see how to fix that.
One improvement would be to make sure that dbo.FN_GETRPTSSIGNMENTID only gets executed once.
Currently, it gets executed three times.
You can replace two of those calls by joining to the field of the (one) remaing call.
Something like
SELECT WORKSHEET_ID
FROM PERSON PER
INNER JOIN PERSON EMPLEE ON EMPLEE.PERSON_ID = PER.PERSON_ID AND dbo.FN_CHECKRPTSECURITY(EMPLEE.PERSON_ID, #p_SEC_ACCOUNT_ID) > 0
INNER JOIN (
SELECT w1.ASSIGNMENT_ID
, w1.WORKSHEET_ID
, w1.EFFECTIVE_DATE
, w1.APPROVED_BY
, w3.CREATED_BY
FROM WORKSHEET_PAYROLL_VW w1
INNER JOIN WORKSHEET w3 ON w3.WORKSHEET_ID = w1.WORKSHEET_ID
WHERE w1.EFFECTIVE_DATE =
CASE WHEN #p_MOST_RECENT_ONLY = 'Y'
THEN (
SELECT MAX(w2.EFFECTIVE_DATE)
FROM WORKSHEET_PAYROLL_VW w2
WHERE w1.ASSIGNMENT_ID = w2.ASSIGNMENT_ID AND (ISNULL(#p_WKS_EFFECTIVE_DATE,w2.EFFECTIVE_DATE) = w2.EFFECTIVE_DATE)
)
ELSE ISNULL(#p_WKS_EFFECTIVE_DATE,w1.EFFECTIVE_DATE)
END
) PERSON_WKS ON PERSON_WKS.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
INNER JOIN (
SELECT ASSIGNMENT_ID
, VALUE
FROM ASSIGNMENT_HISTORY AH
WHERE FIELD_NAME ='HOME PAYROLL GROUP'
AND EFFECTIVE_DATE = (
SELECT MAX(EFFECTIVE_DATE)
FROM ASSIGNMENT_HISTORY
WHERE ASSIGNMENT_ID = AH.ASSIGNMENT_ID
AND EFFECTIVE_DATE <=getDate()
AND FIELD_NAME = 'HOME PAYROLL GROUP'
)
LEFT JOIN SEARCH_ASSIGNMENT_VW PERSON_ASGN ON PERSON_ASGN.ASSIGNMENT_ID = PERSON_WKS.ASSIGNMENT_ID
LEFT JOIN LOOKUP EMPLEE_ASGN_STAT ON EMPLEE_ASGN_STAT.TYPE_ = 'ASSIGNMMENT_STATUS_CODE' AND EMPLEE_ASGN_STAT.CODE = PERSON_ASGN.ASGN_STAT_CODE
) HOME_PAYROLL ON HOME_PAYROLL.ASSIGNMENT_ID = PERSON_WKS.ASSIGNMENT_ID
WHERE (#p_SELECTED_PERSON_ONLY = 'N' OR EMPLEE.PERSON_ID = #p_PERSON_ID)
AND (#p_ASGN_STAT_CODE IS NULL OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,1,1) OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,2,1))
AND (#p_POLICY_ID IS NULL OR PERSON_ASGN.PROGRAM_CODE = #p_POLICY_ID)
AND (#p_HOME_COUNTRY_ID IS NULL OR PERSON_ASGN.HOMECOUNTRYID=#p_HOME_COUNTRY_ID)
AND (#p_HOME_CITY_ID IS NULL OR PERSON_ASGN.HOMECITYID=#p_HOME_CITY_ID )
AND (#p_HOME_COMPANY_ID IS NULL OR PERSON_ASGN.HOMEBUSINESSID=#p_HOME_COMPANY_ID )
AND (#p_HOME_DIVISION_ID IS NULL OR PERSON_ASGN.HOMECOMPONENTID=#p_HOME_DIVISION_ID )
AND (#p_HOST_COUNTRY_ID IS NULL OR PERSON_ASGN.HOSTCOUNTRYID=#p_HOST_COUNTRY_ID )
AND (#p_HOST_CITY_ID IS NULL OR PERSON_ASGN.HOSTCITYID=#p_HOST_CITY_ID )
AND (#p_HOST_COMPANY_ID IS NULL OR PERSON_ASGN.HOSTBUSINESSID=#p_HOST_COMPANY_ID )
AND (#p_HOST_DIVISION_ID IS NULL OR PERSON_ASGN.HOSTCOMPONENTID=#p_HOST_DIVISION_ID )
AND (#p_CREATED_BY IS NULL OR PERSON_WKS.CREATED_BY=#p_CREATED_BY )
AND (#p_APPROVED_BY IS NULL OR PERSON_WKS.APPROVED_BY=#p_APPROVED_BY )
AND (#p_payroll_code IS NULL OR HOME_PAYROLL.VALUE=#p_payroll_code )
ORDER BY
PER.LAST_NAME ASC
, PER.FIRST_NAME ASC
, PERSON_WKS.EFFECTIVE_DATE DESC