<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ZogBit</title>
	<atom:link href="http://www.zogbit.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zogbit.com</link>
	<description>Oracle Development and Support</description>
	<lastBuildDate>Fri, 06 Aug 2010 13:44:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Retrieve an old SQL Plan</title>
		<link>http://www.zogbit.com/2010/08/retrieve-an-old-sql-plan/</link>
		<comments>http://www.zogbit.com/2010/08/retrieve-an-old-sql-plan/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 13:44:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=48</guid>
		<description><![CDATA[This script will use a sql_id to retrieve the execution plan for the query. with aa as (             SELECT DISTINCT ss.sql_id, ss.plan_hash_value             FROM   DBA_HIST_SQLSTAT SS             WHERE  SS.SQL_ID = &#8216;&#38;sql_id&#8217; ) SELECT b.*   from aa, table(dbms_xplan.display_awr(aa.sql_id,aa.plan_hash_value)) b /]]></description>
			<content:encoded><![CDATA[<p>This script will use a sql_id to retrieve the execution plan for the query.</p>
<p>with aa as (<br />
            SELECT DISTINCT ss.sql_id, ss.plan_hash_value<br />
            FROM   DBA_HIST_SQLSTAT SS<br />
            WHERE  SS.SQL_ID = &#8216;&amp;sql_id&#8217;<br />
)<br />
SELECT b.*<br />
  from aa, table(dbms_xplan.display_awr(aa.sql_id,aa.plan_hash_value)) b<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/retrieve-an-old-sql-plan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How much memory are people using</title>
		<link>http://www.zogbit.com/2010/08/how-much-memory-are-people-using/</link>
		<comments>http://www.zogbit.com/2010/08/how-much-memory-are-people-using/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:54:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=45</guid>
		<description><![CDATA[The sql below can be run to show who is using memory and how much memory. select S.sid, S.USERNAME, PM.category, PM.ALLOCATED,        ROUND(PM.USED/(1024*1024),0) as USED_MB, PM.MAX_ALLOCATED, SQL_TEXT  from v$process_memory pm inner join v$process p         on p.pid = pm.pid inner join v$session s         on s.paddr = p.addr inner join v$sql sq         on sq.sql_id <a href="http://www.zogbit.com/2010/08/how-much-memory-are-people-using/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The sql below can be run to show who is using memory and how much memory.</p>
<p>select S.sid, S.USERNAME, PM.category, PM.ALLOCATED,<br />
       ROUND(PM.USED/(1024*1024),0) as USED_MB, PM.MAX_ALLOCATED, SQL_TEXT<br />
 from v$process_memory pm<br />
inner join v$process p<br />
        on p.pid = pm.pid<br />
inner join v$session s<br />
        on s.paddr = p.addr<br />
inner join v$sql sq<br />
        on sq.sql_id = s.sql_id<br />
 order by PM.USED desc nulls last<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/how-much-memory-are-people-using/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Who&#8217;s running in parallel?</title>
		<link>http://www.zogbit.com/2010/08/whos-running-in-parallel/</link>
		<comments>http://www.zogbit.com/2010/08/whos-running-in-parallel/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:53:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=42</guid>
		<description><![CDATA[The below script will query the database for the users running parallel queries. SELECT  case when  px.qcinst_id is NUll then username              ELSE &#8216; &#8211; &#8216;&#124;&#124; LOWER(SUBSTR(s.program,LENGTH(s.program)- 4, 4))              end as &#8220;User name&#8221;         , case when px.qcinst_id is NULL then &#8216;QC&#8217; else &#8216;(Slave)&#8217; end as  &#8220;QC/Slave&#8221;         ,TO_CHAR(px.server_set) &#8220;Slave Set&#8221;         ,TO_CHAR(s.SID) &#8220;SID&#8221; <a href="http://www.zogbit.com/2010/08/whos-running-in-parallel/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The below script will query the database for the users running parallel queries.</p>
<p>SELECT  case when  px.qcinst_id is NUll then username<br />
             ELSE &#8216; &#8211; &#8216;|| LOWER(SUBSTR(s.program,LENGTH(s.program)- 4, 4))<br />
             end as &#8220;User name&#8221;<br />
        , case when px.qcinst_id is NULL then &#8216;QC&#8217; else &#8216;(Slave)&#8217; end as  &#8220;QC/Slave&#8221;<br />
        ,TO_CHAR(px.server_set) &#8220;Slave Set&#8221;<br />
        ,TO_CHAR(s.SID) &#8220;SID&#8221;<br />
        ,case when px.qcinst_id is NULL then TO_CHAR(s.SID) else to_char(px.qcsid) end as  &#8220;QC SID&#8221;<br />
        ,px.req_degree &#8220;Requested DOP&#8221;<br />
        ,px.DEGREE &#8220;Actual DOP&#8221;<br />
        ,s.osuser &#8220;User_id&#8221;<br />
        ,s.status<br />
        ,s.schemaname &#8220;Schema&#8221;<br />
    FROM v$px_session px<br />
    JOIN v$session s on px.SID = s.SID<br />
                    AND px.serial# = s.serial#<br />
ORDER BY 5 ,1 DESC</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/whos-running-in-parallel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manage your tablespace</title>
		<link>http://www.zogbit.com/2010/08/manage-your-tablespace/</link>
		<comments>http://www.zogbit.com/2010/08/manage-your-tablespace/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:50:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=39</guid>
		<description><![CDATA[The following script will calculate the space taken by tables and build the drop and truncate statements to allow you to simply whip through and clear your tablespace. SELECT   segment_name AS table_name,          SUM (BYTES) / (1024 * 1024) AS MB,          &#8216;drop table &#8216; &#124;&#124; TABLE_NAME &#124;&#124; &#8216; purge;&#8217; AS DROP_STATEMENT,          &#8216;truncate table <a href="http://www.zogbit.com/2010/08/manage-your-tablespace/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The following script will calculate the space taken by tables and build the drop and truncate statements to allow you to simply whip through and clear your tablespace.</p>
<p>SELECT   segment_name AS table_name,<br />
         SUM (BYTES) / (1024 * 1024) AS MB,<br />
         &#8216;drop table &#8216; || TABLE_NAME || &#8216; purge;&#8217; AS DROP_STATEMENT,<br />
         &#8216;truncate table &#8216; || TABLE_NAME || &#8216;;&#8217; AS TRUNCATE_STATEMENT<br />
    FROM user_segments s,<br />
         user_tables t<br />
   WHERE S.SEGMENT_NAME = T.TABLE_NAME<br />
GROUP BY segment_name, &#8216;drop table &#8216; || TABLE_NAME || &#8216; purge;&#8217;, &#8216;truncate table &#8216; || TABLE_NAME || &#8216;;&#8217;<br />
ORDER BY SUM (BYTES) DESC<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/manage-your-tablespace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Find locked objects</title>
		<link>http://www.zogbit.com/2010/08/find-locked-objects/</link>
		<comments>http://www.zogbit.com/2010/08/find-locked-objects/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:48:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=36</guid>
		<description><![CDATA[select    c.owner,    c.object_name,    c.object_type,    b.sid,    b.serial#,    b.status,    b.osuser,    b.machine from    v$locked_object a ,    v$session b,    dba_objects c where    b.sid = a.session_id and    a.object_id = c.object_id order by OWNER, OBJECT_NAME /]]></description>
			<content:encoded><![CDATA[<p>select<br />
   c.owner,<br />
   c.object_name,<br />
   c.object_type,<br />
   b.sid,<br />
   b.serial#,<br />
   b.status,<br />
   b.osuser,<br />
   b.machine<br />
from<br />
   v$locked_object a ,<br />
   v$session b,<br />
   dba_objects c<br />
where<br />
   b.sid = a.session_id<br />
and<br />
   a.object_id = c.object_id<br />
order by OWNER, OBJECT_NAME<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/find-locked-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is killing the database? (based on optimizer cost)</title>
		<link>http://www.zogbit.com/2010/08/what-is-killing-the-database-based-on-optimizer-cost/</link>
		<comments>http://www.zogbit.com/2010/08/what-is-killing-the-database-based-on-optimizer-cost/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:47:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=34</guid>
		<description><![CDATA[SELECT SYSTIMESTAMP AS s.SNAPSHOT_TIME,        S.PARSING_SCHEMA_NAME,        S.OPTIMIZER_COST,        S.MODULE,        S.LAST_LOAD_TIME,        S.LAST_ACTIVE_TIME,        S.SQL_TEXT,        s.SQL_ID,        S.SQL_FULLTEXT  from sys.v_$sql s where  module is not null and users_executing != 0 and optimizer_cost &#62;= 5000000 order by OPTIMIZER_COST desc; /]]></description>
			<content:encoded><![CDATA[<p>SELECT SYSTIMESTAMP AS s.SNAPSHOT_TIME,<br />
       S.PARSING_SCHEMA_NAME,<br />
       S.OPTIMIZER_COST,<br />
       S.MODULE,<br />
       S.LAST_LOAD_TIME,<br />
       S.LAST_ACTIVE_TIME,<br />
       S.SQL_TEXT,<br />
       s.SQL_ID,<br />
       S.SQL_FULLTEXT<br />
 from sys.v_$sql s<br />
where  module is not null<br />
and users_executing != 0<br />
and optimizer_cost &gt;= 5000000<br />
order by OPTIMIZER_COST desc;<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/what-is-killing-the-database-based-on-optimizer-cost/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kill an Oracle Session</title>
		<link>http://www.zogbit.com/2010/08/kill-an-oracle-session/</link>
		<comments>http://www.zogbit.com/2010/08/kill-an-oracle-session/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:46:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=32</guid>
		<description><![CDATA[DECLARE BEGIN &#8211; Now call the stored program   oracle.kill_session(&#38;sid,&#38;serial); EXCEPTION WHEN OTHERS THEN   dbms_output.put_line(SubStr(&#8216;Error &#8216;&#124;&#124;TO_CHAR(SQLCODE)&#124;&#124;&#8217;: &#8216;&#124;&#124;SQLERRM, 1, 255)); RAISE; END;]]></description>
			<content:encoded><![CDATA[<p>DECLARE<br />
BEGIN</p>
<p>&#8211; Now call the stored program<br />
  oracle.kill_session(&amp;sid,&amp;serial);</p>
<p>EXCEPTION<br />
WHEN OTHERS THEN<br />
  dbms_output.put_line(SubStr(&#8216;Error &#8216;||TO_CHAR(SQLCODE)||&#8217;: &#8216;||SQLERRM, 1, 255));<br />
RAISE;<br />
END;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/kill-an-oracle-session/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What&#8217;s Cached in the Database</title>
		<link>http://www.zogbit.com/2010/08/whats-cached-in-the-database/</link>
		<comments>http://www.zogbit.com/2010/08/whats-cached-in-the-database/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:44:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=29</guid>
		<description><![CDATA[SELECT *   FROM v$db_object_cache   WHERE type in (&#8216;TRIGGER&#8217;,'PROCEDURE&#8217;,'PACKAGE BODY&#8217;,'PACKAGE&#8217;)    and EXECUTIONS &#62; 0    and owner like UPPER(&#8216;&#38;DB_OWNER&#8217;)  ORDER BY owner, executions desc, loads desc, sharable_mem desc;]]></description>
			<content:encoded><![CDATA[<p>SELECT *<br />
  FROM v$db_object_cache<br />
  WHERE type in (&#8216;TRIGGER&#8217;,'PROCEDURE&#8217;,'PACKAGE BODY&#8217;,'PACKAGE&#8217;)<br />
   and EXECUTIONS &gt; 0<br />
   and owner like UPPER(&#8216;&amp;DB_OWNER&#8217;)<br />
 ORDER BY owner, executions desc, loads desc, sharable_mem desc;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/whats-cached-in-the-database/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Compile Invalid Objects</title>
		<link>http://www.zogbit.com/2010/08/compile-invalid-objects/</link>
		<comments>http://www.zogbit.com/2010/08/compile-invalid-objects/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 11:36:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DBA Scripts]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=24</guid>
		<description><![CDATA[with invalids as ( SELECT distinct    &#8216;ALTER &#8216; &#124;&#124; case object_type when &#8216;PACKAGE BODY&#8217; then &#8216;PACKAGE&#8217; else object_type end &#124;&#124; &#8216; &#8216; &#124;&#124;    OWNER &#124;&#124; &#8216;.&#8217; &#124;&#124; OBJECT_NAME &#124;&#124; &#8216; COMPILE;&#8217; as compile_sql,    case object_type             when &#8216;VIEW&#8217; then 1             when &#8216;FUNCTION&#8217; then 2             when &#8216;PROCEDURE&#8217; then 3             when <a href="http://www.zogbit.com/2010/08/compile-invalid-objects/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>with invalids as<br />
(<br />
SELECT distinct<br />
   &#8216;ALTER &#8216; || case object_type when &#8216;PACKAGE BODY&#8217; then &#8216;PACKAGE&#8217; else object_type end || &#8216; &#8216; ||<br />
   OWNER || &#8216;.&#8217; || OBJECT_NAME || &#8216; COMPILE;&#8217; as compile_sql,<br />
   case object_type<br />
            when &#8216;VIEW&#8217; then 1<br />
            when &#8216;FUNCTION&#8217; then 2<br />
            when &#8216;PROCEDURE&#8217; then 3<br />
            when &#8216;PACKAGE&#8217; then 4<br />
            else 5 END as display_order<br />
from<br />
   dba_objects<br />
where<br />
   status = &#8216;INVALID&#8217;<br />
and<br />
   object_type in (&#8216;PACKAGE&#8217;,'PACKAGE BODY&#8217;,'FUNCTION&#8217;,'PROCEDURE&#8217;,'VIEW&#8217;)<br />
)<br />
select compile_sql<br />
  from invalids<br />
 order by display_order<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/08/compile-invalid-objects/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Bank  Holidays &#8211; Algorithm versus Table</title>
		<link>http://www.zogbit.com/2010/07/bank-holidays-algorithm-versus-table/</link>
		<comments>http://www.zogbit.com/2010/07/bank-holidays-algorithm-versus-table/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 11:51:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Developer Tricks]]></category>

		<guid isPermaLink="false">http://www.zogbit.com/blog/?p=18</guid>
		<description><![CDATA[Bank Holidays in a Table? My client maintains a table in their database with every day of the year and a flag to say if the day is a working day, a bank holiday or a weekend (Saturday/Sunday).  Every now and again somebody takes the responsibility to flag the bank holidays in the future. The primary <a href="http://www.zogbit.com/2010/07/bank-holidays-algorithm-versus-table/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Bank Holidays in a Table?</h2>
<p>My client maintains a table in their database with every day of the year and a flag to say if the day is a working day, a bank holiday or a weekend (Saturday/Sunday).  Every now and again somebody takes the responsibility to flag the bank holidays in the future.</p>
<p>The primary purpose of the table is for setting appointments for agents or giving a date of completion based on x number of working days in the future, so generally the data is only required for a reasonably limited period of time around the current date.</p>
<p>A few issues spring to mind:</p>
<p>1)      Somebody or something needs to maintain this table</p>
<p>2)      Holding data for something that could be done via an algorithm</p>
<p>3)      Database reads whenever making a working day calculation</p>
<p>Point (3) can be dealt with by caching etc. in a Transaction type system, however batch processes have the potential to cause problems, in fact, my client was suffering from a batch job running of 8+ hours.</p>
<h2> Bank Holidays in an Algorithm</h2>
<p>The solution provided to the client was to implement the Bank Holiday package attached to this post, enabling Bank Holiday and Next Working Day calculations without the need to perform data reads.  The 8 hour batch job was reduced to seconds.</p>
<p> Examples for use:</p>
<p> 1)      Check if a date is a working day:</p>
<p> CREATE OR REPLACE FUNCTION IsWorkingDay</p>
<p>   (FromDate IN DATE, NoofDays IN NUMBER DEFAULT 0)</p>
<p>   RETURN VARCHAR2</p>
<p>AS</p>
<p>BEGIN</p>
<p>CASE</p>
<p>  WHEN trim(to_char(fromdate + noofdays, &#8216;DAY&#8217;)) IN (&#8216;SATURDAY&#8217;,'SUNDAY&#8217;)</p>
<p>   THEN RETURN &#8216;FALSE&#8217;;</p>
<p>  WHEN pkg_bank_holidays.fn_is_bank_holiday(fromdate + noofdays)</p>
<p>   THEN RETURN &#8216;FALSE&#8217;;</p>
<p>  ELSE</p>
<p>  RETURN &#8216;TRUE&#8217;;</p>
<p>END CASE;</p>
<p>EXCEPTION</p>
<p>WHEN OTHERS THEN</p>
<p>  RETURN &#8216;FALSE&#8217;;</p>
<p>END;</p>
<p>/</p>
<p>SQL&gt; SELECT isWorkingDay(TO_DATE(&#8217;10-Aug-2010&#8242;,&#8217;dd-mon-yyyy&#8217;), 0) &#8220;Working Day?&#8221;</p>
<p>  2    FROM DUAL</p>
<p>  3  /</p>
<p>Working Day?</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>TRUE</p>
<p>2)      Get the next or previous working day after a number of days in the future</p>
<p>CREATE OR REPLACE FUNCTION NextWorkingDay</p>
<p> ( FromDate IN DATE DEFAULT SYSDATE, NoOfDays IN NUMBER DEFAULT 0 )</p>
<p>  RETURN DATE AS</p>
<p>   v_ReturnDate DATE ;</p>
<p>BEGIN</p>
<p>  v_ReturnDate := FromDate + NoOfDays;</p>
<p>  WHILE (IsWorkingDay(v_ReturnDate,0) = &#8216;FALSE&#8217;) LOOP</p>
<p>    v_ReturnDate := v_ReturnDate + sign(NoOfDays);</p>
<p>  END LOOP;</p>
<p>  RETURN v_ReturnDate;</p>
<p>EXCEPTION</p>
<p> WHEN OTHERS THEN</p>
<p>    RETURN null;</p>
<p>END NextWorkingDay;</p>
<p>/</p>
<p>SQL&gt; SELECT NextWorkingDay(TO_DATE(&#8217;10-Aug-2010&#8242;,&#8217;dd-mon-yyyy&#8217;),5) &#8220;Next Work Day&#8221;</p>
<p>  2    FROM DUAL</p>
<p>  3  /</p>
<p>Next Work</p>
<p>&#8212;&#8212;&#8212;</p>
<p>16-AUG-10</p>
<pre><span id="more-18"></span></pre>
<p>CREATE OR REPLACE PACKAGE pkg_bank_holidays AS<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* Title       : BANK HOLIDAYS                                                  *<br />
&#8211;*                                                                              *<br />
&#8211;* Category    : Utility Functions                                              *<br />
&#8211;*                                                                              *<br />
&#8211;* Type        : Package Spec                                                   *<br />
&#8211;* Description : Given a year, each function will return the date for a         *<br />
&#8211;*               particular bank holiday for that year.                         *<br />
&#8211;*               The function fn_is_bank_holiday will receive a date and return *<br />
&#8211;*               TRUE if that date is a bank holiday.                           *<br />
&#8211;*               The year in each case must be a four digit number.             *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* (c) Copyright Zog-Bit 2009                                                   *<br />
&#8211;* <a href="http://www.zogbit.com">http://www.zogbit.com</a>                                                        *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;*               THE DATES FOR EASTER ARE ACCURATE UNTIL THE YEAR 4099          *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                      M O D I F I C A T I O N  L O G                          *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* Date        Author              Version  Description                         *<br />
&#8211;* &#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;   &#8212;&#8212;-  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*<br />
&#8211;* 28/10/2009  Zog Gibbens          1.0      Initial Version                    *<br />
&#8211;* 07/01/2009  Zog Gibbens          1.1      Added the function                 *<br />
&#8211;*                                           fn_queen_diamond_jubilee_day for   *<br />
&#8211;*                                           Queen&#8217;s Diamond Jubilee in 2012.   *<br />
&#8211;********************************************************************************<br />
 <br />
  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the New Year Bank Holiday<br />
  function fn_new_year_day(p_year number) return date;</p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the Good Friday Bank Holiday<br />
  function fn_good_friday(p_year number) return date;<br />
 <br />
  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the Easter Day (Sunday, not a bank holiday!)<br />
  function fn_easter_day(p_year number) return date; </p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the Easter Monday Bank Holiday<br />
  function fn_easter_monday(p_year number) return date; <br />
 <br />
  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the May Day Bank Holiday<br />
  function fn_may_day(p_year number) return date;<br />
 <br />
  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the May Whitsun Bank Holiday (last Monday in May)<br />
  function fn_may_whitsun(p_year number) return date;<br />
 <br />
  &#8212; Returns the date of the Queen&#8217;s Diamond Jubilee bank holiday<br />
  function fn_queen_diamond_jubilee_day return date;</p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the August Bank Holiday for Scotland<br />
  function fn_august_holiday_scotland(p_year number) return date;</p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the August Bank Holiday<br />
  function fn_august_holiday(p_year number) return date;</p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the Christmas Bank Holiday (not always 25/12)<br />
  function fn_christmas_day(p_year number) return date;</p>
<p>  &#8212; Receives the year as a parameter and returns the date for<br />
  &#8212; the Boxing Day Bank Holiday (not always 26/12)<br />
  function fn_boxing_day(p_year number) return date;<br />
 <br />
  &#8212; Receives a date and returns<br />
  &#8211;  TRUE  &#8211; if the date is a bank holiday<br />
  &#8211;  FALSE &#8211; if the day is not a bank holiday<br />
  function fn_is_bank_holiday(p_date date) return boolean;</p>
<p>end pkg_bank_holidays;<br />
/<br />
CREATE OR REPLACE PACKAGE BODY pkg_bank_holidays as<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* Title       : BANK HOLIDAYS                                                  *<br />
&#8211;*                                                                              *<br />
&#8211;* Category    : Utility Functions                                              *<br />
&#8211;*                                                                              *<br />
&#8211;* Type        : Package Body                                                   *<br />
&#8211;* Description : Given a year, each function will return the date for a         *<br />
&#8211;*               particular bank holiday for that year.                         *<br />
&#8211;*               The function fn_is_bank_holiday will receive a date and return *<br />
&#8211;*               TRUE if that date is a bank holiday.                           *<br />
&#8211;*               The year in each case must be a four digit number.             *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* (c) Copyright Zog-Bit 2009                                                   *<br />
&#8211;* <a href="http://www.zogbit.com">http://www.zogbit.com</a>                                                        *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;*               THE DATES FOR EASTER ARE ACCURATE UNTIL THE YEAR 4099          *<br />
&#8211;*                                                                              *<br />
&#8211;********************************************************************************<br />
&#8211;*                      M O D I F I C A T I O N  L O G                          *<br />
&#8211;********************************************************************************<br />
&#8211;*                                                                              *<br />
&#8211;* Date        Author              Version  Description                         *<br />
&#8211;* &#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;   &#8212;&#8212;-  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*<br />
&#8211;* 28/10/2009  Zog Gibbens          1.0      Initial Version                    *<br />
&#8211;* 07/01/2009  Zog Gibbens          1.1      Changes to the Whistun holidays due*<br />
&#8211;*                                           to the Queen&#8217;s Diamond celebrations*<br />
&#8211;*                                           Whitsun bank holiday as the date   *<br />
&#8211;*                                           has been moved to June 4th for 2012*<br />
&#8211;*                                           instead of the last day in May.    *<br />
&#8211;*                                           Additional bank holiday on June 5th*<br />
&#8211;*                                           officially for the Diamond Jubilee.*<br />
&#8211;********************************************************************************<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_easter_day<br />
  &#8211;    Based on the code written by Ronald Mallen, April 2002<br />
  &#8211;                                 <a href="http://www.assa.org.au/edm.html#Computer">http://www.assa.org.au/edm.html#Computer</a><br />
  &#8211;    Converted to PL/SQL from VB by Zog Gibbens<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_easter_day(p_year number) return date<br />
  is<br />
       firstdig integer;<br />
       remain19 integer;<br />
       temp integer;<br />
       v_easter_day date;<br />
      <br />
       tA  integer;<br />
       tB  integer;<br />
       tC  integer;<br />
       tD  integer;<br />
       tE  integer;<br />
       d   integer;<br />
       m   integer;<br />
       y   integer;<br />
    begin<br />
       y := p_year;<br />
       firstdig := floor(y / 100);<br />
       remain19 := mod(y, 19);<br />
      <br />
       &#8212; calculate PFM date<br />
       temp := (floor(((FirstDig &#8211; 15) / 2)) + 202) &#8211; (11 * Remain19);<br />
      <br />
       case<br />
            when firstdig in (21, 24, 25, 27, 28, 29, 30, 31, 32, 34, 35, 38)<br />
                 then temp := temp &#8211; 1;<br />
            when firstdig in (33, 36, 37, 39, 40)<br />
                 then temp := temp &#8211; 2;<br />
            else null;<br />
       end case;<br />
      <br />
       temp := mod(temp,30);<br />
       tA := temp + 21;<br />
      <br />
       If temp = 29 Then tA := tA &#8211; 1; end if;<br />
       If (temp = 28 And Remain19 &gt; 10) Then tA := tA &#8211; 1; end if;<br />
      <br />
       &#8212; find the next Sunday<br />
       tB := mod((tA &#8211; 19), 7);<br />
       tC := mod((40 &#8211; FirstDig), 4);<br />
      <br />
       If tC = 3 Then tC := tC + 1; end if;<br />
       If tC &gt; 1 Then tC := tC + 1; end if;<br />
      <br />
       temp := mod(y, 100);<br />
       tD := mod((temp + (floor(temp / 4))), 7);<br />
       tE := (mod((20 &#8211; tB &#8211; tC &#8211; tD), 7)) + 1;<br />
       d := tA + tE;<br />
      <br />
       &#8212; return the date<br />
       If d &gt; 31 Then<br />
          d := d &#8211; 31;<br />
          m := 4;<br />
       Else<br />
          m := 3;<br />
       End If;</p>
<p>       v_easter_day := to_date( lpad(d,2,&#8217;0&#8242;) || lpad(m,2,&#8217;0&#8242;) || p_year, &#8216;DDMMYYYY&#8217;);</p>
<p>       return v_easter_day;</p>
<p>  end fn_easter_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_new_year_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Simply based on 01/01/YYYY, checks if this is a Saturday or Sunday and<br />
  &#8211;    adds the number of days to 01/01/YYYY as necessary<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_new_year_day(p_year number) return date<br />
  is<br />
     v_date date;<br />
  begin<br />
 <br />
     v_date := to_date(&#8217;0101&#8242; || to_char(p_year), &#8216;DDMMYYYY&#8217;);<br />
 <br />
     case trim(to_char(v_date, &#8216;DAY&#8217;))<br />
          when &#8216;SATURDAY&#8217; THEN v_date := v_date + 2;<br />
          WHEN &#8216;SUNDAY&#8217;   THEN v_date := v_date + 1;<br />
          ELSE null;<br />
     END CASE;<br />
 <br />
     RETURN v_date;<br />
 <br />
  end fn_new_year_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_good_friday<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Uses the fn_easter_day to get the date for Easter Day, then substracts 2<br />
  &#8211;    days from this date.<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_good_friday(p_year number) return date<br />
  IS<br />
  BEGIN</p>
<p>     return fn_easter_day(p_year) &#8211; 2;</p>
<p>  END fn_good_friday;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_easter_monday<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Uses the fn_easter_day to get the date for Easter Day, then adds 1 day<br />
  &#8211;    to this date.<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_easter_monday(p_year number) return date<br />
  IS<br />
  BEGIN</p>
<p>     return fn_easter_day(p_year) + 1;</p>
<p>  END fn_easter_monday; <br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_may_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Uses the 1st May, then works out the date for the first Monday of the month<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_may_day(p_year number) return date<br />
  is<br />
    v_date date;<br />
  begin</p>
<p>    v_date := to_date(&#8217;0105&#8242; || p_year, &#8216;DDMMYYYY&#8217;);</p>
<p>       Case trim (to_char(v_date, &#8216;Day&#8217;))<br />
            when &#8216;Monday&#8217; then return v_date;<br />
            when &#8216;Tuesday&#8217; then return v_date + 6;<br />
            when &#8216;Wednesday&#8217; then return v_date + 5;<br />
            when &#8216;Thursday&#8217; then return v_date + 4;<br />
            when &#8216;Friday&#8217; then return v_date + 3;<br />
            when &#8216;Saturday&#8217; then return v_date + 2;<br />
            when &#8216;Sunday&#8217; then return v_date + 1;<br />
            else return null;<br />
      end case;</p>
<p>  end fn_may_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_whitsun_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Gets the last day of May, then works out the date for the previous Monday <br />
  &#8211;    Modification for 2012 &#8211; Whitsun has been moved to the first Monday in June<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_may_whitsun(p_year number) return date<br />
  is<br />
    v_date date;<br />
  begin<br />
 <br />
    if p_year = 2012 then</p>
<p>       v_date := to_date(&#8217;0106&#8242; || p_year, &#8216;DDMMYYYY&#8217;);</p>
<p>       Case trim (to_char(v_date, &#8216;Day&#8217;))<br />
            when &#8216;Monday&#8217; then return v_date;<br />
            when &#8216;Tuesday&#8217; then return v_date + 6;<br />
            when &#8216;Wednesday&#8217; then return v_date + 5;<br />
            when &#8216;Thursday&#8217; then return v_date + 4;<br />
            when &#8216;Friday&#8217; then return v_date + 3;<br />
            when &#8216;Saturday&#8217; then return v_date + 2;<br />
            when &#8216;Sunday&#8217; then return v_date + 1;<br />
            else return null;<br />
      end case;</p>
<p>    else</p>
<p>       v_date := last_day(to_date(&#8217;0105&#8242; || p_year, &#8216;DDMMYYYY&#8217;));</p>
<p>       Case trim (to_char(v_date, &#8216;Day&#8217;))<br />
            when &#8216;Monday&#8217; then return v_date;<br />
            when &#8216;Tuesday&#8217; then return v_date &#8211; 1;<br />
            when &#8216;Wednesday&#8217; then return v_date &#8211; 2;<br />
            when &#8216;Thursday&#8217; then return v_date &#8211; 3;<br />
            when &#8216;Friday&#8217; then return v_date &#8211; 4;<br />
            when &#8216;Saturday&#8217; then return v_date &#8211; 5;<br />
            when &#8216;Sunday&#8217; then return v_date &#8211; 6;<br />
            else return null;<br />
      end case;</p>
<p>    end if;</p>
<p>  end fn_may_whitsun;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_queen_diamond_jubilee_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    A new bank holiday for the Queen&#8217;s Diamond Jubilee, date is fixed as     <br />
  &#8211;    Tuesday June 5th 2012.<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_queen_diamond_jubilee_day return date<br />
  is<br />
    v_date date := to_date(&#8217;05/06/2012&#8242;, &#8216;DD/MM/YYYY&#8217;);<br />
  begin<br />
 <br />
     return v_date;<br />
   <br />
  end fn_queen_diamond_jubilee_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_august_holiday_scotland<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Gets the first day of August, then works out the date for first Monday <br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_august_holiday_scotland(p_year number) return date<br />
  is<br />
    v_date date;<br />
  begin</p>
<p>    v_date := to_date(&#8217;0108&#8242; || p_year, &#8216;DDMMYYYY&#8217;);</p>
<p>       Case trim (to_char(v_date, &#8216;Day&#8217;))<br />
            when &#8216;Monday&#8217; then return v_date;<br />
            when &#8216;Tuesday&#8217; then return v_date + 6;<br />
            when &#8216;Wednesday&#8217; then return v_date + 5;<br />
            when &#8216;Thursday&#8217; then return v_date + 4;<br />
            when &#8216;Friday&#8217; then return v_date + 3;<br />
            when &#8216;Saturday&#8217; then return v_date + 2;<br />
            when &#8216;Sunday&#8217; then return v_date + 1;<br />
            else return null;<br />
      end case;</p>
<p>  end fn_august_holiday_scotland;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_august_holiday<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Gets the last day of August, then works out the date for the previous Monday <br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_august_holiday(p_year number) return date<br />
  is<br />
    v_date date;<br />
  begin</p>
<p>    v_date := last_day(to_date(&#8217;0108&#8242; || p_year, &#8216;DDMMYYYY&#8217;));</p>
<p>       Case trim (to_char(v_date, &#8216;Day&#8217;))<br />
            when &#8216;Monday&#8217; then return v_date;<br />
            when &#8216;Tuesday&#8217; then return v_date &#8211; 1;<br />
            when &#8216;Wednesday&#8217; then return v_date &#8211; 2;<br />
            when &#8216;Thursday&#8217; then return v_date &#8211; 3;<br />
            when &#8216;Friday&#8217; then return v_date &#8211; 4;<br />
            when &#8216;Saturday&#8217; then return v_date &#8211; 5;<br />
            when &#8216;Sunday&#8217; then return v_date &#8211; 6;<br />
            else return null;<br />
      end case;</p>
<p>  end fn_august_holiday;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_christmas_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Simply based on 25/12/YYYY, checks if this is a Saturday or Sunday and<br />
  &#8211;    adds the number of days to 25/12/YYYY as necessary<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_christmas_day(p_year number) return date<br />
  is<br />
     v_date date;<br />
  begin<br />
 <br />
     v_date := to_date(&#8217;2512&#8242; || to_char(p_year), &#8216;DDMMYYYY&#8217;);</p>
<p>     case trim(to_char(v_date, &#8216;DAY&#8217;))<br />
          when &#8216;SATURDAY&#8217; THEN v_date := v_date + 2;<br />
          WHEN &#8216;SUNDAY&#8217;   THEN v_date := v_date + 1;<br />
          ELSE null;<br />
     END CASE;</p>
<p>     RETURN v_date;</p>
<p>  end fn_christmas_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_boxing_day<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Simply based on 26/12/YYYY, checks if this is a Saturday or Sunday and<br />
  &#8211;    adds the number of days to 26/12/YYYY as necessary<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_boxing_day(p_year number) return date<br />
  is<br />
     v_date date;<br />
  begin<br />
 <br />
     v_date := to_date(&#8217;2612&#8242; || to_char(p_year), &#8216;DDMMYYYY&#8217;);<br />
 <br />
     CASE trim(to_char(v_date, &#8216;DAY&#8217;))<br />
          WHEN &#8216;SATURDAY&#8217; THEN v_date := v_date + 2;<br />
          WHEN &#8216;SUNDAY&#8217;   THEN v_date := v_date + 2;<br />
          WHEN &#8216;MONDAY&#8217;   THEN v_date := v_date + 1;<br />
          ELSE null;<br />
     END CASE;<br />
 <br />
     RETURN v_date;<br />
 <br />
  end fn_boxing_day;<br />
  &#8211;<br />
  &#8211;<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  &#8212; fn_is_bank_holiday<br />
  &#8211;    Written by Zog Gibbens<br />
  &#8211;    Recieves a date, checks the month to see if it is a month with a potential<br />
  &#8211;    bank holiday (hard coded), if so, checks the date against the relevant<br />
  &#8211;    bank holiday function, if a match is found returns true, otherwise returns<br />
  &#8211;    false.<br />
  &#8212; &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -<br />
  function fn_is_bank_holiday(p_date date) return boolean<br />
  is<br />
 <br />
    v_month number;<br />
    v_bank_holiday date;<br />
    v_year number;<br />
   <br />
  begin<br />
 <br />
    v_month := to_number(to_char(p_date, &#8216;MM&#8217;));<br />
    v_year := to_number(to_char(p_date, &#8216;YYYY&#8217;));<br />
   <br />
    case<br />
       when v_month = 1<br />
         then v_bank_holiday := fn_new_year_day(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                return false;<br />
              end if;<br />
       when v_month = 3<br />
         then v_bank_holiday := fn_good_friday(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                v_bank_holiday := fn_easter_monday(v_year);<br />
                if p_date = v_bank_holiday then<br />
                  return true;<br />
                else<br />
                  return false;<br />
                end if;<br />
              end if;<br />
       when v_month = 4<br />
         then v_bank_holiday := fn_good_friday(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                v_bank_holiday := fn_easter_monday(v_year);<br />
                if p_date = v_bank_holiday then<br />
                  return true;<br />
                else<br />
                  return false;<br />
                end if;<br />
              end if;<br />
       when v_month = 5<br />
         then v_bank_holiday := fn_may_day(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                v_bank_holiday := fn_may_whitsun(v_year);<br />
                if p_date = v_bank_holiday then<br />
                  return true;<br />
                else<br />
                  return false;<br />
                end if;<br />
              end if;<br />
       when v_month = 6 and v_year = 2012<br />
         then v_bank_holiday := fn_may_whitsun(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                v_bank_holiday := fn_queen_diamond_jubilee_day();<br />
                if p_date = v_bank_holiday then<br />
                  return true;<br />
                else<br />
                  return false;<br />
                end if;<br />
              end if;<br />
       when v_month = 8<br />
         then v_bank_holiday := fn_august_holiday(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                return false;<br />
              end if;<br />
       when v_month = 12<br />
         then v_bank_holiday := fn_christmas_day(v_year);<br />
              if p_date = v_bank_holiday then<br />
                return true;<br />
              else<br />
                v_bank_holiday := fn_boxing_day(v_year);<br />
                if p_date = v_bank_holiday then<br />
                  return true;<br />
                else<br />
                  return false;<br />
                end if;<br />
              end if;<br />
        else return false;<br />
    end case;<br />
   <br />
  end fn_is_bank_holiday;<br />
 <br />
end pkg_bank_holidays;<br />
/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zogbit.com/2010/07/bank-holidays-algorithm-versus-table/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

