passing multiple varchar values to parameter in procedure [duplicate] - sql

This question already has answers here:
Passing an array of parameters to a stored procedure
(11 answers)
Closed 8 years ago.
sp_panelistid1 '585','201401','108972',''4','5''
alter procedure sp_panelistid1
(
#branch int,
#yearweak int,
#id int ,
#branchid varchar(10))
as
print #branchid
select f.lydelse as QuestionText, f.id as QuestionID, i.artal as Year, i.vecka as Week, i.id as Intervjuperson,
b.beskrivning as Branch, b.id as BranchID, v.beskrivning as Brand, v.id as BrandID, s.regperson as Buss, f.land as CountryID
, vi.NepaVikt as Weight , cp.CintPanelistId
from fraga f
inner join svar s on s.fraga = f.id
inner join bransch b on b.id = f.bransch
inner join varumarke v on v.id = s.varumarke
inner join intervjuperson i on i.id = s.intervjuperson
inner join vikt vi ON f.Bransch = vi.Bransch AND s.Intervjuperson = vi.Intervjuperson
inner join CintPanelistIntervjuperson cp on s.Intervjuperson=cp.Intervjuperson
where f.bransch = #branch
and (100*i.artal)+i.vecka > #yearweak
and f.land = 1 and f.id=#id
and v.beskrivning in (#branchid)
I need to pass multiple values in #branch id how do I pass parameters such that it works in 'IN condition ' like v.beskrivning in ('4','5','6','7 = Stämmer helt')

If you pass comma separated ids like this - '1, 2, 3' and if you want to use with "In" clause then you have to use Split() function. like this -
SELECT f.lydelse AS QuestionText
,f.id AS QuestionID
,i.artal AS Year
,i.vecka AS Week
,i.id AS Intervjuperson
,b.beskrivning AS Branch
,b.id AS BranchID
,v.beskrivning AS Brand
,v.id AS BrandID
,s.regperson AS Buss
,f.land AS CountryID
,vi.NepaVikt AS Weight
,cp.CintPanelistId
FROM fraga f
INNER JOIN svar s ON s.fraga = f.id
INNER JOIN bransch b ON b.id = f.bransch
INNER JOIN varumarke v ON v.id = s.varumarke
INNER JOIN intervjuperson i ON i.id = s.intervjuperson
INNER JOIN vikt vi ON f.Bransch = vi.Bransch
AND s.Intervjuperson = vi.Intervjuperson
INNER JOIN CintPanelistIntervjuperson cp ON s.Intervjuperson = cp.Intervjuperson
WHERE f.bransch = #branch
AND (100 * i.artal) + i.vecka > #yearweak
AND f.land = 1
AND f.id = #id
AND v.beskrivning IN (SELECT items FROM dbo.split(#branchid, ','))
Note: Split function is not in-built function. Its used defined table-valued function.
and here is the split function.
and here is the function.
CREATE FUNCTION [dbo].[Split] (
#String NVARCHAR(4000)
,#Delimiter CHAR(1)
)
RETURNS #Results TABLE (Items NVARCHAR(4000))
AS
BEGIN
DECLARE #INDEX INT
DECLARE #SLICE NVARCHAR(4000)
-- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
SELECT #INDEX = 1
IF #String IS NULL
RETURN
WHILE #INDEX != 0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT #INDEX = CHARINDEX(#Delimiter, #STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF #INDEX != 0
SELECT #SLICE = LEFT(#STRING, #INDEX - 1)
ELSE
SELECT #SLICE = #STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO #Results (Items)
VALUES (#SLICE)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT #STRING = RIGHT(#STRING, LEN(#STRING) - #INDEX)
-- BREAK OUT IF WE ARE DONE
IF LEN(#STRING) = 0
BREAK
END
RETURN
END

Related

Outer apply with INSERT statement

I want to do something like this
CREATE TABLE #tempFacilitiesAssociated
(
FacilityID BIGINT,
FacilityName VARCHAR(MAX),
IsPrimary BIT
)
-- Insert statements for procedure here
;WITH CTE_RESULT AS
(
SELECT
usr_id, t.name AS Title,
usr_fname, usr_lname, primaryAddress.add_suburb,
CASE
WHEN primaryAddress.add_suburb = #suburb THEN 1
WHEN t.name = #Title THEN 2
ELSE 3
END AS MatchOrder
FROM
core_users u
LEFT JOIN
RIDE_ct_title t ON t.title_id = u.usr_title
OUTER APPLY
(INSERT INTO #tempFacilitiesAssociated
EXEC dbo.[sp_Common_Get_AllFacilitiesForSupervisor] usr_id, 5
SELECT TOP 1 fa.*
FROM CORE_Facilities f
LEFT JOIN CORE_FacilityAddresses fa ON fac_id = fa.add_owner
WHERE fac_id = (SELECT TOP 1 FacilityID
FROM #tempFacilitiesAssociated
WHERE IsPrimary = 1)) primaryAddress
WHERE
u.usr_fname = #FirstName AND usr_lname = #LastName
)
So, first I want to get all facilities of that user through a stored procedure, and then use it to outer apply and select its suburb
UPDATE
I tried using function instead
CREATE FUNCTION fn_GetAddressForUserFacility
(#UserID BIGINT)
RETURNS #Address TABLE (FacilityID BIGINT,
add_address NVARCHAR(MAX),
add_addressline2 NVARCHAR(MAX),
add_suburb NVARCHAR(MAX)
)
AS
BEGIN
DECLARE #FacilitiesAssociated TABLE
(FacilityID BIGINT,
FacilityName NVARCHAR(MAX),
IsPrimary BIT)
INSERT INTO #FacilitiesAssociated
EXEC dbo.[sp_Common_Get_AllFacilitiesForSupervisor] #UserID, 5
INSERT INTO #Address
SELECT TOP 1
fa.add_owner, fa.add_address, fa.add_addressline2, fa.add_suburb
FROM
CORE_Facilities f
LEFT JOIN
CORE_FacilityAddresses fa ON f.fac_id = fa.add_owner AND add_type = 5
WHERE
fac_id = (SELECT TOP 1 FacilityID
FROM #FacilitiesAssociated
WHERE IsPrimary = 1)
RETURN
END
But now its returning
Invalid use of a side-effecting operator 'INSERT EXEC' within a function.

Returning column with count of 0

I have a query that looks up a list of documents depending on their department and their status.
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.name,
COUNT(*) AS TodayCount
FROM dbo.TableA ILDP
LEFT JOIN dbo.TableB ILDPS ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
LEFT JOIN dbo.TableC ILDPST ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
WHERE (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
AND ILDPS.CurrentStateTypeId IN (
SELECT value
FROM dbo.StringAsIntTable(#StatusIds)
)
GROUP BY ILDPST.name;
This returns the results:
However, I'd also like to be able to return statuses where the TodayCount is equal to 0 (i.e. any status with an id included in #StatusIds should be returned, regardless of TodayCount).
I've tried messing with some unions / joins / ctes but I couldn't quite get it to work. I'm not much of an SQL person so not sure what else to provide that could be useful.
Thanks!
If you want to have all the records from TableC you need to left join all other tables to it, not left join it to the other tables. Also it's best to INNER JOIN the filtering table you create from #StatusIds rather then apply it through INclause. Try this:
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.Name, COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM (SELECT DISTINCT value FROM dbo.StringAsIntTable(#StatusIds)) StatusIds
INNER JOIN dbo.TableC ILDPST
ON ILDPST.IntranetLoanDealPreStateTypeId = StatusIds.value
LEFT JOIN dbo.TableB ILDPS
ON ILDPS.CurrentStateTypeId = ILDPST.IntranetLoanDealPreStateTypeId
LEFT JOIN dbo.TableA ILDP
ON ILDP.IntranetLoanDealPreStateId = ILDPS.IntranetLoanDealPreStateId
AND (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
GROUP BY ILDPST.Name;
Try this instead:
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.name,
COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM
dbo.TableC ILDPST
LEFT JOIN
dbo.TableB ILDPS ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
LEFT JOIN
dbo.TableA ILDP ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
AND (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
WHERE
ILDPST.IntranetLoanDealPreStateTypeId
IN (
SELECT value
FROM dbo.StringAsIntTable(#StatusIds)
)
GROUP BY ILDPST.name;
You could use the following function to create a table value for your status id's.
CREATE FUNCTION [dbo].[SplitString]
(
#myString varchar(max),
#deliminator varchar(2)
)
RETURNS
#ReturnTable TABLE
(
[Part] [varchar](max) NULL
)
AS
BEGIN
Declare #iSpaces int
Declare #part varchar(max)
--initialize spaces
Select #iSpaces = charindex(#deliminator,#myString,0)
While #iSpaces > 0
Begin
Select #part = substring(#myString,0,charindex(#deliminator,#myString,0))
Insert Into #ReturnTable(Part)
Select #part
Select #myString = substring(#mystring,charindex(#deliminator,#myString,0)+ len(#deliminator),len(#myString) - charindex(' ',#myString,0))
Select #iSpaces = charindex(#deliminator,#myString,0)
end
If len(#myString) > 0
Insert Into #ReturnTable
Select #myString
RETURN
END
This can now be used as a table that you can LEFT JOIN to.
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
SELECT * FROM dbo.SplitString(#StatusIds, ',')
It is not tested but give it a try:
;With Cte ( Value ) As
( Select Distinct Value From dbo.StringAsIntTable( #StatusIds ) )
Select
ILDPST.name,
COUNT(*) AS TodayCount
From
dbo.TableC As ILDPST
Inner Join Cte On ( ILDPST.IntranetLoanDealPreStateTypeId = Cte.Value )
Left Join dbo.TableB As ILDPS On ( ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId )
Left Join dbo.TableA As ILDP On ( ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId )
And ( ( ILDP.CreatedByDepartmentId = #DepartmentId ) Or ( #DepartmentId Is Null ) )
Group By
ILDPST.name

Changing SQL Stored Procedure for multiple search results

I have some inherited code I need to modify in order to accommodate multiple #ParentFolderID parameter. At present, one ID is passed in. However I will now need to account for several ID's being passed in and returning results from each. Below is the current code. I'm not quite sure what exactly where I would start.
declare #Values xml
declare #ValueAttributeID int
declare #YearAttributeID int
declare #CategoryID int
declare #year int
declare #ParentFolderID int
declare #DealerAttributeID int
set #ParentFolderID = 10646615
set #CategoryID = 10646175
set #YearAttributeID = 3
set #ValueAttributeID = 2
set #year = 2014
set #Values = '<values><value id=''1000104'' /></values>'
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
with Parents
(
dataid
)
as
(
select #ParentFolderID
Union
select child.dataid
from DTree parent (NOLOCK)
inner join DTree child (NOLOCK)
on parent.dataid = child.parentid
where parent.dataid = #ParentFolderID
and child.subtype = 0
)
select doc.name as '#name',
doc.dataId as '#id',
(
select allAtts.AttrID as '#id',
case when ((allAtts.ValInt is null) and (allAtts.ValStr is null))
then cast(allAtts.ValDate as nvarchar(255))
when (allAtts.ValInt is null and allAtts.ValDate is null)
then cast(allAtts.ValStr as nvarchar(255))
when (allAtts.ValDate is null and allAtts.ValStr is null)
then cast(allAtts.ValInt as nvarchar(255))
end as '#val'
from LLAttrData allAtts (NOLOCK)
where allAtts.id = doc.dataid
for xml path('attribute'), TYPE
)
from DTree category (NOLOCK)
inner join LLAttrData value (NOLOCK)
on category.dataid = value.defid
--Changes per environment (value attribute)
and value.AttrID = #ValueAttributeID
--Check for values
inner join #Values.nodes('//value') as A(att)
on A.att.value('#id', 'nvarchar(255)') = value.ValStr
--Changes per environment (year attribute)
inner join LLAttrData y (NOLOCK)
on category.dataid = y.defid
--Changes per environment (year attribute)
and y.AttrID = #YearAttributeID
--Check for year
and year(y.valDate) = #year
inner join DTree doc (NOLOCK)
on value.id = doc.dataid
and y.id = doc.dataid
inner join Parents parent
on parent.dataid = doc.parentid
--Must be associated to the category
where category.dataid = #CategoryID -- This is the hard coded category ID
order by doc.dataid --, allAtts.AttrID
FOR XML PATH('document'), Root('documents')`

Convert Comma Delimited String to bigint in SQL Server

I have a varchar string of delimited numbers separated by commas that I want to use in my SQL script but I need to compare with a bigint field in the database. Need to know to convert it:
DECLARE #RegionID varchar(200) = null
SET #RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
SELECT a.ClassAdID, -- 1
a.AdURL, -- 2
a.AdTitle, -- 3
a.ClassAdCatID, -- 4
b.ClassAdCat, -- 5
a.Img1, -- 6
a.AdText, -- 7
a.MemberID, -- 9
a.Viewed, -- 10
c.Domain, -- 11
a.CreateDate -- 12
FROM ClassAd a
INNER JOIN ClassAdCat b ON b.ClassAdCAtID = a.ClassAdCAtID
INNER JOIN Region c ON c.RegionID = a.RegionID
AND a.PostType = 'CPN'
AND DATEDIFF(d, GETDATE(), ExpirationDate) >= 0
AND a.RegionID IN (#RegionID)
AND Viewable = 'Y'
This fails with the following error:
Error converting data type varchar to bigint.
RegionID In the database is a bigint field.. need to convert the varchar to bigint.. any ideas..?
Many thanks in advance,
neojakey
create this function:
CREATE function [dbo].[f_split]
(
#param nvarchar(max),
#delimiter char(1)
)
returns #t table (val nvarchar(max), seq int)
as
begin
set #param += #delimiter
;with a as
(
select cast(1 as bigint) f, charindex(#delimiter, #param) t, 1 seq
union all
select t + 1, charindex(#delimiter, #param, t + 1), seq + 1
from a
where charindex(#delimiter, #param, t + 1) > 0
)
insert #t
select substring(#param, f, t - f), seq from a
option (maxrecursion 0)
return
end
change this part:
AND a.RegionID IN (select val from dbo.f_split(#regionID, ','))
Change this for better overall performance:
AND DATEDIFF(d, 0, GETDATE()) <= ExpirationDate
Your query does not know that those are separate values, you can use dynamic sql for this:
DECLARE #RegionID varchar(200) = null
SET #RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
declare #sql nvarchar(Max)
set #sql = 'SELECT a.ClassAdID, -- 1
a.AdURL, -- 2
a.AdTitle, -- 3
a.ClassAdCatID, -- 4
b.ClassAdCat, -- 5
a.Img1, -- 6
a.AdText, -- 7
a.MemberID, -- 9
a.Viewed, -- 10
c.Domain, -- 11
a.CreateDate -- 12
FROM ClassAd a
INNER JOIN ClassAdCat b ON b.ClassAdCAtID = a.ClassAdCAtID
INNER JOIN Region c ON c.RegionID = a.RegionID
AND a.PostType = ''CPN''
AND DATEDIFF(d, GETDATE(), ExpirationDate) >= 0
AND a.RegionID IN ('+#RegionID+')
AND Viewable = ''Y'''
exec sp_executesql #sql
I use this apporach sometimes and find it very good.
It transfors your comma-separated string into an AUX table (called #ARRAY) and then query the main table based on the AUX table:
declare #RegionID varchar(50)
SET #RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
declare #S varchar(20)
if LEN(#RegionID) > 0 SET #RegionID = #RegionID + ','
CREATE TABLE #ARRAY(region_ID VARCHAR(20))
WHILE LEN(#RegionID) > 0 BEGIN
SELECT #S = LTRIM(SUBSTRING(#RegionID, 1, CHARINDEX(',', #RegionID) - 1))
INSERT INTO #ARRAY (region_ID) VALUES (#S)
SELECT #RegionID = SUBSTRING(#RegionID, CHARINDEX(',', #RegionID) + 1, LEN(#RegionID))
END
select * from your_table
where regionID IN (select region_ID from #ARRAY)
It avoids you from ahving to concatenate the query string and then use EXEC to execute it, which I dont think it is a very good approach.
if you need to run the code twice you will need to drop the temp table
I think the answer should be kept simple.
Try using CHARINDEX like this:
DECLARE #RegionID VARCHAR(200) = NULL
SET #RegionID =
'853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
SELECT 1
WHERE Charindex('834', #RegionID) > 0
SELECT 1
WHERE Charindex('999', #RegionID) > 0
When CHARINDEX finds the value in the large string variable, it will return it's position, otherwise it return 0.
Use this as a search tool.
The easiest way to change this query is to replace the IN function with a string function. Here is what I consider the safest approach using LIKE (which is portable among databases):
AND ','+#RegionID+',' like '%,'+cast(a.RegionID as varchar(255))+',%'
Or CHARINDEX:
AND charindex(','+cast(a.RegionID as varchar(255))+',', ','+#RegionID+',') > 0
However, if you are explicitly putting the list in your code, why not use a temporary table?
declare #RegionIds table (RegionId int);
insert into #RegionIds
select 853 union all
select 834 union all
. . .
select 303
Then you can use the table in the IN clause:
AND a.RegionId in (select RegionId from #RegionIds)
or in a JOIN clause.
I like Diego's answer some, but I think my modification is a little better because you are declaring a table variable and not creating an actual table. I know the "in" statement can be a little slow, so I did an inner join since I needed some info from the Company table anyway.
declare #companyIdList varchar(1000)
set #companyIdList = '1,2,3'
if LEN(#companyIdList) > 0 SET #companyIdList = #companyIdList + ','
declare #CompanyIds TABLE (CompanyId bigint)
declare #S varchar(20)
WHILE LEN(#companyIdList) > 0 BEGIN
SELECT #S = LTRIM(SUBSTRING(#companyIdList, 1, CHARINDEX(',', #companyIdList) - 1))
INSERT INTO #CompanyIds (CompanyId) VALUES (#S)
SELECT #companyIdList = SUBSTRING(#companyIdList, CHARINDEX(',', #companyIdList) + 1, LEN(#companyIdList))
END
select d.Id, d.Name, c.Id, c.Name
from [Division] d
inner join [Company] c on d.CompanyId = c.Id
inner join #CompanyIds cids on c.Id = cids.CompanyId

calling a udf in listing of values in a select

i have a list of items i am selecting and want to also include a few values from a UDF mixed in.
I am pulling names of people in various roles of a project management system.
where there is a name i want to get its initials, so i want to use the Abbreviate UDF mixed in the select to fn_ProjectStakeholders such that it will return names and initials along side names as its result.
see the section:
ExecutiveChampion NVARCHAR(500),
-- Abbreviate (ExecutiveChampion) as ExecutiveChampionInit,
BusinessOwner NVARCHAR(500),
-- Abbreviate (BusinessOwner) as BusinessOwnerInit,
here is my code:
CREATE FUNCTION [dbo].[fn_ProjectStakeholders]
(
#ProjectListCSV VARCHAR(8000)
)
RETURNS #TableOfValues TABLE
(
ProjectId INT,
ExecutiveChampion NVARCHAR(500),
-- Abbreviate (ExecutiveChampion) as ExecutiveChampionInit,
BusinessOwner NVARCHAR(500),
-- Abbreviate (BusinessOwner) as BusinessOwnerInit,
BusinessAnalyst NVARCHAR(500),
GeneralContractor NVARCHAR(500),
PrimaryPM NVARCHAR(500),
DevelopmentManager NVARCHAR(500),
DevelopmentLead NVARCHAR(500),
TDM NVARCHAR(500),
PTM NVARCHAR(500)
)
AS
BEGIN
DECLARE #pList TABLE (pk INT IDENTITY(1,1),ProjectId INT)
INSERT INTO #pList (ProjectId) SELECT Value FROM Split(',', #ProjectListCSV)
INSERT INTO #TableOfValues
SELECT ProjectId,
ISNULL([95],'n/a') ExecutiveChampion,
ISNULL([96],'n/a') BusinessOwner,
ISNULL([97],'n/a') BusinessAnalyst,
ISNULL([100],'n/a') GeneralContractor,
ISNULL([101],'n/a') PrimaryPM,
ISNULL([102],'n/a') DevelopmentManager,
ISNULL([103],'n/a') DevelopmentLead,
ISNULL([104],'n/a') TDM,
ISNULL([105],'n/a') PTM
FROM (
SELECT pl.ProjectId, StakeholderCID, FullName
FROM #pList pl
INNER JOIN StatusCode sc ON 1 = 1 AND SCID IN (8, 9)
LEFT JOIN ProjectStakeholder ps ON pl.ProjectId = ps.ProjectId AND sc.CID = ps.StakeholderCID
) AS ST
PIVOT
(MAX(FullName) FOR StakeholderCID IN ([95], [96], [97], [100], [101], [102], [103], [104], [105])) AS PT
RETURN
END
CREATE FUNCTION dbo.Abbreviate ( #InputString varchar(1000) )
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE #Index INT
DECLARE #OutputString VARCHAR(100)
SET #InputString = LTRIM(#InputString)
SET #OutputString = UPPER(LEFT(#InputString, 1))
SET #Index = CHARINDEX(' ', #InputString) + 1
WHILE #Index > 1
BEGIN
SET #OutputString = #OutputString + UPPER(SUBSTRING(#InputString, #Index, 1))
SET #Index = CHARINDEX(' ', #InputString, #Index) + 1
END
RETURN #OutputString
END
answer inspired by this question
my resulting code is thus:
select
--p.parentprojectid,
pp.ProjectName as ParentProjectName,
p.ProjectName as ProjectName,
p.ClarityId,
R.Name as releaseName,
CASE WHEN PSH.GeneralContractor = 'Jeff Jablonski' THEN 'Y' ELSE 'N' END as 'GC',
-- cg initials
PSH.GeneralContractor,
dbo.Abbreviate(PSH.GeneralContractor),
p.CaseManagerBenId,
P.Budget,
PSH.BusinessOwner,
PSH.DevelopmentLead ,
PSH.PrimaryPM,
PSH.DevelopmentManager,
-- SA ?!?!!?
scs.CodeName as latestStatus
-- 6x true/ false status for link types (with sanity check)
from project p
left outer join project pp on pp.projectid = p.parentprojectid
inner join Release R on R.ReleaseID = P.ReleaseID
LEFT OUTER JOIN ProjectStatus ps ON ps.ProjectId = p.ProjectId
AND ps.LastUpdate = (SELECT MAX(LastUpdate)
FROM ProjectStatus ips
WHERE ips.ProjectId = p.ProjectId)
LEFT OUTER JOIN StatusCode scs ON scs.CID = ps.RAGStatusCID
Left OUTER JOIN fn_ProjectStakeholders ('25,66,97') as PSH ON PSH.projectId = p.ProjectId
where p.projectId in (25,66,97)