Descartar resultados de un SP dentro de otro

26/09/2004 - 17:13 por Leonardo Azpurua | Informe spam
Hola.

Tengo un SP que calcula los precios de un ticket aereo. El SP devuelve como
valor de retorno el precio en Moneda Nacional del ticket, pero ademas
devuelve los resultados de una consulta donde se incluye el Valor en MN, el
codigo de la unidad monetaria en la que se define la tarifa, el tipo de
cambio y el "metodo de calculo" utilizado (Tarifa Promocional o Descuento
sobre Tarifa Publicada).

Desde otro SP -que calcula los impuestos- llamo al primero para obtener el
valor en MN del Ticket, asi:

EXEC @PrecioMN = CalcPrecio @Ruta, @Clase, @Tarifa, @TipoPax, @Fecha

y funciona, en el sentido de que @PrecioMN asume el precio correspondiente
al tramo. El problema es que obtengo un conjunto de resultados que se agrega
al conjunto de resultados que debe devolver mi SP.

La pregunta es si existe alguna manera de obtener el valor de retorno de
CalcPrecio descartando el conjunto de resultados.

Gracias

Leonardo

Preguntas similare

Leer las respuestas

#6 Javier Loria
27/09/2004 - 18:30 | Informe spam
Hola Leronardo:
Muchas gracias por el codigo, esta muy claro y muy bien documentado.
Seria imposible entenerde el problema si no estuviera tan claro.
Sin tener el codigo de las tablas me puse un poco a jugar con los
SELECTs, te pido disculpas si engo errores de sintaxis o logica pero no
puede probarlas :(
La primera parte del procedimiento es la que "no te permite" seleccionar
los datos de forma de conjunto ya que hay que tomar decisiones sobre el
calculo, pero en realidad si es posible tomar las desiciones usando
CASE/WHEN/THEN, que es muy parecido a un IIF de Visual Basic pero un poco
mas completo.
Creo que el siguiente SELECT me da la prioridad maxima menor para cada
codigo de Tarifa:
= Maxima Prioridad Anterior
SELECT T2.Codigo
, Max(T1.Prioridad) AS PrioridadAnterior
FROM Tarifas AS T1
JOIN Tarifas AS T2
ON T1.Prioridad<T2.Prioridad
GROUP BY T2.Codigo
= Si esto esta bien, puede usarse como base para "sutituir" tarifas, de
manera que podamos escoger una tarifa alternativa. Este select es un buen
candidato para ser una vista
=CREATE VIEW TarifasSustitutas
AS
SELECT VC,Codigo
, NC.Codigo AS NuevoCodigo
FROM Tarifas NC
JOIN (SELECT T2.Codigo
, Max(T1.Prioridad) AS PrioridadAnt
FROM Tarifas AS T1
JOIN Tarifas AS T2
ON T1.Prioridad<T2.Prioridad
GROUP BY T2.Codigo) AS VC
ON NC.Codigo=VC.Codigo
AND NC.Prioridad=VC.PrioridadAnt
WHERE NC.AceptaDescuentos<>0
= Esta vista, selecciona el nuevo codigo de tarifa alternativo. Es por
cierto el mas complejo y me disculpo por los errores de sintaxis que pueda
tener. Es particularmente compleja porque no pude asumir nada respecto a las
llaves primarias :(
Si los dos pasos anteriores estan correctos, sustituirse el siguiente
codigo de procedimiento:
-
SET @TarifaAceptaDescuentos = (SELECT AceptaDescuentos FROM Tarifas WHERE
Codigo = @Tarifa)
IF @TarifaAceptaDescuentos = 0
BEGIN
SET @CodigoTarifa = (SELECT Codigo FROM Tarifas WHERE AceptaDescuentos
<> 0
AND Prioridad = (SELECT Max(Prioridad) FROM
Tarifas WHERE Prioridad <
(SELECT Prioridad FROM Tarifas
WHERE Codigo = @Tarifa)))
IF @CodigoTarifa IS NULL SET @CodigoTarifa = 'Y'
END
ELSE SET @CodigoTarifa = @Tarifa
PRINT @CodigoTarifa
por algo como:
SELECT Codigo,
, CASE WHEN AceptaDescuentos=0
THEN TarifasSustitutas.NuevoCodigo -- Puede ser
NULL
ELSE @Tarifa END AS CodigoTarifa
FROM Tarifas
LEFT JOIN TarifasSustitutas
ON Tarifas.Codigo=TarifasSustitutas.Codigo
= Claro el nuevo lo hace para todas las tarifas y el de arriba para una
sola.
Si validas lo anterior, entonces es relativamente facil escribir la
vista sustituto del procedimiento. Si me envias el codigo de los CREATE
TABLE (puedes poner las columnas relevantes si no quieres copiarlo todo), y
sobre todo las llaves primarias, puede verificar y/o simplificar la
sintaxis.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda

"Leonardo Azpurua" <l e o n a r d o (arroba) m v p s (punto) o r g> wrote in
message news:

"Javier Loria" escribió en el mensaje
news:%
Hola:
Si los precios son un conjunto de datos que debe ser reutilizado


dentro
del SQL porque no hacer esa logica en una Vista y no en un Procedimiento
Almacenado?
Si postearas el codigo podriamos opinar con mayor fundamento.



Hola.

Los precios no son suceptibles (hasta donde puedo imaginar, que es poco) de
representarse mediante una vista, porque hay decisiones que tomar en el
calculo:

CREATE PROCEDURE dbo.CalcPrecio
Tarifa vigentes para una fecha.
Descuento(TipoPax) / 100)
(
@Ruta As Bigint,
@Clase As nVarChar(3),
@Tarifa As nVarChar(3),
@TipoPax As nVarChar(3),
@Fecha As datetime
)
AS
Declare @PrecioY As money
Declare @PrecioYMN As Money
Declare @TipoCambioY As float
Declare @MonedaY as nvarchar(3)
Declare @PrecioCT As money
Declare @PrecioCTMN As Money
Declare @TipoCambioCT As float
Declare @MonedaCT As nvarchar(3)
Declare @DescuentoTipo As float
Declare @Metodo As NVarChar(1)
Declare @TarifaAceptaDescuentos as SmallInt
Declare @CodigoTarifa As nVarChar(3)

SET @TarifaAceptaDescuentos = (SELECT AceptaDescuentos FROM Tarifas WHERE
Codigo = @Tarifa)
IF @TarifaAceptaDescuentos = 0
BEGIN
SET @CodigoTarifa = (SELECT Codigo FROM Tarifas WHERE AceptaDescuentos
<> 0
AND Prioridad = (SELECT Max(Prioridad) FROM
Tarifas WHERE Prioridad <
(SELECT Prioridad FROM Tarifas
WHERE Codigo = @Tarifa)))
IF @CodigoTarifa IS NULL SET @CodigoTarifa = 'Y'
END
ELSE SET @CodigoTarifa = @Tarifa
PRINT @CodigoTarifa

SET @DescuentoTipo = (SELECT Descuento FROM TipoPax WHERE Codigo @TipoPax)
SELECT @PrecioY = Precio, @MonedaY = Cod, @TipoCambioY = TCambio
FROM CambiosPrecio, Monedas
WHERE Monedas.Cod = CambiosPrecio.Moneda
AND CambiosPrecio.Ruta = @Ruta
AND CambiosPrecio.Clase = @Clase
AND CambiosPrecio.Tarifa = @CodigoTarifa
AND CambiosPrecio.InicioVigencia (SELECT MAX(InicioVigencia) FROM CambiosPrecio
WHERE Ruta = @Ruta AND Clase = @Clase AND Tarifa @CodigoTarifa
AND InicioVigencia <= @Fecha)
SET @PrecioY = @PrecioY * (1 - @DescuentoTipo / 100)
SET @PrecioYMN = @PrecioY * @TipoCambioY

SELECT @PrecioCT = Precio, @MonedaCT = Cod, @TipoCambioCT = TCambio
FROM CambiosPrecio, Monedas
WHERE Monedas.Cod = CambiosPrecio.Moneda
AND CambiosPrecio.Ruta = @Ruta
AND CambiosPrecio.Clase = @Clase
AND CambiosPrecio.Tarifa = @Tarifa
AND CambiosPrecio.InicioVigencia (SELECT MAX(InicioVigencia) FROM CambiosPrecio
WHERE Ruta = @Ruta AND Clase = @Clase AND Tarifa = @Tarifa
AND InicioVigencia <= @Fecha)

SET @PrecioCTMN = @PrecioCT * @TipoCambioCT
SET @Metodo = @CodigoTarifa
If @PrecioCTMN < @PrecioYMN
BEGIN
SET @Metodo = @Tarifa
SET @PrecioYMN = @PrecioCTMN
SET @PrecioY = @PrecioCT
SET @TipoCambioY = @TipoCambioCT
SET @MonedaY = @MonedaCT
END

asumí):
SELECT @PrecioY As Precio, @TipoCambioY As TipoCambio, @MonedaY As Moneda,
@Metodo As Metodo

