Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何将存储过程返回的XML放入变量中?_Sql Server_Xml_Stored Procedures_Variables - Fatal编程技术网

Sql server 如何将存储过程返回的XML放入变量中?

Sql server 如何将存储过程返回的XML放入变量中?,sql-server,xml,stored-procedures,variables,Sql Server,Xml,Stored Procedures,Variables,我有一个返回XML的存储过程。返回的XML不是参数,而是选择的结果: create procedure #xml_test as select 1 as a for xml raw go 我试图将此XML放入一个变量中: declare @xml as nvarchar(max) 但我不知道怎么做。我最好的主意是插入。。。EXEC,但我收到错误“INSERT语句中不允许FOR XML子句”: create table #tmp(col1 nvarchar(max) not null)

我有一个返回XML的存储过程。返回的XML不是参数,而是选择的结果:

create procedure #xml_test
as
  select 1 as a for xml raw
go
我试图将此XML放入一个变量中:

declare @xml as nvarchar(max)
但我不知道怎么做。我最好的主意是插入。。。EXEC,但我收到错误“INSERT语句中不允许FOR XML子句”:

create table #tmp(col1 nvarchar(max) not null)

insert into #tmp
exec #xml_test
这种方法适用于普通文本:

create procedure #text_test
as
  select 'aaa' as a 
go

insert into #tmp
exec #text_test

我想知道以前是否有人碰到过这个问题?我使用的是SQL Server 2005

在本页上有许多从XML选择变量的示例:

Microsoft SQL Server 2005中XML的新增功能

给出的最简单示例是:

DECLARE @cust XML;
SET @cust = (SELECT * FROM Customers FOR XML AUTO, TYPE)

好吧,在对一个愚蠢的、考虑不周的评论进行适当的警告之后,我希望有一个更好的答案。它使用OPENROWSET将存储过程的结果存储到临时表中。从那里,可以将结果传递给变量。这有点混乱,需要ALTERSETTINGS服务器级权限才能启用临时分布式查询

无论如何,下面是经过充分测试的T-SQL:

CREATE DATABASE db_test;
GO

USE [db_test];
GO

CREATE PROCEDURE xml_test
AS
    SELECT 1 AS a FOR XML RAW
GO

sp_configure 'show advanced options', 1;
RECONFIGURE;
GO

sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO

SELECT * INTO #tbl_test FROM
    OPENROWSET(
        'SQLNCLI',
        'Server=(local);trusted_connection=yes',
        'set fmtonly off exec db_test.dbo.xml_test') AS tbl_test;
GO

DECLARE @xml_test AS XML;
SET @xml_test = (SELECT * FROM #tbl_test FOR XML RAW, BINARY BASE64);
GO

您可以包装SELECT,以便它设置一个局部变量,然后在存储过程的末尾选择该变量:

CREATE PROCEDURE xml_test
AS
BEGIN
    DECLARE @xml

    SET @xml = (SELECT 1 AS a FOR XML RAW)

    SELECT @xml AS my_xml
END

但是使用FOR XML存在一些问题,因此如果您有子查询、联合等,则可能需要稍微修改查询。

这个问题让我忙了一段时间

我有一个函数,该函数生成一个xml变量,其中包含两个输入xml变量的差异

这就是我能够返回结果的方式



该函数现在将生成一个XML变量,其内容如下:



值1
价值3



您不能将其作为输出参数返回吗?如果是这样的话,这种方法应该可以满足您的需要。不幸的是,我无法更改存储过程:(是的,我在搜索答案时看到了这篇文章。不幸的是,它只处理选择。我必须从存储过程中获取XML。哦,我明白了。我误解了这一点。“EXEC@XML=XML_test()怎么样?”?不,这完全是胡说八道。我建议你在回答之前做一些测试。@Mike-答案不错-似乎不可能避免BASE64编码?@Martin Smith:我没有找到用XML RAW避免BASE64的方法,但在其他模式下可能会这样-我没有花太多时间试图找到解决这一点的方法。BASE64有这似乎是一个非常不幸的结果。不幸的是,我无法更改存储过程。那么我认为您运气不好…:(
CREATE FUNCTION [dbo].[GetXmlDiff]
(
    @id uniqueidentifier,
    @left XML,
    @right XML
)
RETURNS XML
AS
BEGIN
    DECLARE @Delta TABLE
    (
        id uniqueidentifier,
        Delta NVARCHAR( 10 ),
        Attribute NVARCHAR( MAX ),
        Value NVARCHAR( MAX )
    );
        ---
    --- DO THE DIFFING INTO  table VARIABLE
        ---
    DECLARE @ResultVar XML = (
    SELECT * FROM  ( 
                        SELECT  1 AS tag, 
                                null as parent, 
                                id   AS 'o!1!id',
                                null AS 'a!2!delta',
                                null AS 'a!2!name',
                                null AS 'a!2!!element'
                                 FROM @Delta 
                        UNION
                        SELECT  2 as tag, 
                                1 as parent, 
                                id,
                                Delta,
                                Attribute,
                                Value
                                 FROM @Delta 
                    ) Q 
                    FOR XML EXPLICIT );
    RETURN @ResultVar;
END
<o id="4CBA2CC4-1FB6-426E-8504-0000468CD7E5">
  <a delta="Add" name="attribute1">value 1</a>
  <a delta="Delete" name="attribute2"></a>
  <a delta="Update" name="attribute3">value 3</a>
 </o>