Reputation: 832
I have a linked server which contains data. Calling each table separately takes too long so the only choice is to use OpenQuery. The wrinkle being that I need to pass a parameter to the query.
OpenQuery does not support parameters meaning it has to be done via Exec and a string built up with the full command in it. I also need to client application written in C#.
I could build the string in C# and pass that but I am trying to make the application agnostic when it comes to the data source so want to avoid having SQL embedded in the application.
Code to the stored procedure is
ALTER PROCEDURE [dbo].[Get_Patient_By_MRN] ( @MRN VarChar(10) )
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare @Patient_Sql VarChar(768) =
'
SELECT * FROM OPENQUERY([CERNER_APP_DB_PROD],''
Select P.PERSON_ID
, PA1.ALIAS AS MRN
, PA2.ALIAS AS NHS_Number
, P.NAME_LAST_KEY
, P.NAME_FIRST_KEY
, P.NAME_FULL_FORMATTED
, P.BIRTH_DT_TM
From V500.PERSON P LEFT JOIN V500.PERSON_ALIAS PA1
ON PA1.PERSON_ID = P.PERSON_ID AND
PA1.PERSON_ALIAS_TYPE_CD = 10
LEFT JOIN V500.PERSON_ALIAS PA2
ON PA2.PERSON_ID = P.PERSON_ID AND
PA2.PERSON_ALIAS_TYPE_CD = 18
Where PA1.ALIAS = ''''' + @MRN + '''''
'')
'
Return Exec @Patient_Sql
END
Upvotes: 0
Views: 371
Reputation: 95689
You were close with your SQL. You don't RETURN
a dataset with a Stored procedure. RETURN
is normally used to return the success result of an SP; 0 means succes, anything else means it didn't (this is how the Microsoft SP's work). What you need to do here is simply execute your dynamic statement.
I've changed the SQL a little bit, and stopped injection (although very hard with a varchar(10)
) by using QUOTENAME
, and changed the datatype to be correct for sp_executesql
:
ALTER PROCEDURE [dbo].[Get_Patient_By_MRN] (@MRN varchar(10))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Patient_Sql nvarchar(MAX) = '
SELECT * FROM OPENQUERY([CERNER_APP_DB_PROD],''
Select P.PERSON_ID
, PA1.ALIAS AS MRN
, PA2.ALIAS AS NHS_Number
, P.NAME_LAST_KEY
, P.NAME_FIRST_KEY
, P.NAME_FULL_FORMATTED
, P.BIRTH_DT_TM
From V500.PERSON P LEFT JOIN V500.PERSON_ALIAS PA1
ON PA1.PERSON_ID = P.PERSON_ID AND
PA1.PERSON_ALIAS_TYPE_CD = 10
LEFT JOIN V500.PERSON_ALIAS PA2
ON PA2.PERSON_ID = P.PERSON_ID AND
PA2.PERSON_ALIAS_TYPE_CD = 18
Where PA1.ALIAS = ' + QUOTENAME(@MRN,'''') + ');';
EXEC sp_executesql @Patient_Sql;
END;
Upvotes: 1