RETURN @PrecioYMN
-

y el calculo de los impuestos es este:

CREATE PROCEDURE dbo.CalcularImpuestos
(
@Ruta as Bigint,
@Clase As nVarChar(3),
@Tarifa As nVarChar(3),
@TipoPax As nVarChar(3),
@Fecha AS DateTime,
@nTramo as Smallint
)
AS
Declare @PrecioMN Money
Declare @MetodoCalculo SmallInt
Declare @AtributosDescuento BigInt
Declare @AplicarBoleto SmallInt

SET @AplicarBoleto = 0
IF @nTramo = 1 SET @AplicarBoleto = 1

EXEC @PrecioMN = CalcPrecio @Ruta, @Clase, @Tarifa, @TipoPax, @Fecha

IF @PrecioMN IS NULL SET @PrecioMN = 0
SET @AtributosDescuento = (SELECT Atributos FROM TipoPax WHERE Codigo @TipoPax)

SELECT
Codigo,
Valor CASE Metodo
WHEN 0 THEN Factor / 100 * @PrecioMN
WHEN 1 THEN Factor * (SELECT TCambio FROM Monedas WHERE Cod Moneda) * (SELECT Tramos FROM Rutas WHERE ID = @Ruta) * (SELECT CASE (Filtro
& @AtributosDescuento) WHEN 0 THEN 1 ELSE 0 END)
WHEN 2 THEN Factor * (SELECT TCambio FROM Monedas WHERE Cod Moneda) * (SELECT CASE (Filtro & @AtributosDescuento) WHEN 0 THEN 1 ELSE 0
END)
WHEN 3 THEN Factor * (SELECT TCambio FROM Monedas WHERE Cod Moneda) * @AplicarBoleto * (SELECT CASE (Filtro & @AtributosDescuento) WHEN
0 THEN 1 ELSE 0 END)
END
FROM Impuestos

