Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » PostgreSQL »

Calculo de fechas inicio y fin con psql

Estas en el tema de Calculo de fechas inicio y fin con psql en el foro de PostgreSQL en Foros del Web. HOLA, estoy haciendo un procedimiento almacenado el cual me debe devolver un par de fechas en una cadena EJ: 2010-04-10,2010-05-09. para culquier fecha comprendida en ...
  #1 (permalink)  
Antiguo 19/04/2010, 11:10
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 2 meses
Puntos: 5
Calculo de fechas inicio y fin con psql

HOLA, estoy haciendo un procedimiento almacenado el cual me debe devolver un par de fechas en una cadena EJ: 2010-04-10,2010-05-09. para culquier fecha comprendida en este intervalo de tiempo.

el codigo es el siguiente:

Código SQL:
Ver original
  1. CREATE OR REPLACE FUNCTION p_get(INTEGER) RETURNS SETOF CHARACTER VARYING AS
  2. $BODY$
  3. DECLARE
  4.  
  5.     customer    ALIAS FOR $1;
  6.     sql_query   VARCHAR;
  7.     start_day   INTEGER;
  8.     days_to_use INTEGER;
  9.     dates       CHARACTER VARYING;
  10.     diferenre   INTEGER;
  11.     query_result t_list;
  12. BEGIN
  13.  
  14.     sql_query   :=  '   SELECT  INTO register start_day_to_use, (days_to_use - 1) AS days_to_use
  15.                         FROM    contract
  16.                         WHERE   state = $$'A'$$ AND fk_pk_customer = '||customer;
  17.  
  18.     EXECUTE sql_query;
  19.  
  20.     start_day   :=  register.start_day_to_use;
  21.     days_to_us  :=  register.days_to_use;
  22.  
  23.     SELECT INTO register EXTRACT (DAY FROM CURRENT_DATE)::INTEGER AS current_day;
  24.  
  25.     IF register.current_day <   start_day   THEN
  26.         diference   :=  start_day   -   register.current_day;
  27.         sql_query   :=  "SELECT INTO register((CURRENT_DATE - INTERVAL '1 MONTHS') + INTERVAL '"||diference||"DAYS')::date AS start_date";
  28.         EXECUTE  sql_query;
  29.         dates   :=  register.start_date;
  30.  
  31.         sql_query   :=  "SELECT INTO register (((CURRENT_DATE - INTERVAL '1 MONTHS') + INTERVAL '"||diference||"DAYS') + INTERVAL '"||days_to_use||"')::date AS end_date";
  32.         EXECUTE  sql_query;
  33.         dates   :=  dates   || ','|| register.end_date;
  34.     ELSE
  35.         diference   :=  register.current_day    - start_day;
  36.         sql_query   :=  "SELECT INTO register(CURRENT_DATE - INTERVAL '"||diference||" DAYS')::date AS start_date";
  37.         EXECUTE  sql_query;
  38.         dates   :=  register.start_date;
  39.  
  40.         sql_query   :=  "SELECT INTO register((CURRENT_DATE - INTERVAL '"||diference||" DAYS') + INTERVAL '"||days_to_use||" DAYS') AS end_date";
  41.         EXECUTE  sql_query;
  42.         dates   :=  dates   || ','|| register.end_date;
  43.     END IF;
  44.  
  45.     SELECT
  46.  
  47.  
  48.     RETURN dates;
  49. END $BODY$ LANGUAGE 'plpgsql' VOLATILE;
  50.  
  51. SELECT p_get(996);

en el primer query es para obtener el dia de cada mes en el cual se empieza un nuevo ciclo de facturacion para un cliente, junto con la cantidad de dias que se han de facturar 30 o 60.

de resto son para calcular la fecha de inicio y final dependiendo de esta cantidad de dias a facturar y el dia actual.

al momento de crear el procedimientos me salen estos errores:

Código de error 0, estado SQL42601: ERROR: una cadena separada por $ está inconclusa en o cerca de «$BODY$
DECLARE

customer ALIAS FOR $1»
Línea 1, columna 1

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 6, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «start_day»
Línea 7, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «days_to_use»
Línea 8, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «dates»
Línea 9, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «diferenre»
Línea 10, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «query_result»
Línea 11, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 12, columna 1

Código de error 0, estado SQL26000: ERROR: no existe la sentencia preparada «sql_query»
Línea 18, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «start_day»
Línea 20, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «days_to_us»
Línea 21, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «INTO»
Línea 23, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «IF»
Línea 25, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 27, columna 3

Código de error 0, estado SQL26000: ERROR: no existe la sentencia preparada «sql_query»
Línea 28, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «dates»
Línea 29, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 31, columna 3

