Usuario
Consulta condicional que devuelve varios campos de tabla de una función

Pregunta
-
Hola
Tengo una consulta general que de acuerdo a una condicion(case when else)llamara a un función de usuario u otro
Cada funcion de usuario recibe como parametro un campo de otra tabla llamada prueba que contiene un archivo xml.. Cada funcion de usuario retorna una tabla con varios campos.
Mi consulta gerneral que llama a las funciones de usuario lo pude crear pero solo me trae un solo campo y no me sirve. Como esta hecho son subconsultas, pero si no lo hago como subconsultas tambien me da un error.
Reptio si lo hago como subconsulta solo me trae un campo y no me sirve.
Si no lo expreso como subconsultas me da un error como lo habia expresado en otra consulta anterior en este foro
A continuación escribo los codigos:
Consulta general con subconsultas en los case, solo retorna una campo y no varios. No me sirve.select com.cod,com.tic,
CASE com.tic
WHEN 'I' THEN (Select * from dbo.fCfdiDatosFacturasXml(com.arc)) --llamo a una funcion
ELSE (Select * from dbo.fCfdiDatosPagosXml(com.arc))-- llamo a otra funcion de usuario
END
from prueba as com
Consulta general sin subconsultas en los case. Me da un error: No se encuentra la columna 'dbo' o la función definida por el usuario o agregado 'dbo.fCfdiDatosFacturasXml'; o bien, el nombre es ambiguo.
select com.cod,com.tic,
CASE com.tic
WHEN 'I' THEN dbo.fCfdiDatosFacturasXml(com.arc) --llamo a una funcion de usuario
ELSE dbo.fCfdiDatosPagosXml(com.arc)-- llamo a otra funcion de usuario
END
from prueba as com
Ese es el código de una de las funciones de usuario de tabla:
IF OBJECT_ID ('dbo.fCfdiDatosFacturasXml') IS NOT NULL
drop function dbo.fCfdiDatosFacturasXml
go
create function dbo.fCfdiDatosFacturasXml(@archivoXml xml)returns table
--Propósito. Obtiene los datos de la factura electrónica
--Usado por. vwCfdTransaccionesDeVenta
--Requisitos. CFDI
--25/10/17 jcf Creación cfdi 3.3
--25/01/18 jcf Agrega receptorRfc
--returns table
return(
WITH XMLNAMESPACES('http://www.sat.gob.mx/TimbreFiscalDigital' as "tfd",
'http://www.sat.gob.mx/cfd/3' as "cfdi")
SELECT
@archivoXml.value('(//tfd:TimbreFiscalDigital/@Version)[1]', 'varchar(5)') [version],
@archivoXml.value('(//tfd:TimbreFiscalDigital/@UUID)[1]', 'varchar(50)') UUID,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@FechaTimbrado)[1]', 'varchar(20)') FechaTimbrado,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@RfcProvCertif)[1]', 'varchar(20)') RfcPAC,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@Leyenda)[1]', 'varchar(150)') Leyenda,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@SelloCFD)[1]', 'varchar(8000)') SelloCFD,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@NoCertificadoSAT)[1]', 'varchar(20)') NoCertificadoSAT,
@archivoXml.value('(//tfd:TimbreFiscalDigital/@SelloSAT)[1]', 'varchar(8000)') SelloSAT,
@archivoXml.value('(//@Sello)[1]', 'varchar(8000)') Sello,
@archivoXml.value('(//@NoCertificado)[1]', 'varchar(20)') NoCertificado,
@archivoXml.value('(//@FormaPago)[1]', 'varchar(50)') FormaPago,
@archivoXml.value('(//@MetodoPago)[1]', 'varchar(21)') MetodoPago,
@archivoXml.value('(//cfdi:Receptor/@Rfc)[1]', 'varchar(15)') receptorRfc,
@archivoXml.value('(//cfdi:Receptor/@UsoCFDI)[1]', 'varchar(4)') UsoCFDI,
@archivoXml.value('(//cfdi:CfdiRelacionados/@TipoRelacion)[1]', 'varchar(4)') TipoRelacion,
@archivoXml.value('(//cfdi:CfdiRelacionado/@UUID)[1]', 'varchar(60)') UUIDrelacionado,
--AGREGO CAMPOS
@archivoXml.value('(//cfdi:Concepto/@ClaveProdServ)[1]', 'varchar(8)')ClaveProdServ,
@archivoXml.value('(//cfdi:Concepto/@Importe)[1]', 'varchar(10)')Importe,
@archivoXml.value('(//cfdi:Traslado/@Importe)[1]', 'varchar(10)')ImpuestoValorAgregado,
@archivoXml.value('(//cfdi:Traslado/@TasaOCuota)[1]', 'varchar(10)')TasaCuota
)
go
Todas las respuestas
-
Cada funcion de usuario retorna una tabla con varios campos
Si ambas funciones devuelven el mismo número de columnas y las columnas tienen el mismo propósito, he aquí una solución provisional:
-- código #1 SELECT com.cod, com.tic, F.columna_1, ..., F.columna_n from prueba as com outer apply dbo.fCfdiDatosFacturasXml(com.arc) as F where com.tic = 'I' union all SELECT com.cod, com.tic, F.columna_1, ..., F.columna_n from prueba as com outer apply dbo.fCfdiDatosPagosXml(com.arc) as F where com.tic <> 'I';
Desventaja: La tabla PRUEBA se lee dos veces.
José Diz Belo Horizonte, MG - Brasil [query performance tuning: Porto SQL]
Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.
- Propuesto como respuesta Pablo RubioModerator martes, 19 de noviembre de 2019 21:40
- Editado José Diz miércoles, 20 de noviembre de 2019 2:20