RETURN @PrecioMN

TipoPax.Atributos es una mascara de bits. Los tres primeros (1, 2 y 4)
indican que debe exonerarse uno de los tres -de momento- impuestos activos.
La columna Impuestos.Filtro contiene potencias de 2 (1, 2, 4 de momento) con
valores unicos para cada fila.

Salud!

Leonardo
mvp vb
Respuesta Responder a este mensaje
#7 Leonardo Azpurua
28/09/2004 - 04:02 | Informe spam
"Javier Loria" escribió en el mensaje
news:
Hola Leronardo:
Muchas gracias por el codigo, esta muy claro y muy bien documentado.



Muchas gracias a ti por tu esfuerzo. Sé que cualquier procedimiento que
genere un conjunto de datos puede reemplazarse por una construcción SQL que
genere ese mismo conjunto. Pero despues de casi treinta años diciéndole a
las computadoras lo que deben hacer, se me hace de lo más cuesta arriba
aprender a pedirles lo que quiero.

Al final me escapé por la tangente: como siempre que requiero los precios es
casi seguro que tambien necesitare los impuestos, unifique los dos usos de
las consultas en uno solo: CalcularCargosTramo en el que utilizo los dos
conjuntos de datos. A fin de cuentas, lo que soy es programador y lo urgente
es resolver el problema.

No verifiqué sintácticamente tu solución, pero vaya que es elegante.

Salud!

Leonardo
mvp vb
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida