【问题标题】:How can I pass xml data from one sproc to another?如何将 xml 数据从一个 sproc 传递到另一个?
【发布时间】:2026-02-16 16:30:01
【问题描述】:

我有 2 个 sproc 用于分配,我想要做的是将 xml 输出从一个 sproc 传递到另一个并将其放入变量中,我知道 ex1.xml_sp1 在使用 @987654321 调用它时返回一个 int @ 很明显,当尝试选择它时,它会返回 null,因为 @x 是 xml 数据类型。

我想要做的是从 sproc 1 中检索 xml 数据并将其存储到 sproc 2 中的@x

有什么办法吗?

sproc 1:

ALTER PROC [ex1].[xml_sp1]
@careteamid int
as

select CareTeams.CareTeamID, Doctors.DoctorID, Doctors.DoctorName,
   CareTeamDoctors.DateJoined, CareTeamDoctors.CurrentMember
from dbo.CareTeamTbl as CareTeams
inner join dbo.CareTeamDoctorTbl as CareTeamDoctors on
CareTeams.CareTeamID = CareTeamDoctors.CareTeamID
inner join dbo.DoctorTbl as Doctors on
CareTeamDoctors.DoctorID=CareTeamDoctors.DoctorID
where CareTeamDoctors.CareTeamID = @careteamid
and CareTeamDoctors.DoctorID = Doctors.DoctorID
for xml auto, root('thedata')

存储过程 2:

ALTER PROC [ex1].[xml_sp2]
@careteamid int
as 
declare @x xml

exec @x = ex1.xml_sp1
          @careteamid = @careteamid

select @x as XMLData

【问题讨论】:

    标签: sql sql-server xml sql-server-2008 tsql


    【解决方案1】:

    对于返回值(即EXEC @ReturnValue = StoredProcName...;),INT 是唯一允许的数据类型。如果这需要真正保留为存储过程,那么您可以使用OUTPUT 变量或在第二个存储过程中创建临时表或表变量并执行INSERT INTO ... EXEC StoredProc1;

    但是,鉴于第一个存储过程仅执行简单的 SELECT 语句,您最好将其转换为内联表值函数 (iTVF),如下所示:

    CREATE FUNCTION dbo.GetData (@CareTeamID INT)
    RETURNS TABLE
    AS RETURN
    
    SELECT tab.col AS [CareData]
    FROM (    
        SELECT CareTeams.CareTeamID, Doctors.DoctorID, Doctors.DoctorName,
               CareTeamDoctors.DateJoined, CareTeamDoctors.CurrentMember
        FROM   dbo.CareTeamTbl as CareTeams
        INNER JOIN dbo.CareTeamDoctorTbl as CareTeamDoctors
                ON  CareTeams.CareTeamID = CareTeamDoctors.CareTeamID
        INNER JOIN dbo.DoctorTbl as Doctors
                ON CareTeamDoctors.DoctorID=CareTeamDoctors.DoctorID
        WHERE  CareTeamDoctors.CareTeamID = @CareTeamID
        AND    CareTeamDoctors.DoctorID = Doctors.DoctorID
        FOR XML AUTO, ROOT('thedata'), TYPE -- "TYPE" causes result to be XML and not NVARCHAR
         ) tab(col);
    

    然后只需将第二个存储过程更改为:

    SELECT  care.CareData AS [XMLData]
    FROM    dbo.GetData(@CareTeamID);
    

    或者,如果您确实需要在第二个存储过程中使用该 XML 数据,请执行以下操作:

    DECLARE @TempData XML;
    
    SELECT  @TempData = care.CareData
    FROM    dbo.GetData(@CareTeamID);
    

    最后,如果您需要 XML 数据实际上是来自该 iTVF 的 XML 数据类型(或者即使您将其保留为存储过程),那么您需要将 TYPE 选项添加到 @987654329 @ 子句,否则返回字符串 /NVARCHAR(MAX):

    FOR XML AUTO, ROOT ('thedata'), TYPE
    

    【讨论】:

    • 我需要将它作为 xml 数据类型传递,因为我的任务要求我使用 xquery 将 xml 数据切碎到一个临时表中,但我没有提到这一点,因为我知道如何做到这一点简单地说,我遇到的问题实际上是将第一个 sproc 的输出传递给第二个 sproc 来执行此操作,希望这可以澄清:)
    • @ConorS 我明白了。只要您将值放入XML 变量中,那么在这一点上它实际上都是一样的。如果您或任何人这样做是为了工作而不是任务(即正确且有效地),我只是展示了如何做到这一点:-)
    【解决方案2】:

    我想做的是从sproc 1中检索xml数据并将其存储到sproc 2中的@x。

    您可以使用OUTPUT parameters 轻松实现它:

    CREATE PROCEDURE [xml_sp1]
       @careteamid INT,
       @xml_output XML OUTPUT
    AS
    BEGIN
       SET @xml_output = (SELECT * FROM ... FOR XML AUTO, root('thedata'));
    END;
    GO
    
    CREATE PROCEDURE [xml_sp2]
       @careteamid INT
    AS
    BEGIN
       DECLARE @x XML;
    
       EXEC [xml_sp1]
         @careteamid,
         @x OUTPUT;
    
       SELECT @x AS XMLData;
    END;
    GO
    

    最后的电话:

    EXEC [xml_sp2] @careteamid = 1;
    

    LiveDemo

    考虑使用BEGIN/END 块并以; 结束每个语句以避免可能出现的严重问题。

    可能的共享数据方法的完整列表How to Share Data between Stored Procedures by Erland Sommarskog

    【讨论】:

      【解决方案3】:

      为什么不试试这个而不是直接分配 sp1 的输出

       declare  @t table
          (
          val xml
          )
      
          insert into  @t
          exec ex1.xml_sp1
          @careteamid = @careteamid
      
          select * from @t
      

      【讨论】:

      • 这有一些你应该注意的限制:INSERT-EXEC
      • 感谢您提供的链接,这很有帮助
      【解决方案4】:

      这行得通吗?

      declare @xml xml
      set @xml = (select *
                  from tableABC
                  for xml auto, elements)
      

      然后将该变量传递给另一个存储过程?

      我从这里得到答案

      How to insert FOR AUTO XML result into table?

      在我看来这个想法是相似的,或者应该是相似的。

      【讨论】:

        最近更新 更多