Código de error 0, estado SQL26000: ERROR: no existe la sentencia preparada «sql_query»
Línea 32, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «dates»
Línea 33, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «ELSE»
Línea 34, columna 2

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 36, columna 3

Código de error 0, estado SQL26000: ERROR: no existe la sentencia preparada «sql_query»
Línea 37, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «dates»
Línea 38, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «sql_query»
Línea 40, columna 3

Código de error 0, estado SQL26000: ERROR: no existe la sentencia preparada «sql_query»
Línea 41, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «dates»
Línea 42, columna 3

Código de error 0, estado SQL42601: ERROR: error de sintaxis en o cerca de «IF»
Línea 43, columna 2

Código de error 0, estado SQL42703: ERROR: no existe la columna «return»
Línea 45, columna 2

Código de error 0, estado SQL42601: ERROR: una cadena separada por $ está inconclusa en o cerca de «$BODY$ LANGUAGE 'plpgsql' VOLATILE»
Línea 49, columna 1

Código de error 0, estado SQL42883: ERROR: no existe la función p_get(integer)
Línea 51, columna 1,

INVESTIGARE MAS MIENTRAS ME RESPONDEN POR ACA, HABER QUE PUEDO ECONTRAR.

GRACIAS POR LA AYUDA
  #2 (permalink)  
Antiguo 19/04/2010, 13:29
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 2 meses
Puntos: 5
Respuesta: Calculo de fechas inicio y fin con psql

HOLA

BUENO, HE DESCUBIERTO UN PAR DE ERRORES, COMO POR EJEMPLO QUE TENIA QUE TRABAJAR CON CURSORES AL MISMO TIEMPO QUE CON LOS RECORD.

ahora mi problema es del concatenacion de una cadena la cual contiene comillas y varoles variables,

el query que itento armar debe quedar por ejemplo asi:

Código SQL:
Ver original
  1. SELECT INTO register((CURRENT_DATE - INTERVAL '1 MONTHS') + INTERVAL '20 DAYS')::DATE AS start_date;
  2. --DONDE EL 20 es un parametro variable


ACTUALMENTE LO TENGO ASI Y NO ME LO RECONOCE
Código SQL:
Ver original
  1. sql_query   :=  'SELECT INTO register((CURRENT_DATE - INTERVAL '1 MONTHS') + INTERVAL $$'||diference|| 'DAYS'$$')::date AS start_date';

AGRADEZCO LA AYUDA
  #3 (permalink)  
Antiguo 19/04/2010, 15:03
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 2 meses
Puntos: 5
Respuesta: Calculo de fechas inicio y fin con psql

bueno, ya logre resolver todo mi acertijo, la clave para concatenar en una variable, comillas + un valor variable + texto + comillas fue con: E'\''

AQUI PEGO EL CODIGO RESULTANTE DE MI PROCEDIMIENTO ALMACENADO Y COMENTADITO

