从发送到链接服务器并由存储过程返回的查询中检索结果表

时间:2019-07-02 13:44:39

标签: sql-server

我有一个包含数据的链接服务器。单独调用每个表花费的时间太长,因此唯一的选择是使用OpenQuery。麻烦的是,我需要将参数传递给查询。

OpenQuery不支持参数,这意味着必须通过Exec以及其中包含完整命令的字符串来完成。我还需要使用C#编写的客户端应用程序。

我可以在C#中构建字符串并传递该字符串,但是我试图使应用程序在涉及数据源时不可知,因此希望避免在应用程序中嵌入SQL。

存储过程的代码是

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

1 个答案:

答案 0 :(得分:1)

您与SQL关系密切。您不会RETURN使用存储过程的数据集。 RETURN通常用于返回SP的成功结果; 0表示成功,其他则表示没有成功(这就是Microsoft SP的工作方式)。您只需要执行动态语句即可。

我对SQL进行了一些更改,并通过使用varchar(10)停止了注入(尽管对于QUOTENAME来说非常困难),并且将数据类型更改为对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;
相关问题