Sql server 用于组合来自OpenQuery的输出结果的SQL Server存储过程

Sql server 用于组合来自OpenQuery的输出结果的SQL Server存储过程,sql-server,stored-procedures,Sql Server,Stored Procedures,这是我的第一篇文章。希望能在我的代码方面得到一些帮助 我正在尝试编写一个存储过程,以合并来自两个打开的查询的结果,每个查询都指向不同的链接服务器 存储过程接受一个参数 第一个OPENQUERY返回多行Col1、Col2、Col3、Col4 我想将Col1的结果传递给第二个OPENQUERY,后者返回Col1、Col5、Col6,然后将结果合并到一个表变量中进行读取 我不能在这里粘贴精确的查询,但会粘贴结构。希望这有助于理解我目前的做法。如果我能得到一些建议,我将不胜感激 这适用于1个输入,但当我

这是我的第一篇文章。希望能在我的代码方面得到一些帮助

我正在尝试编写一个存储过程,以合并来自两个打开的查询的结果,每个查询都指向不同的链接服务器

存储过程接受一个参数

第一个
OPENQUERY
返回多行
Col1、Col2、Col3、Col4

我想将
Col1
的结果传递给第二个
OPENQUERY
,后者返回
Col1、Col5、Col6
,然后将结果合并到一个表变量中进行读取

我不能在这里粘贴精确的查询,但会粘贴结构。希望这有助于理解我目前的做法。如果我能得到一些建议,我将不胜感激

这适用于1个输入,但当我传递多个输入时,显然会失败。如何处理第一次查询的结果并将其传递到第二次查询

ALTER PROCEDURE [dbo].[MyStoredProc] 
    @Input AS NVARCHAR(MAX)
AS
    BEGIN TRY
        SET NOCOUNT ON;

        DECLARE @TSQL1 NVARCHAR(MAX)
        DECLARE @TSQL2 NVARCHAR(MAX)
        DECLARE @Col1Results NVARCHAR(MAX)

        /*** OpenQuery 1***/
        SELECT  @TSQL1 = 'SELECT Col1, Col2, Col3, Col4 FROM Table1
                          WHERE Input IN ('''+ @Input +''') '

        DECLARE @tblTempTable1 AS TABLE 
                                  (
                                      Col1 NVARCHAR(100),
                                      Col2 NVARCHAR(100),
                                      Col3 NVARCHAR(50),
                                      Col4 NVARCHAR(50)
                                  )

        INSERT INTO @tblTempTable1 
            EXEC (@TSQL1) AT [LinkedServer1]

        SELECT @Col1Results = Col1 
        FROM @tblTempTable1 

        /*** Open Query 2***/
        SELECT  @TSQL2 = 'SELECT Col1, Col5, Col6 FROM Table2
                          WHERE Input IN ('''+ @Col1Results +''') '

        DECLARE @tblTempTable2 AS TABLE 
                                  (
                                       Col1 NVARCHAR(100),
                                       Col5 NVARCHAR(100),
                                       Col6 NVARCHAR(50)
                                  )

        INSERT INTO @tblTempTable2 
            EXEC (@TSQL2) AT [LinkedServer2]

        SELECT 
            t1.Col1, t1.Col2, t1.Col3, t2.Col2, t2.Col3
        FROM
            @tblTempTable1 t1
        INNER JOIN
            @tblTempTable2 t2 ON t1.Col1 = t2.Col1
    END TRY
    BEGIN CATCH
    END CATCH
------------------------------------更新-----------------

我能够使用游标来实现期望的结果。但是注意到,使用游标在很大程度上影响了性能。能否进一步优化以下代码以提高性能。谢谢


    ALTER PROCEDURE [dbo].[MyStoredProc] 
    @Input AS NVARCHAR(MAX) AS
    BEGIN TRY
    SET NOCOUNT ON;


Declare @tblTempTable1 Table
            (
                Col1 Nvarchar(100),
                Col2 Nvarchar(100),
                Col3 nvarchar(50),
                Col4 nvarchar(50)
            )

SELECT  @TSQL1 = 'Select Col1,Col2,Col3,Col4 From Table1
              where Input in ('''+@Input+''')'