Código SQL:
Ver original
  1. CREATE OR REPLACE FUNCTION p_get_range_date_to_billing(INTEGER) RETURNS VARCHAR AS
  2. $BODY$
  3. DECLARE
  4.  
  5.     customer    ALIAS FOR $1;
  6.     sql_query   VARCHAR;
  7.     start_day   INTEGER;
  8.     days_to_use INTEGER;
  9.     dates       CHARACTER VARYING;
  10.     state       CHARACTER VARYING;
  11.     diference   INTEGER;
  12.     myCursor    refcursor;
  13.     register    RECORD;
  14.     register2   RECORD;
  15.     aux     VARCHAR;
  16.     var_string  VARCHAR;
  17.     other_string    VARCHAR;
  18.    
  19. BEGIN
  20.  
  21.     --INICIO CONSULTA PARA OBTENER EL DIA DE INICIO DE LA FACTURACION Y LA CANTIDAD DE DIAS A FACTURAR 30 - 60
  22.     state       :=  $$'A'$$;
  23.     sql_query   :=  'SELECT  start_day_to_use, (days_to_use - 1) AS days_to_use
  24.                  FROM    contract
  25.                  WHERE   state = '||state||' AND fk_pk_customer =996';                 
  26.                    
  27.     OPEN myCursor FOR EXECUTE sql_query;
  28.     FETCH   myCursor INTO register;
  29.  
  30.     start_day   :=  register.start_day_to_use;
  31.     days_to_use :=  register.days_to_use;
  32.  
  33.     CLOSE   myCursor;
  34.  
  35.     --QUERY PARA OBTENER EL DIA ACTUAL
  36.     SELECT INTO register2 (EXTRACT (DAY FROM CURRENT_DATE)::INTEGER) AS current_day;
  37.  
  38.     --CALCULOS, CUANDO EL DIA ACTUAL ES MENOR QUE EL DIA DE INICIO DE LA FACTURACION
  39.     --INDICA QUE EL DIA ACTUAL PERTENECE AL MES SIGUIENTE DEL DIA DE INICIO DE LA FACTURACION
  40.     IF register2.current_day    <   start_day   THEN
  41.         diference   :=  start_day   -   register2.current_day;
  42.         aux     :=  $$'1 MONTHS'$$;
  43.         var_string  :=  E'\''||diference||E' DAYS\''; -- SE CONCATENA Y SE OBTIENE UN RESULTATE TIPO '8 DAYS'
  44.         sql_query   :=  'SELECT ((CURRENT_DATE - INTERVAL '||aux||') + INTERVAL '||var_string||')::date AS start_date';
  45.         OPEN myCursor FOR EXECUTE sql_query;
  46.         FETCH   myCursor INTO register;
  47.         dates   :=  register.start_date;
  48.         CLOSE myCursor;
  49.  
  50.         other_string    :=  E'\''||days_to_use||E' DAYS\'';  -- SE CONCATENA Y SE OBTIENE UN RESULTATE TIPO '30 DAYS'
  51.         sql_query   :=  'SELECT (((CURRENT_DATE - INTERVAL '||aux||') + INTERVAL '||var_string||') + INTERVAL '||other_string||')::date AS end_date';
  52.         OPEN myCursor FOR EXECUTE sql_query;
  53.         FETCH   myCursor INTO register;
  54.         dates   :=  dates   || ','|| register.end_date;
  55.         CLOSE myCursor;
  56.     ELSE -- EL MES ACTUAL ES EL MISMO DEL MES DEL DIA DE INICIO DE LA FACTURACION
  57.         diference   :=  register2.current_day   - start_day;
  58.         var_string  :=  E'\''||diference||E' DAYS\'';  -- SE CONCATENA Y SE OBTIENE UN RESULTATE TIPO '10 DAYS'
  59.         sql_query   :=  'SELECT (CURRENT_DATE - INTERVAL '||var_string||')::date AS start_date';
  60.        
  61.         OPEN myCursor FOR EXECUTE sql_query;
  62.         FETCH   myCursor INTO register;
  63.         dates   :=  register.start_date;
  64.         CLOSE myCursor;
  65.  
  66.         aux :=  E'\''||days_to_use||E' DAYS\'';  -- SE CONCATENA Y SE OBTIENE UN RESULTATE TIPO '30 DAYS'
  67.         sql_query   :=  'SELECT ((CURRENT_DATE - INTERVAL '||var_string||') + INTERVAL '||aux||')::date AS end_date';
  68.         OPEN myCursor FOR EXECUTE sql_query;
  69.         FETCH   myCursor INTO register;
  70.         dates   :=  dates   || ','|| register.end_date;
  71.         CLOSE myCursor;
  72.     END IF;
  73.  
  74.     RETURN dates;
  75. END $BODY$ LANGUAGE 'plpgsql' VOLATILE;
  76.  
  77. SELECT p_get_range_date_to_billing(996);

de todos modos no estoy 100% satisfecho con el codigo realizado, si alguien me puede dar ideas acerca de como optimizarlo y/o hacerlo mas entendible, seria genial.

Muchas Gracias.
  #4 (permalink)  
Antiguo 19/04/2010, 15:19
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 1 mes
Puntos: 360
Respuesta: Calculo de fechas inicio y fin con psql

Parece que ya lo resolviste...
pero te recomiendo trabajar con la función quote_literal que te puede ayudar con el manejo de las comillas simples dentro de una cadena.

aca se trata un poco el tema.
http://www.forosdelweb.com/f99/compa...adenas-727099/

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #5 (permalink)  
Antiguo 19/04/2010, 16:52
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 2 meses
Puntos: 5
Respuesta: Calculo de fechas inicio y fin con psql

LOGRE SACAR ESTE QUERY CON QUOTE_LITERAL, PARA OBTEBNER

COMILLA + VALOR_VARIABLE + TEXTO + COMILLA

Código SQL:
Ver original
  1. SELECT SUBSTRING(QUOTE_LITERAL('') FROM 1 FOR 1) ||20||  
  2.              SUBSTRING(QUOTE_LITERAL(' DAYS') FROM 2),'20 DAYS'

EN SINTESIS TENGO UNA FILA CON DOS COLUMNAS '20 DAYS',20 DAYS

Etiquetas: calculo, fechas, inicio
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:10.