vistas vista una tipos tabla parametros modificar funciona crear consultar con complejas como oracle plsql oracle11g date-arithmetic

oracle - una - Crear vista con 365 días



vistas con parametros oracle (3)

Cómo crear una View con todos los días del año. view debería llenarse con fechas desde el JAN-01 hasta el 31 de diciembre. ¿Cómo puedo hacer esto en el oráculo?

si el año actual tiene 365 días, la view debe tener 365 filas con fechas. si el año actual tiene 366 días, la view debe tener 366 filas con fechas. Quiero que la view tenga una sola columna de tipo DATE


Esta simple vista lo hará:

create or replace view year_days as select trunc(sysdate, ''YYYY'') + (level-1) as the_day from dual connect by level <= to_number(to_char(last_day(add_months(trunc(sysdate, ''YYYY''),11)), ''DDD'')) /

Me gusta esto:

SQL> select * from year_days; THE_DAY --------- 01-JAN-11 02-JAN-11 03-JAN-11 04-JAN-11 05-JAN-11 06-JAN-11 07-JAN-11 08-JAN-11 09-JAN-11 10-JAN-11 11-JAN-11 ... 20-DEC-11 21-DEC-11 22-DEC-11 23-DEC-11 24-DEC-11 25-DEC-11 26-DEC-11 27-DEC-11 28-DEC-11 29-DEC-11 30-DEC-11 31-DEC-11 365 rows selected. SQL>

La fecha se genera aplicando varias funciones de fecha de Oracle:

  • trunc(sysdate, ''yyyy'') nos da el primero de enero para el año actual
  • add_months(x, 11) nos da el primero de diciembre
  • last_day(x) nos da el treinta y uno de diciembre
  • to_char(x, ''DDD'') nos da el número del treinta y uno de diciembre, 365 este año y 366 siguiente.
  • Esta última figura proporciona el límite superior para el generador de filas CONNECT BY LEVEL <= X

Esto funciona bien en MS SQL

SELECT TOP (DATEDIFF(day, DATEADD(yy, DATEDIFF(yy,0,getdate()), 0), DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1))) n = ROW_NUMBER() OVER (ORDER BY [object_id]), dateadd(day, ROW_NUMBER() OVER (ORDER BY [object_id]) - 1, DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) AS AsOfDate FROM sys.all_objects


Puedes usar la tabla piplined, debería ser algo como esto:

create or replace type year_date_typ as object (v_day date); create or replace type year_date_tab as table of year_date_typ; CREATE OR REPLACE FUNCTION get_dates(year IN VARCHAR2) RETURN year_date_tab PIPELINED IS v_start_date date := to_date(''0101'' || year, ''ddmmyyyy''); res year_date_typ := year_date_typ(null); v_days_in_year integer := 365; BEGIN if to_char(last_day(to_date(''0102''||year, ''ddmmyyyy'')), ''dd'') = ''29'' then v_days_in_year := 366; end if; FOR i in 0 .. v_days_in_year integer-1 LOOP res.v_day := v_start_date + i; pipe row(res); END LOOP; return; END get_dates;

y puedes usarlo:

select * from table(get_dates(''2011''));