Insert @tblTempTable1 EXEC (@TSQL1) at [LinkedServer1]

Declare @tblTempTable2 Table
            (
                Col1 Nvarchar(100),
            Col2 Nvarchar(100),
                Col3 nvarchar(50)
        )

Declare db_cursor CURSOR for 
Select Col1 from @tblTempVTErrors

Open db_cursor
fetch NEXT FROM db_cursor into @Column1

While @@FETCH_STATUS=0
Begin


SELECT  @TSQL2 = 'Select Col1,Col5,Col6 From Table2
              where Col1 in ('''+@Column1+''')'

Insert @tblTempTable2 EXEC (@TSQL2) at [LinkedServer2]

FETCH NEXT FROM db_cursor INTO @Column1


End

Close db_Cursor
Deallocate db_Cursor


    Select t1.Col1,t1.Col2,t1.Col3,t2.Col2,t2.Col3
    from @tblTempTable1 t1
    inner join @tblTempTable2 t2 on t1.Col1=t2.Col1

END TRY
BEGIN CATCH
END CATCH

如果我理解正确的话,当输入是单个值时,比如说“Test”,那么它就工作了,因为只选择了一条记录——输入是某种唯一标识符。但一旦通过“Test”、“Test2”和“Test3”,它就会失败,因为它将多个记录放入@tblTempTable1,然后选择@Col1Results将失败,因为选择了多个记录

如果是这样,那么您需要执行以下操作:

创建一个函数,允许您拆分此类输入参数。我使用:

create FUNCTION [dbo].[fnSplit](
    @sInputList VARCHAR(max) -- List of delimited items
  , @sDelimiter VARCHAR(5) -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(max))

BEGIN
DECLARE @sItem VARCHAR(max)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END

你能分享一些关于这部分的例子吗:
这适用于1个输入,但当我传递多个输入时显然失败了
我们是否理解输入是唯一的标识符?谢谢你调查我的问题。我使用VBA从excel报表调用此存储过程。最初,这两个开放查询是两个独立的存储过程,它们工作得很好。现在,我尝试将输出合并到一个报告中。我正在从Excel传递逗号分隔的输入,如Input1、Input2、Input3。。。希望这有助于进一步添加,如果我传递输入1并运行该过程,我将获得上次Select查询返回的所有列。但是如果我通过输入1,输入2,它就会失败。我猜我在这一部分处理结果不正确。。。从@tbltemptable1中选择@Col1Results=Col1如果需要通过参数传入多个值,请查看SQL Server 2008及更新版本中提供的表值参数功能。这将允许您避免使用动态SQL,并使事情变得更简单……谢谢Jonathan。我会试试你的建议,看看效果如何。感谢您的快速回复,没问题。如果您需要任何帮助,请随时与我联系。您可以编辑您的查询以包括使用链接服务器时的外观。我尝试了几次,但可能使用了错误的语法。我使用的查询不是到SQL server,而是到使用链接服务器的外部系统,正如我在上面的代码中使用的那样。链接服务器的正常语法是SELECT。。。从…起例如DatabaseServer1.db1.dbo.table1
ALTER PROCEDURE MyStoredProc @Input as NVARCHAR(Max)
AS
    BEGIN TRY
    SET NOCOUNT ON;


    Declare @tblTempTable1 Table
    (
    Col1 Nvarchar(100),
    Col2 Nvarchar(100),
    Col3 nvarchar(50),
    Col4 nvarchar(50)

    )

    insert INTO @tblTempTable1 
    Select Col1,Col2,Col3,Col4 From Table1
    where Input in (SELECT Item FROM dbo.fnSplit(@Input, ','))

    Declare @tblTempTable2 Table
    (
    Col1 Nvarchar(100),
    Col2 Nvarchar(100),
    Col3 nvarchar(50)
    )

    insert INTO @tblTempTable2
    Select Col1,Col5,Col6 From Table2
    where Input in (SELECT Col1 FROM @tblTempTable1)

    Select t1.Col1,t1.Col2,t1.Col3,t2.Col2,t2.Col3
    from @tblTempTable1 t1
    inner join @tblTempTable2 t2 on t1.Col1=t2.Col1
END TRY
BEGIN CATCH
END CATCH