【问题标题】:How to use a variable inside a function in SQL Server如何在 SQL Server 的函数中使用变量
【发布时间】:2019-09-13 22:14:30
【问题描述】:

简而言之,我试图在 SQL Server 函数中使用一个变量,该变量在 While 循环内的每一轮中将其自身的值增加一。

我正在将一个xml文本放入一个变量中,并试图在一个属性中检索一个值,但它有不止一个相似的元素,所以我需要一个一个地检索它。

问题出在这段代码的最后一部分:

DECLARE
        @XMLTI NVARCHAR(MAX),
        @now INT = 1,
        @pagos VARCHAR(50),
        @Trx33 INT = 1,
        @NumOperacionT VARCHAR(19),
        @FechaPagoT VARCHAR(19),
        @FormaDePagoT VARCHAR(50),
        @MonedaT VARCHAR(80),
        @TipoCambioT DECIMAL(22, 2) = 1.00,
        @CtaBeneficiarioT VARCHAR(50),
        @RfcEmisorCtaBenT VARCHAR(13),
        @MontoT DECIMAL(22, 2),
        @XML XML

SET @XMLTI = (SELECT xml FROM emi_trx33_complementos_r WHERE id_complemento = @Trx33 )

SET @XMLTI = REPLACE( @XMLTI, '<cfdi:', '<' )   
SET @XMLTI = REPLACE( @XMLTI, '</cfdi:', '</' ) 
SET @XMLTI = REPLACE( @XMLTI, '<tfd:', '<' )    
SET @XMLTI = REPLACE( @XMLTI, '<pago10:', '<' )
SET @XMLTI = REPLACE( @XMLTI, '</pago10:', '</' )   
SET @XMLTI = REPLACE( @XMLTI, '<nomina12:', '<' )   
SET @XMLTI = REPLACE( @XMLTI, '</nomina12:', '</' )

DROP TABLE IF EXISTS #Pagos

CREATE TABLE #Pagos 
(
    Id INT NOT NULL IDENTITY PRIMARY KEY ,
    NumOperacion VARCHAR(19),
    FechaPago VARCHAR(19),
    FormaDePago VARCHAR(50),
    Moneda VARCHAR(80),
    TipoCambio DECIMAL(22, 2),
    CtaBeneficiario VARCHAR(50),
    RfcEmisorCtaBen VARCHAR(13),
    Monto DECIMAL(22, 2)
)

SET @pagos = @XMLTI
SET @XML = @XMLTI

SET @pagos = CONVERT(VARCHAR(MAX), (SELECT @XML.query('count(/Comprobante/Complemento/Pagos/Pago)')))
SET @NumOperacionT =  CONVERT(VARCHAR(MAX), (SELECT @XML.value('data(/Comprobante/Complemento/Pagos/Pago/@NumOperacion)[@MyVariable]', 'VARCHAR(30)')))

--Pagos =3
--now =1
WHILE @now < @pagos
BEGIN
    SET @NumOperacionT = CONVERT(VARCHAR(MAX), (SELECT @XML.value('data(/Comprobante/Complemento/Pagos/Pago/@NumOperacion)[@now]', 'VARCHAR(30)')))

    INSERT INTO X table @NumOperacionT 

    @now = @now + 1
END

但我收到以下错误

错误 SET @NumOperacionT = convert(varchar(max),(select @XML.value('data(/Comprobante/Complemento/Pagos/Pago/@NumOperacion)[@MyVariable]','varchar(30)')))

选择@NumOperacionT 作为操作

[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]XQuery [value()]: / (2374) 需要一个节点或一组节点

【问题讨论】:

    标签: sql-server xml-parsing xquery-sql


    【解决方案1】:

    您正在将一个字符串输入value 函数,因此如果您想将变量的值插入到该字符串内的数据目录中,您需要将变量拉到字符串外并连接起来,如下所示:

    SET @NumOperacionT = convert(varchar(max),(select @XML.value('data(/Comprobante/Complemento/Pagos/Pago/@NumOperacion)[' + @now + ']','varchar(30)')))

    但是,这也可能会引发错误,因为如果是对字符串内容的错误检查,则需要使用动态 SQL。例如:

    declare @sql varchar(4000) 
    set @sql = 'SET @NumOperacionT = convert(varchar(max),(select @XML.value(''data(/Comprobante/Complemento/Pagos/Pago/@NumOperacion)[' + @now + ']'',''varchar(30)'')))'
    exec(@sql)
    

    老实说,由于您使用的是局部变量,因此这很可能也不起作用,因为动态 SQL 不会知道变量,因为它位于不同的进程中。

    您可以通过使用实际表数据来管理循环来解决此问题,但通常不建议这样做,并且可能会导致很多意外问题,尤其是在多线程场景中。

    应该有一种更简洁的方式来编写它而不使用循环。我建议尝试找到一种替代方法,您可以使用它来以实际表格格式检索您需要的数据,而不是使用变量。不知道数据很难说,但您可以尝试此线程中概述的一些方法,例如:

    Getting multiple records from xml column with value() in SQL Server

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多