Related
New to SQL and was given the query below to use in Power BI. It pulls the data table correctly on preview but fails when applying the change into Power BI Desktop. I don't know how to fix the syntax.
I get this error:
Power BI - SQL: Incorrect syntax near the keyword 'DECLARE'. Incorrect syntax near ')'.
Here is the query:
DECLARE #CLIENT AS NVARCHAR(32)
DECLARE #FULLVERSION AS NVARCHAR(10)
DECLARE #DATERUN AS DATETIME
DECLARE #ANON AS INT --1 to set anonymised mode on, 0 to set it to off
DECLARE #FROMDATE AS DATE --(FORMAT = YYYYMMDD) --UPDATE
DECLARE #TODATE AS DATE --(FORMAT = YYYYMMDD) --UPDATE
SET #CLIENT = 'HOGANS'
--SET #FULLVERSION = (SELECT MAX(BH_Version) FROM BH_Version)
SET #DATERUN = ( Getdate() )
SET #ANON = 0
SET #FROMDATE = '20211101' --(FORMAT = YYYYMMDD) --UPDATE
SET #TODATE = '20211231' --(FORMAT = YYYYMMDD) --UPDATE
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET nocount ON;
-- Insert statements for procedure here
SELECT #Client AS
ClientName,
#DATERUN AS DateRun,
#FROMDATE AS
QueryVariable_FromDate,
#TODATE AS
QueryVariable_ToDate,
-- #FULLVERSION as BHVersionWhenRun,
T.bh_taskguid,
RIGHT(Datepart(yy, T.bh_creationdate), 2)
+ RIGHT('00'+ CONVERT(NVARCHAR(2), Datepart(mm, T.bh_creationdate)), 2)
+ '-' + CONVERT(NVARCHAR, T.bh_referenceid) AS TaskID,
Auth.bh_userguid AS
AuthorGUID,
CASE
WHEN #ANON = 0 THEN Auth.bh_username
WHEN #ANON = 1 THEN NULL
END AS
AuthorName,
AuthDept.bh_departmentname AS
AuthorDepartmentName,
(SELECT TOP 1 AD.bh_departmentname
FROM bh_historic_report_departments AS AD
WHERE AuthDept.bh_parentguid = AD.bh_departmentguid) AS
AuthorDepartmentParent,
--THIS CHECKS THE HISTORIC DEPT STRUCTURE TO GET THE NAME OF THE PARENT DEPARTMENT OF THE AUTHOR
Sec.bh_userguid AS
CompletedByGUID,
CASE
WHEN #ANON = 0 THEN Sec.bh_username
WHEN #ANON = 1 THEN NULL
END AS
CompletedByName,
SecDept.bh_departmentname AS
CompletedByDepartmentName,
(SELECT TOP 1 SD.bh_departmentname
FROM bh_historic_report_departments AS SD
WHERE SecDept.bh_parentguid = SD.bh_departmentguid) AS
SecDepartmentParent,
--THIS CHECKS THE HISTORIC DEPT STRUCTURE TO GET THE NAME OF THE PARENT DEPARTMENT OF THE SECRETARY
CASE
WHEN #ANON = 0 THEN (SELECT TOP 1 HU.bh_username
--BH_UserGuid and remove the join for GUID only
FROM bh_historic_report_taskaudit HTA
INNER JOIN bh_historic_report_users AS HU
ON ( HU.bh_userguid =
HTA.bh_userguid )
WHERE ( HTA.bh_taskguid = T.bh_taskguid )
ORDER BY bh_auditid ASC)
WHEN #ANON = 1 THEN NULL
END AS
'Submitted By (Name)',
(SELECT TOP 1 bh_userguid
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
ORDER BY bh_auditid ASC) AS
'Submitted By (GUID)',
(SELECT bh_username
FROM bh_locks
WHERE bh_objectguid = t.bh_taskguid) AS
'Locked By',
CASE
WHEN (SELECT bh_username
FROM bh_locks
WHERE bh_objectguid = t.bh_taskguid) IS NULL THEN 'Pending'
WHEN Sec.bh_userguid IS NULL THEN 'In Progress'
ELSE 'Complete'
END AS
'TaskStatus',
CASE
WHEN (SELECT TOP 1 bh_userguid
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
ORDER BY bh_auditid ASC) = Auth.bh_userguid THEN 'Author'
ELSE 'On Behalf'
END AS
'Logged by',
WF.bh_workflowname AS
WorkflowName,
CASE
WHEN DT.bh_workflowname IS NOT NULL THEN DT.bh_workflowname
ELSE 'Not Configured'
END AS
'Work Type Should Go To',
CASE
WHEN ( DT.bh_workflowguid = T.bh_workflowguid ) THEN 'Correct Workflow'
--If no default workflow is specified then we assume this is sent to the correct workflow.
WHEN ( DT.bh_workflowguid IS NULL ) THEN 'No Default Workflow'
ELSE 'Incorrect Workflow'
END AS
'Sent To Correct Workflow',
-- ONLY POSSIBLE ON V5 AND ABOVE
CASE
WHEN ( T.bh_source = '15' ) -- Sent from Forms Desktop Assistant
--OR the below which includes iOS (10, 11), Android (12), Now Mail (4) and Hub (18)
OR ( T.bh_lengthintenths = '0'
AND T.bh_source IN ( '18', '10', '11', '12', '4' ) )
--AND T.BH_DocumentType NOT IN (SELECT BH_DocumentTypeName FROM BH_DocumentTypes)) -- assuming that if WT no longer exists and is zero length and is sent from Hub (i.e. not from Mobile, Classic etc which can't send Now tasks) then NOW
THEN 'TASK'
ELSE 'VOICE'
END AS
'Task Type (TASK or VOICE)',
--FOR V4, MANUALLY APPLYING ALL VOICE AS TASK TYPE
-- 'VOICE' as 'Task Type (NOW or VOICE)',
CASE
WHEN #ANON = 0 THEN T.bh_title
WHEN #ANON = 1 THEN NULL
ELSE NULL
END AS
'BH_Title',
T.bh_documenttype AS WorkType
,
T.bh_creationdate,
T.bh_senddate,
T.bh_sentpriority,
CASE
WHEN TA.priorities > 1 THEN 'YES'
ELSE 'NO'
END AS
'PriorityChanged',
T.bh_completiondate,
CASE
WHEN ( T.bh_requiredby IS NOT NULL )
AND ( T.bh_completiondate <= T.bh_requiredby ) THEN 'On Time'
WHEN ( T.bh_requiredby IS NOT NULL )
AND ( T.bh_completiondate > T.bh_requiredby ) THEN 'Overdue'
WHEN T.bh_requiredby IS NULL THEN 'No Deadline Set'
END AS OnTime,
T.bh_priorityname,
T.bh_requiredby,
CASE
WHEN TA.requiredby > 1 THEN 'YES'
ELSE 'NO'
END AS
'RequiredByChanged',
T.bh_sourcetimezone AS
TimeZoneOffset,
T.bh_turnaroundtime AS
TurnaroundTimeInSec,
--NOTE: this is the difference in seconds between the send date and the completion date
-- (
-- RIGHT('000' + CONVERT(VARCHAR, T.BH_TurnaroundTime / 3600 / 24),3) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR, T.BH_TurnaroundTime / 3600 % 24),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR, T.BH_TurnaroundTime / 60 % 60),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR,T.BH_TurnaroundTime % 60),2)
-- ) AS TurnaroundTimeDays,
T.bh_numreassignments,
CASE
WHEN ( T.bh_source = '0' ) THEN 'Classic Client'
WHEN ( T.bh_source = '4' ) THEN 'Now Mail'
WHEN ( T.bh_source = '5' ) THEN 'Web Client'
WHEN ( T.bh_source = '6' ) THEN 'Windows Mobile'
WHEN ( T.bh_source = '7' ) THEN 'BlackBerry'
WHEN ( T.bh_source = '8' ) THEN 'Hosted Services Client'
WHEN ( T.bh_source = '9' ) THEN 'Work Manager'
WHEN ( T.bh_source = '10' ) THEN 'BigHand Go'
WHEN ( T.bh_source = '11' ) THEN 'BigHand Mobile iPhone'
WHEN ( T.bh_source = '12' ) THEN 'Android'
WHEN ( T.bh_source = '13' ) THEN 'BlackBerry 10'
WHEN ( T.bh_source = '14' ) THEN 'Windows Phone'
WHEN ( T.bh_source = '15' ) THEN 'BigHand Now'
WHEN ( T.bh_source = '16' ) THEN 'BigHand Go For Windows'
WHEN ( T.bh_source = '17' ) THEN 'BigHand Go For Windows Phone'
WHEN ( T.bh_source = '18' ) THEN 'Hub'
END AS 'Source'
,
T.bh_sourcetimezone,
--(
-- RIGHT('00' + CONVERT(VARCHAR, (T.BH_LengthInTenths/10) / 3600 % 24),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR, (T.BH_LengthInTenths/10) / 60 % 60),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR,(T.BH_LengthInTenths/10) % 60),2)
-- ) AS LengthInHours,
( T.bh_lengthintenths / 10 ) AS
LengthInSeconds,
( T.bh_lengthintenths / 10 ) / 60 AS
LengthInMins,
(SELECT Sum(Datediff(second, bh_startdate, bh_enddate))
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )) AS
'Total Processing Time (Sec)',
--(
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND BH_StartDate >= T.BH_SendDate) / 3600 % 24),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND BH_StartDate >= T.BH_SendDate) / 60 % 60),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND BH_StartDate >= T.BH_SendDate) % 60),2)
--) AS TotalProcessingHours,
( Isnull((SELECT Sum(Datediff(second, bh_startdate, bh_enddate))
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
AND ( bh_userguid = T.bh_authorguid )), 0) ) AS
'Author Processing Time (Sec)',
--(ISNULL((
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 3600 % 24),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 60 % 60),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) % 60),2)), '00:00:00')
-- ) AS AuthorProcessingHours,
( Isnull((SELECT Sum(Datediff(second, bh_startdate, bh_enddate))
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
AND ( bh_userguid <> T.bh_authorguid )
AND ( bh_startdate >= T.bh_senddate )), 0) ) AS
'Non-Author Processing Time (Sec)',
--(ISNULL((
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 3600 % 24),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 60 % 60),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(datediff(SECOND,BH_StartDate, BH_EndDate))
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) % 60),2)), '00:00:00')
--) AS NonAuthorProcessingHours,
(SELECT Sum(bh_playtime)
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
AND ( bh_startdate >= T.bh_senddate )) AS
'TotalPlay Time',
--(
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_StartDate >= T.BH_SendDate)) / 3600 % 24),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_StartDate >= T.BH_SendDate)) / 60 % 60),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_StartDate >= T.BH_SendDate)) % 60),2)
--) AS TotalPlaytimeHours,
( Isnull((SELECT Sum(bh_playtime)
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
AND ( bh_userguid = T.bh_authorguid )
AND ( bh_startdate >= T.bh_senddate )), 0) ) AS
'Author Play Time (Sec)',
-- (ISNULL((
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 3600 % 24),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 60 % 60),2) + ':'
-- + RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid = T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) % 60),2)), '00:00:00' )
-- ) AS AuthorPlaytimeHours,
( Isnull((SELECT Sum(bh_playtime)
FROM bh_historic_report_taskaudit
WHERE ( bh_taskguid = T.bh_taskguid )
AND ( bh_userguid <> T.bh_authorguid )
AND ( bh_startdate >= T.bh_senddate )), 0) ) AS
'Non-Author Play Time (Sec)'
--(ISNULL((
-- RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 3600 % 24),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR, (SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) / 60 % 60),2) + ':'
--+ RIGHT('00' + CONVERT(VARCHAR,(SELECT sum(BH_PlayTime)
-- FROM BH_HISTORIC_REPORT_TASKAUDIT
-- WHERE (BH_TaskGuid = T.BH_TaskGuid) AND (BH_UserGuid <> T.BH_AuthorGuid) AND (BH_StartDate >= T.BH_SendDate)) % 60),2)
--), '00:00:00')) AS NonAuthorPlaytimeHours,
FROM bh_historic_report_tasks AS T
INNER JOIN bh_historic_report_users AS Auth
ON ( T.bh_authorguid = Auth.bh_userguid )
LEFT OUTER JOIN bh_historic_report_users AS Sec
ON ( T.bh_completedby = Sec.bh_userguid )
INNER JOIN bh_historic_report_departments AS AuthDept
ON ( T.bh_authordept = AuthDept.bh_departmentguid )
LEFT OUTER JOIN bh_historic_report_departments AS SecDept
ON ( T.bh_completedbydept = SecDept.bh_departmentguid )
INNER JOIN bh_historic_report_workflows AS WF
ON ( T.bh_workflowguid = WF.bh_workflowguid )
LEFT OUTER JOIN (SELECT NULL AS Availability,
A.bh_documenttypeguid,
A.bh_documenttypename,
A.bh_workflowguid,
WF.bh_workflowname,
A.bh_usage
FROM bh_documenttypes AS A
INNER JOIN bh_historic_report_workflows AS WF
ON ( A.bh_workflowguid =
WF.bh_workflowguid )
WHERE ( bh_isglobal = '1'
AND bh_deleted = 0
AND bh_disabled = 0 )
UNION
SELECT DocTypeDept.bh_departmentguid AS Availability,
DOCTYPE.bh_documenttypeguid,
DOCTYPE.bh_documenttypename,
DOCTYPE.bh_workflowguid,
WFLOW.bh_workflowname,
DOCTYPE.bh_usage
FROM bh_documenttypebydepartment AS DOCTYPEDEPT
INNER JOIN bh_documenttypes AS DOCTYPE
ON ( DOCTYPE.bh_documenttypeguid =
DOCTYPEDEPT.bh_documenttypeguid )
LEFT OUTER JOIN bh_historic_report_workflows AS
WFLOW
ON ( DOCTYPE.bh_workflowguid =
WFLOW.bh_workflowguid )
WHERE DOCTYPEDEPT.bh_departmentguid IN
(SELECT DISTINCT tempT.bh_authordept
FROM
bh_historic_report_tasks AS TempT
WHERE
--TempT.BH_SendDate >='20170901'
TempT.bh_completiondate >= #FROMDATE
--Only include tasks sent after a certain date (FORMAT = YYYYMMDD)
AND TempT.bh_completiondate < #TODATE
--Only include tasks sent after a certain date (FORMAT = YYYYMMDD)
)
AND DOCTYPE.bh_deleted = 0
AND DOCTYPE.bh_disabled = 0) AS DT
ON ( T.bh_documenttype = DT.bh_documenttypename )
AND ( ( DT.availability = AuthDept.bh_departmentguid )
OR ( DT.availability IS NULL ) )
AND ( DT.bh_usage = ( CASE
WHEN ( T.bh_source = '15' )
-- Sent from Now client
OR ( T.bh_lengthintenths =
'0'
AND T.bh_source = '18'
)
----OR sent from Hub and zero length
THEN '2' --NOW TYPE
ELSE '1' --VOICE TYPE
END ) )
--Joining on latest Audit row for the task so can return things like the latest Workflow stage etc.
INNER JOIN (SELECT bh_taskguid,
Max(bh_auditid) AS AuditID,
Count(DISTINCT bh_requiredby) RequiredBy,
Count(DISTINCT bh_priorityname) Priorities
FROM bh_historic_report_taskaudit
GROUP BY bh_taskguid) TA
ON T.bh_taskguid = TA.bh_taskguid
INNER JOIN bh_historic_report_taskaudit TAUD
ON TA.auditid = TAUD.bh_auditid
WHERE
--T.BH_CompletionDate IS NOT NULL --Include completed tasks only AND
--T.BH_CompletedByDept IS NOT NULL--Excludes Drafts created but not submitted--changed from--AND SecDept.BH_DepartmentName IS NOT NULL AND
T.bh_completiondate >= #FROMDATE
--Only include tasks created after a certain date (FORMAT = YYYYMMDD)
AND T.bh_completiondate < #TODATE
--Only include tasks created after a certain date (FORMAT = YYYYMMDD)
AND TAUD.bh_startdate >= Dateadd(month, -1, #FROMDATE)
AND TAUD.bh_startdate <= Dateadd(month, 1, #TODATE) --only includes processing audit times for activities started within 1 month prior to and post the Completion Date range
Power BI constructs a query like this:
select * from ( ... your query goes here ... ) as SourceQuery
So when it puts your query between the parenthesis, it isn't a valid query anymore. Power BI does that, because it needs to be able to add joins and filters to your query. Either rebuild the logic inside Power BI using M and DAX, or put your query in a view/UDF in the data source and select from it.
I am trying to pull data out and chuck it into a Stimulsoft report. The problem I am having is that I need it to output to two columns. I also need every "manager" record to show even if the count assigned to said record is NULL.
This is what i have at the moment:
DECLARE #ManagerCount INT = (( SELECT Count(*) FROM AM WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0 ) + 1) / 2
DECLARE #tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO #tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0
SELECT * FROM (
SELECT ta.id AS id1, ta.AMName AS ManagerName1, COUNT(*) AS ManagerCount1 FROM #tmp_AM1 tA INNER JOIN Job J ON tA.AMID = j.AMID
WHERE ta.ID BETWEEN 1 AND #ManagerCount AND j.jobStatusID != 5
GROUP BY ta.ID, ta.AMName
) a
LEFT JOIN
(
SELECT ta.id AS id2,ta.AMName AS ManagerName2, COUNT(*) AS ManagerCount2 FROM #tmp_AM1 tA INNER JOIN Job J ON tA.AMID = j.AMID
WHERE ta.ID > #ManagerCount AND j.jobStatusID != 5
GROUP BY ta.AMName, ta.ID
) b ON a.id1 + #ManagerCount = b.id2
Which ends up returning something like:
There are 18 managers so 9 per column, but this code doesn't show them all since anything that doesn't have a count in the first left join, won't show, and therefore the same row in column 2 doesn't show.
Results of SELECT * FROM #tmp_AM1:
DECLARE #tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO #tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0
SELECT * FROM (
SELECT ta.id AS id1, ta.AMName AS ManagerName1, COUNT(*) AS ManagerCount1 FROM #tmp_AM1 tA INNER JOIN Job J ON tA.AMID = j.AMID
WHERE ta.ID BETWEEN 1 AND #ManagerCount AND j.jobStatusID != 5
GROUP BY ta.ID, ta.AMName
) a
LEFT OUTER JOIN
(
SELECT ta.id AS id2,ta.AMName AS ManagerName2, COUNT(*) AS ManagerCount2 FROM #tmp_AM1 tA INNER JOIN Job J ON tA.AMID = j.AMID
WHERE ta.ID > #ManagerCount AND j.jobStatusID != 5
GROUP BY ta.AMName, ta.ID
) b ON a.id1 + #ManagerCount = b.id2 where ManagerName2 IS Null and ManagerCount2 IS NULL
just you want to use LEFT OUTER JOIN for select row even there is have any null values.,
Since the two subqueries are pretty much identical, except the where-statement, I would consiter rewriting it into one single query. I'm not sure why you need the same columns outputed into different columns in the result, but something like this might work:
WITH cte AS (
SELECT
ta.id AS id
,ta.AMName AS ManagerName
,COUNT(*) AS ManagerCount
,CASE WHEN ta.ID BETWEEN 1 AND #ManagerCount THEN 0 ELSE 1 END AS something
FROM
#tmp_AM1 tA
INNER JOIN Job J ON tA.AMID = j.AMID
WHERE
j.jobStatusID != 5
GROUP BY
ta.ID
,ta.AMName
,CASE WHEN ta.ID BETWEEN 1 AND #ManagerCount THEN 0 ELSE 1 END
)
SELECT
CASE WHEN something = 0 THEN cte.id ELSE null END AS id1
,CASE WHEN something = 0 THEN cte.ManagerName ELSE null END AS ManagerName1
,CASE WHEN something = 0 THEN cte.ManagerCount ELSE null END AS ManagerCount1
,CASE WHEN something = 1 THEN cte.id ELSE null END AS id2
,CASE WHEN something = 1 THEN cte.ManagerName ELSE null END AS ManagerName2
,CASE WHEN something = 1 THEN cte.ManagerCount ELSE null END AS ManagerCount2
FROM
cte
Probably not the best approach but i got the correct output using:
DECLARE #ManagerCount INT = (( SELECT Count(*) FROM AM WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0 ) + 1) / 2
DECLARE #tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO #tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0
ORDER By AMName
SELECT ManagerName1, ManagerName2, ManagerCount1, ManagerCount2 FROM (
SELECT AMID, ta.id AS id1, ta.AMName AS ManagerName1 FROM #tmp_AM1 tA
WHERE (ta.ID BETWEEN 1 AND #ManagerCount)
) a
LEFT JOIN
(
SELECT AMID, ISNULL(COUNT(*), 0) AS ManagerCount1 FROM Job j
INNER JOIN tblJobOutcome jO ON j.JobOutcomeID = jo.JobOutcomeID AND jO.JobOutcomeID != 5
GROUP BY AMID
) a1 ON a.AMID = a1.AMID
LEFT JOIN
(
SELECT AMID, ta.id AS id2, ta.AMName AS ManagerName2 FROM #tmp_AM1 tA
WHERE (ta.ID > #ManagerCount)
) b ON a.id1 + #ManagerCount = b.id2
LEFT JOIN
(
SELECT AMID, ISNULL(COUNT(*), 0) AS ManagerCount2 FROM Job j
INNER JOIN tblJobOutcome jO ON j.JobOutcomeID = jo.JobOutcomeID AND jO.JobOutcomeID != 5
GROUP BY AMID
) b1 ON b.AMID = b1.AMID
Gives me the correct output in two columns.
gives me this:
Getting error:
Msg 512, Level 16, State 1, Line 48
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Msg 512, Level 16, State 1, Line 87
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Need to check each record in the table and update a table if there is no records = to 0,00. Then update an existing table with current values. I want to be able to track current data and compare with old data.
DECLARE #LocTime DATETIME;
DECLARE #MinDateTime DATETIME;
DECLARE #SystemDateTime DATETIME;
DECLARE #LIR MONEY;
DECLARE #LOAR MONEY;
SELECT #SystemDateTime = SYSDATETIME(); --= '2016-12-07 23:30:00'
SELECT #MinDateTime = DATEADD(mi,-30,#SystemDateTime) --go back half hour of reads, job is running every 10 minutes for overlap
--select #MinDateTime, #SystemDateTime
IF OBJECT_ID(N'tempdb..##LastOver2') IS NOT NULL
BEGIN
DROP TABLE ##LastOver2
END
--make temp table to hold found data
CREATE TABLE ##LastOver2 (ReadDate DATETIME
, FacilityName NVARCHAR(100)
, FacilityID UNIQUEIDENTIFIER
, LastInstantRead MONEY
, LastOverAllRead MONEY
, FacilityTimeZone INT
, FacilityTime DATETIME)
INSERT INTO ##LastOver2 (ReadDate, FacilityName
, FacilityID, LastInstantRead
, LastOverAllRead
, FacilityTimeZone, FacilityTime)
SELECT DISTINCT --why distinct?
fmr.ReadDate, f.Name
, f.FacilityID, fm.LastInstantRead
, fm.LastOverAllRead
, f.Timezone
, #LocTime
FROM [dbo].[Facilities] f WITH (NOLOCK)
JOIN [dbo].[FacilityMeters] fm WITH (NOLOCK)
ON F.FacilityID = FM.FacilityID
JOIN FacilityMeterReadings fmr WITH (NOLOCK)
ON FM.FacilityMeterID = FMR.FacilityMeterID
WHERE --fm.FacilityMeterID = '9268d1af-cc29-432c-9cdb-06c158180d2f'
(fmr.ReadDate >= #MinDateTime and ReadDate <= #SystemDateTime) --including on both side to continue with overlap
and (fm.IsVirtual = 0 and fm.ParentMeterID is NULL)
--and (fm.LastInstantRead = 0.00 and fm.LastOverAllRead = 0.00)
AND f.SuppressMonitoring = 0
select * from ##LastOver2
IF (select LastInstantRead from ##LastOver2) = 0.00 OR (SELECT LastOverAllRead FROM ##LastOver2) = 0.00
BEGIN
--UPDATE dbo.Facilities
--SET SuppressMonitoring = 1
-- FROM dbo.Facilities F
-- JOIN ##LastOver L
-- ON F.FacilityID = l.FacilityID
-- WHERE F.FacilityID = l.FacilityID
DECLARE #body_content NVARCHAR(150);
DECLARE #StartHour NVARCHAR(8) = '08:30:00' ;
DECLARE #StopHour NVARCHAR(8) = '16:00:00';
--why distinct, is it already distinct. Is is supposed to distinct the facility or meter?
DECLARE #SQLScript NVARCHAR(200) = 'SELECT distinct * FROM ##LastOver2 WHERE CONVERT(TIME, FacilityTime) BETWEEN '
+ CHAR(39) + #StartHour + CHAR(39) +' AND ' + CHAR(39) + #StopHour + CHAR(39);
--only looking for reads during day hours? shouldn't use between.
DECLARE #copyRecipients NVARCHAR(100)
SET #body_content = 'Please check the attached file. This was from server: ' + ##SERVERNAME
DECLARE #fileName nvarchar(255);
select #fileName = 'BadReading_' + replace(replace(convert(nvarchar(19),getdate(), 126),':',''),'-','') + '.txt';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'SQLSupport'
,#recipients = 'Btest#test.com'
--, #recipients = 'jira#cleanenergycollective.atlassian.net'
--, #copy_recipients= #copyRecipients
--, #copy_recipients= 'Bill.Lugaila#easycleanenergy.com;yvonne.lewis#easycleanenergy.com;don.munroe#easycleanenergy.com;Justin.Reed#easycleanenergy.com'
, #query = #SQLScript
, #subject = 'Facility Meter Check and Updating table' --change so easier to see in emails
, #body= #body_content
, #importance= 'High'
, #attach_query_result_as_file = 1
, #query_attachment_filename = #fileName ;
--select #SQLScript
END
ELSE IF (select LastInstantRead from ##LastOver2) != 0.00 OR (SELECT LastOverAllRead FROM ##LastOver2) != 0.00
BEGIN
UPDATE [dbo].[_LastInstant_OverAll_Read]
SET [FacilityName] = lo.FacilityName,
[LastInstantRead] = lo.LastInstantRead,
[LastOverAllRead]= lo.LastOverAllRead,
[Time_Date] = (SELECT CONVERT(DateTime, SysDateTime()))
FROM ##LastOver2 lo
WHERE lo.FacilityName = [dbo].[_LastInstant_OverAll_Read].FacilityName
AND lo.LastInstantRead != [dbo].[_LastInstant_OverAll_Read].LastInstantRead
AND lo.LastOverAllRead != [dbo].[_LastInstant_OverAll_Read].LastOverAllRead
END
the following could be returning multiple rows:
.
.
.
IF
(
SELECT LastInstantRead
FROM ##LastOver2
) = 0.00
OR
(
SELECT LastOverAllRead
FROM ##LastOver2
) = 0.00
.
.
.
IF
(
SELECT LastInstantRead
FROM ##LastOver2
) != 0.00
OR
(
SELECT LastOverAllRead
FROM ##LastOver2
) != 0.00
if you are expecting them to return only 1 row then you will need to fix the issue with the following query:
SELECT DISTINCT --why distinct?
fmr.ReadDate,
f.Name,
f.FacilityID,
fm.LastInstantRead,
fm.LastOverAllRead,
f.Timezone,
#LocTime
FROM [dbo].[Facilities] f WITH (NOLOCK)
JOIN [dbo].[FacilityMeters] fm WITH (NOLOCK) ON F.FacilityID = FM.FacilityID
JOIN FacilityMeterReadings fmr WITH (NOLOCK) ON FM.FacilityMeterID = FMR.FacilityMeterID
WHERE --fm.FacilityMeterID = '9268d1af-cc29-432c-9cdb-06c158180d2f'
(fmr.ReadDate >= #MinDateTime
AND ReadDate <= #SystemDateTime) --including on both side to continue with overlap
AND (fm.IsVirtual = 0
AND fm.ParentMeterID IS NULL)
--and (fm.LastInstantRead = 0.00 and fm.LastOverAllRead = 0.00)
AND f.SuppressMonitoring = 0;
I'm stuck - I have this nice little text searcher I've put together.
I realised I needed to count lnies in individual blocks of text that the stored procedure is stored in, so I think I've figured a way to do that.
But it's not getting every instance of a search term in a stored procedure - and I think it's the same reason... the search term is split across a text boundary.
I've looked at how to change my query - and I'm coming up blank. The skills involved to change it are beyond me!
--Text searcher.
DECLARE #searchString VARCHAR(255),
#doesNotContain VARCHAR(255),
#previewLength INTEGER,
#findStoredProcedures VARCHAR(3),
#findTableFunction VARCHAR(3),
#findScalerFunction VARCHAR(3),
#findTrigger VARCHAR(3),
#findView VARCHAR(3),
#findUserTable VARCHAR(3),
#onlyInName VARCHAR(3)
--------------------------------------------------------
-- Search criteria:
SET #searchString = 'My search Term'
SET #findStoredProcedures = 'yes'
SET #findTableFunction = 'yes'
SET #findScalerFunction = 'yes'
SET #findUserTable = 'yes'
SET #findTrigger = 'yes'
SET #findView = 'yes'
SET #doesNotContain = ''
SET #previewLength = 30
--------------------------------------------------------
SELECT DISTINCT
ISNULL(
(SELECT REPLACE(CONVERT(VARCHAR(20), (CAST(SUM(LEN(SC2.text)) AS MONEY)), 1), '.00', '')
FROM syscomments SC2 WHERE SC2.id = SO.id GROUP BY SC2.id)
, '')
AS [Object length]
,
SO.name AS [Object name]
,
CASE
WHEN SO.xtype = 'P' THEN 'Stored Procedure'
WHEN SO.xtype = 'TF' THEN 'Table Function'
WHEN SO.xtype = 'FN' THEN 'Scaler Function'
WHEN SO.xtype = 'U' THEN 'User Table'
WHEN SO.xtype = 'TR' THEN 'Trigger'
WHEN SO.xtype = 'V' THEN 'View'
END
+ ISNULL((SELECT ' - ' + name FROM sysobjects WHERE id = SO.parent_obj), '')
AS [Object type]
,
ISNULL(SUBSTRING(SC.text, CHARINDEX(#searchString, SC.text) - #previewLength, #previewLength) +
SUBSTRING(SC.text, CHARINDEX(#searchString, SC.text), #previewLength + LEN(#searchString))
, '') AS [Preview of code]
,
(SELECT
COALESCE(
SUM(LEN(SC3.text) - LEN(REPLACE(SC3.text, CHAR(13), '')) + 1) + 4
+
(
SELECT
(LEN(LEFT(SC4.text, CHARINDEX(#searchString, SC4.text))) -
LEN(REPLACE(LEFT(SC4.text, CHARINDEX(#searchString, SC4.text)), CHAR(13), '')))
FROM syscomments SC4
WHERE
SC4.id = SO.id
AND SC4.colid = SC.colid
)
,
SUM(LEN(SC3.text) - LEN(REPLACE(SC3.text, CHAR(13), '')) + 1) + 4
,
(
SELECT
(LEN(LEFT(SC4.text, CHARINDEX(#searchString, SC4.text))) -
LEN(REPLACE(LEFT(SC4.text, CHARINDEX(#searchString, SC4.text)), CHAR(13), '')) + 1)
FROM syscomments SC4
WHERE
SC4.id = SO.id
AND SC4.colid = SC.colid
)
)
FROM syscomments SC3
WHERE
SC3.id = SO.id
AND SC3.colid < SC.colid
)
AS [Line number]
FROM sysobjects SO
LEFT JOIN syscomments SC
ON SO.id = SC.id
WHERE
(
(SO.type = 'P' AND #findStoredProcedures = 'yes')
OR
(SO.type = 'TF' AND #findTableFunction = 'yes')
OR
(SO.type = 'FN' AND #findScalerFunction = 'yes')
OR
(SO.type = 'TR' AND #findTrigger = 'yes')
OR
(SO.type = 'U' AND #findUserTable = 'yes')
OR
(SO.type = 'V' AND #findView = 'yes')
)
AND SO.category = 0
AND
(
(CHARINDEX(#searchString, SC.text) > 0
AND CHARINDEX(#doesNotContain, SC.text) = 0)
OR
(SO.type = 'U'
AND CHARINDEX(#searchString, SO.name) > 0
AND CHARINDEX(#doesNotContain, SO.name) = 0)
)
ORDER BY
[Object type], [Object name], [Line number]
Your where clause seems to have an issue, this bit here
(
(CHARINDEX(#searchString, SC.text) > 0
AND CHARINDEX(#doesNotContain, SC.text) = 0)
--OR
--(SO.type = 'U'
--AND CHARINDEX(#searchString, SO.name) > 0
--AND CHARINDEX(#doesNotContain, SO.name) = 0)
We have a person search stored procedure in our database, which I want to map into Visual Studio 2012 in my edmx file. The stored procedure returns the rows that satisfy the search and it sets a return code. When I execute the stored procedure manually I get the 4 rows I expect and I get a return code of 0.
I am using 2012, EF 5, and Entity Framework components in the framework.
When I select the stored procedure via UpdateModelFromDatabase and add it to my project, instead of defining the usual {storedProcedureName}_Result and returning that, it is translated to return only an integer. This prevents me from using the stored procedure to actually get to the rows to display them.
Interestingly enough, we have a test PersonSearch stored procedure which happens to be broken, but it is the same stored procedure with some internal changes. It still returns the results of the search AND sets the return code. When I pull that second stored procedure in, it does as expected and creates the stored procedure as returning the {storedProcedureName}_Result and returning the rows.
Has anyone seen this issue and how do I work around this issue? I need this first stored procedure to return the rows, not the return code.
Follow Up
I came across this question and had my DBA look at it. But making similar changes to our stored procedure still has EF returning an integer instead of a complex object.
I also ran the sproc with all fields null and it returned the empty table structure in addition to the return code.
This is the stored procedure:
USE [ourdatabase]
GO
/****** Object: StoredProcedure [dbo].[usp_Person_SearchPerson] Script Date: 01/30/2013 11:46:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_Person_SearchPerson]
#firstName nvarchar(50), --OR
#lastName nvarchar(50), --OR
#companyName nvarchar(150), --OR
#phoneNumber1 nvarchar(50), --OR
#phoneNumber2 nvarchar(50), --OR
#email nvarchar(100), --OR
#franchiseSetId uniqueidentifier, --AND
#recordSourceId uniqueidentifier --AND
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ReturnTable TABLE
(
PersonID UNIQUEIDENTIFIER,
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
CompanyName NVARCHAR(150),
EmailAddress NVARCHAR(100),
PhoneNumber1 NVARCHAR(50),
PhoneNumber2 NVARCHAR(50),
Address1 NVARCHAR(50),
City NVARCHAR(100),
State NVARCHAR(50),
PostalCode NVARCHAR(20),
Score INT
)
-- flags to be used instead of calling the function udf_Strings_IsNullOrEmpty repeatedly
Declare
#firstNamebit bit, --OR
#lastNamebit bit, --OR
#companyNamebit bit, --OR
#phoneNumber1bit bit, --OR
#phoneNumber2bit bit, --OR
#emailbit bit, --OR
#franchiseSetIdbit bit, --AND
#recordSourceIdbit bit,
#rowID int
Insert into AppToolData..SearchLog
(
firstname ,
lastname ,
companyName ,
phoneNumber1 ,
phoneNumber2 ,
email ,
franchiseSetId ,
recordSourceID ,
StartTime_UTC
)
Values
(
#firstname ,
#lastname ,
#companyName ,
#phoneNumber1 ,
#phoneNumber2 ,
#email ,
#franchiseSetId ,
#recordSourceID ,
SYSDATETIMEOFFSET()
)
Select #rowID = SCOPE_IDENTITY()
-- working set to accumulate Person records meeting search criteria
--Declare #People table
Create Table #People
(
PersonID uniqueIdentifier
)
--work set of distinct person reocrds from previous working set
Declare #DistinctPeople table
(
PersonID uniqueIdentifier not null Primary Key
)
--Set flags
Select -- 0 = False (Is Not Null) 1 = True (Is Null)
#firstNamebit = dbo.udf_Strings_IsNullOrEmpty(#firstName),
#lastNamebit = dbo.udf_Strings_IsNullOrEmpty(#lastName),
#companyNamebit = dbo.udf_Strings_IsNullOrEmpty(#companyName),
#phoneNumber1bit = dbo.udf_Strings_IsNullOrEmpty(#phoneNumber1),
#phoneNumber2bit = dbo.udf_Strings_IsNullOrEmpty(#phoneNumber2),
#emailbit = dbo.udf_Strings_IsNullOrEmpty(#email)
DECLARE #MinimumWeight INT
SET #MinimumWeight = 1
DECLARE #AvailableWeight INT
SET #AvailableWeight = 0
If #franchiseSetId is not null
Begin
Select #firstName = '%'+#firstName+'%'
Select #lastName = '%'+#lastName+'%'
End
Else
Begin
Select #firstName = #firstName+'%'
Select #lastName = #lastName+'%'
End
If #franchiseSetId is null
Begin
-- first name provided, last name not provided, phone number not provided
IF #firstNamebit = 0 and #lastNamebit = 1 and #phoneNumber1bit = 1
BEGIN
SET #AvailableWeight = #AvailableWeight + 15 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where first name is a partial string match
Insert into #People
Select PersonID from Person p
Where (PatIndex(#firstName, p.FirstName)>0)
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name not provided, last name provided, phone number not provided
Else IF #firstNamebit = 1 and #lastNamebit = 0 and #phoneNumber1bit = 1
BEGIN
SET #AvailableWeight = #AvailableWeight + 20 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where last name is a partial string match
Insert into #People
Select PersonID from Person p
Where
(PatIndex(#lastName, p.lastName)>0)
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name provided, last name provided, phone number not provided
Else IF #firstNamebit = 0 and #lastNamebit = 0 and #phoneNumber1bit = 1
BEGIN
SET #AvailableWeight = #AvailableWeight + 30 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where first & last name are a partial string match
Insert into #People
Select PersonID from Person p
Where
(
(PatIndex(#firstName, p.FirstName)>0)
and
(PatIndex(#lastName, p.lastName)>0)
)
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name provided, last name not provided, phone number provided
IF #firstNamebit = 0 and #lastNamebit = 1 and #phoneNumber1bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 45 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where first name is a partial string match
-- and Phone Number is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where
(PatIndex(#firstName, p.FirstName)>0)
and
pn1.Number = #PhoneNumber1
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name not provided, last name provided, phone number provided
Else IF #firstNamebit = 1 and #lastNamebit = 0 and #phoneNumber1bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 50 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where last name is a partial string match
-- and Phone Number is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where
(PatIndex(#lastName, p.LastName)>0)
and
pn1.Number = #PhoneNumber1
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name provided, last name provided, phone number provided
Else IF #firstNamebit = 0 and #lastNamebit = 0 and #phoneNumber1bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 65 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where first & last name are a partial string match
-- and Phone Number is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where
(
(PatIndex(#firstName, p.FirstName)>0)
and
(PatIndex(#lastName, p.LastName)>0)
)
and
pn1.Number = #PhoneNumber1
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
-- first name not provided, last name not provided, phone number provided
Else IF #firstNamebit = 1 and #lastNamebit = 1 and #phoneNumber1bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 30 -- (First Name = 15, Last Name = 20, Phone Number = 30)
-- Add records where Phone Number is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where
pn1.Number = #PhoneNumber1
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
End
Else -- Indicates WORKCENTER/Drybook search
Begin
IF #firstNamebit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 15
-- Add records where first name is a partial string match
Insert into #People
Select PersonID from Person p
Where (PatIndex(#firstName, p.FirstName)>0)
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
IF #lastNamebit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 20
-- Add records where last name is a partial string match
Insert into #People
Select PersonID from Person p
Where
(PatIndex(#lastName, p.lastName)>0)
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
IF #phoneNumber1bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 30
-- Add records where Phone Number 1 is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where pn1.Number = #PhoneNumber1
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
End
IF #phoneNumber2bit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 30
-- Add records where Phone Number 2 is an exact match
Insert into #People
SELECT
p.PersonId
FROM
Person p WITH (NOLOCK)
LEFT OUTER JOIN
PersonPhoneNumber ppn1 WITH (NOLOCK)
ON p.PersonId=ppn1.PersonId
LEFT OUTER JOIN
PhoneNumber pn1 WITH (NOLOCK)
ON ppn1.PhoneNumberId=pn1.PhoneNumberId
Where pn1.Number = #PhoneNumber2
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
IF #emailbit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 40
-- Add records where Email is an exact match
Insert into #People
Select
p.PersonId
from Person p
LEFT OUTER JOIN
PersonEmailAddress pea WITH (NOLOCK)
ON p.PersonId=pea.PersonId
LEFT OUTER JOIN
EmailAddress ea WITH (NOLOCK)
ON pea.EmailAddressId=ea.EmailAddressId
Where ea.[Address] = #email
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
IF #companyNamebit = 0
BEGIN
SET #AvailableWeight = #AvailableWeight + 10
-- Add records where Company Name is an exact match
Insert into #People
Select
p.PersonId
from Person p
LEFT OUTER JOIN
Company c WITH (NOLOCK)
ON p.CompanyId=c.CompanyId
Where c.Name = #companyName
AND
(
p.RecordSourceId = Coalesce(#recordSourceId, p.RecordSourceId)
--(#recordSourceId IS NULL)
--OR
--(p.RecordSourceId = #recordSourceId)
)
AND
(
p.FranchiseSetId = Coalesce(#franchiseSetId, p.FranchiseSetId)
--(#franchiseSetId IS NULL AND p.FranchiseSetId IS NULL)
--OR
--(p.FranchiseSetId = #franchiseSetId)
)
END
If #franchiseSetId is not null
Begin
-- WORKCENTER -- do not return results that are less than a 40% match of what was passed in
SET #MinimumWeight = #AvailableWeight * 0.4
End
Else
Begin
-- ClaimsEntry -- do not return results that are less than a 60% match of what was passed in
SET #MinimumWeight = #AvailableWeight * 0.6
End
-- get list of unique records
Insert into #DistinctPeople
Select Distinct PersonID from #People order by PersonID
INSERT INTO #ReturnTable (PersonID, FirstName, LastName, CompanyName, EmailAddress, PhoneNumber1, PhoneNumber2, Score)
(
SELECT
DistinctPeople.PersonId,
p.FirstName,
p.LastName,
c.Name,
ea.[Address],
null as PhoneNumber1,
null as PhoneNumber2,
Score =
(
--first name score
(
(CASE WHEN #firstNamebit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN PatIndex(#firstName, p.FirstName)>0 THEN 1 ELSE 0 END)
*
15
)
+
--last name score
(
(CASE WHEN #lastNamebit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN PatIndex(#lastName, p.LastName)>0 THEN 1 ELSE 0 END)
*
20
)
+
--email score
(
(CASE WHEN #emailbit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN ea.[Address] = #email THEN 1 ELSE 0 END)
*
40
)
+
--company score
(
(CASE WHEN #companyNamebit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN PatIndex(#companyName, c.Name)>0 THEN 1 ELSE 0 END)
*
10
)
)
FROM
#DistinctPeople DistinctPeople
LEFT OUTER JOIN
Person p WITH (NOLOCK)
ON DistinctPeople.PersonId=p.PersonId
LEFT OUTER JOIN
PersonEmailAddress pea WITH (NOLOCK)
ON p.PersonId=pea.PersonId
LEFT OUTER JOIN
EmailAddress ea WITH (NOLOCK)
ON pea.EmailAddressId=ea.EmailAddressId
LEFT OUTER JOIN Company c WITH (NOLOCK)
ON p.CompanyId=c.CompanyId
)
--If neither Phone number was passed as a parameter, the scores will not change
-- We can get rid of records that will not be returned
If #phoneNumber1bit = 1 and #phoneNumber2bit = 1
Begin
-- update the phone number scores, the actual phone number values
-- can be in either the first or second position
UPDATE rt
SET Score = Score +
(
(CASE WHEN #phoneNumber1bit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN rt.PhoneNumber1 = #phoneNumber1 THEN 1
WHEN rt.PhoneNumber2 = #phoneNumber1 THEN 1 ELSE 0 END)
*
30
)
+
--phone 2 score
(
(CASE WHEN #phoneNumber2bit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN rt.PhoneNumber1 = #phoneNumber2 THEN 1
WHEN rt.PhoneNumber2 = #phoneNumber2 THEN 1 ELSE 0 END)
*
30
)
FROM #ReturnTable rt
-- clear out the records we no longer care about
DELETE FROM #ReturnTable WHERE Score < #MinimumWeight
End
UPDATE rt
SET rt.PhoneNumber1 =
(
select top 1 xpn1.number
from PersonPhoneNumber xppn1 WITH (NOLOCK)
LEFT OUTER JOIN
PhoneNumber xpn1 WITH (NOLOCK)
on xppn1.PhoneNumberId =xpn1.PhoneNumberId
where xppn1.PersonId = rt.PersonID
order by (CASE
WHEN xpn1.Number = #phoneNumber1 then -999
else xppn1.SequenceNumber
end )
)
FROM #ReturnTable rt
UPDATE rt
SET rt.PhoneNumber2 =
(
select top 1 xpn1.number from PersonPhoneNumber xppn1 WITH (NOLOCK)
LEFT OUTER JOIN PhoneNumber xpn1 WITH (NOLOCK) on xppn1.PhoneNumberId =xpn1.PhoneNumberId
where xppn1.PersonId = rt.PersonID
and rt.PhoneNumber1 != xpn1.Number
order by (CASE
WHEN xpn1.Number = #phoneNumber2 then -998
else xppn1.SequenceNumber end )
)
FROM #ReturnTable rt
-- update the phone number scores, the actual phone number values can be in either the first or second position
UPDATE rt
SET Score = Score +
(
(CASE WHEN #phoneNumber1bit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN rt.PhoneNumber1 = #phoneNumber1 THEN 1
WHEN rt.PhoneNumber2 = #phoneNumber1 THEN 1 ELSE 0 END)
*
30
)
+
--phone 2 score
(
(CASE WHEN #phoneNumber2bit = 0 THEN 1 ELSE 0 END)
*
(CASE WHEN rt.PhoneNumber1 = #phoneNumber2 THEN 1
WHEN rt.PhoneNumber2 = #phoneNumber2 THEN 1 ELSE 0 END)
*
30
)
FROM #ReturnTable rt
-- clear out the records we no longer care about
DELETE FROM #ReturnTable WHERE Score < #MinimumWeight
UPDATE rt
SET Address1 = a.Address1,
City = a.City,
State = s.Abbreviation,
PostalCode = a.PostalCode
FROM #ReturnTable rt
OUTER APPLY
(
SELECT TOP 1 *
FROM PersonAddress pa WITH (NOLOCK)
WHERE pa.PersonId = rt.PersonID
ORDER BY pa.SequenceNumber
) ppa
LEFT JOIN Address a WITH (NOLOCK) on ppa.AddressId = a.AddressId
LEFT JOIN State s WITH (NOLOCK) on a.StateId = s.StateId
Update AppToolData..SearchLog
Set EndTime_UTC = SYSDATETIMEOFFSET()
Where rowid = #rowid
-- return only those that meet the minimum score/weight requirements
Delete FROM #ReturnTable WHERE Score < #MinimumWeight
SELECT * FROM #ReturnTable
--order by Score Desc
END
Based on information from cadrell0 and our own tests we found the following:
A stored procedure that is generating a table and returning rows from that table are doing this only at runtime. When called by Entity Framework with fmtonly it throws an error because the runtime object is not created.
We added FMTONLY OFF to our stored procedure which allowed Entity Framework to see the format of the table and, thus, the format for the complex object.
This allowed me to add the stored procedure, get the correct returned object, and now I'm able to use the sproc to execute our search on the database side of the fence.
This was important to us as the original code is using this and our code HAD to use it.