<?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>Zona J &#187; plsql</title>
	<atom:link href="http://zonaj.org/category/plsql/feed/" rel="self" type="application/rss+xml" />
	<link>http://zonaj.org</link>
	<description>Zona Java - Um blog português sobre java.</description>
	<lastBuildDate>Sun, 29 Jun 2014 18:29:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>De DBMS_JOB para DBMS_SCHEDULER: o Deploy</title>
		<link>http://zonaj.org/2007/05/31/de-dbms_job-para-dbms_scheduler-o-deploy/</link>
		<comments>http://zonaj.org/2007/05/31/de-dbms_job-para-dbms_scheduler-o-deploy/#comments</comments>
		<pubDate>Thu, 31 May 2007 10:49:59 +0000</pubDate>
		<dc:creator><![CDATA[bgoncalves]]></dc:creator>
				<category><![CDATA[plsql]]></category>

		<guid isPermaLink="false">http://www.zonaj.org/?p=42</guid>
		<description><![CDATA[Nos últimos tempos tenho trabalhado com jobs em base de dados Oracle. Mesmo que a base de dados utilizada fosse a 10g é ainda utilizado o DBMS_JOB. Recentemente li o [1] e descobri o DBMS_SCHEDULER. Dou dois buying cialis online exemplos de dificuldades que senti com o DBMS_JOB: definir o intervalo de execução: fraca legibilidade, &#8230; <a href="http://zonaj.org/2007/05/31/de-dbms_job-para-dbms_scheduler-o-deploy/" class="more-link">Continue reading <span class="screen-reader-text">De DBMS_JOB para DBMS_SCHEDULER: o Deploy</span></a>]]></description>
				<content:encoded><![CDATA[<p>
Nos últimos tempos tenho trabalhado com jobs em base de dados Oracle.<br />
Mesmo que a base de dados utilizada fosse a 10g é ainda utilizado o <code>DBMS_JOB</code>. Recentemente li o [1] e descobri o <code>DBMS_SCHEDULER</code>.
</p>
<p>
Dou dois
<div style="display: none"><a href='http://cialispricee.com/' title='buying cialis online'>buying cialis online</a></div>
<p>exemplos de dificuldades que senti com o <code>DBMS_JOB</code>:</p>
<ul>
<li>definir o intervalo de execução: fraca legibilidade, demasiado código para conseguir o agendamento desejado;
  </li>
<li>configurar o deploy de um job: apenas um campo númérico identifica univocamente o job na lista.
  </li>
</ul>
<p>Neste post vou falar sobre o segundo ponto: o deploy de um job.
</p>
<h3>Oracle 9i: o DBMS_JOB</h3>
<p>
Na versão 9i a gestão de jobs é feita com o package <code>DBMS_JOB</code>.<br />
Eis o script de deploy mais simples:</p>
<pre class="prettyprint">
DECLARE
  V_JOB NUMBER;
BEGIN
  DBMS_JOB.SUBMIT(
		JOB => V_JOB,
		WHAT => 'BEGIN MY_PKG.MY_EXEC_PROC; END;',
		NEXT_DATE => SYSDATE);
  commit;
  dbms_output.put_line('Created MY_PKG.MY_EXEC_PROC <div style="display: none"><a href='http://thecheap-cialis.org/' title='buy cheap cialis'>buy cheap cialis</a></div> job: '||v_job);
END;
/ </pre>
<p>Este script tem o seguinte problema: se executarmos o script outra vez o resultado vai ser a criação de outro job igual ao primeiro. Este foi alias a situação com que me deparei de início: a base de dados tinha dezenas de jobs a realizar a mesma tarefa!
</p>
<p>
Posto o problema de apenas o campo <code>job</code> (do tipo número) identificar univocamente o job, utilizei o campo <code>what</code> para o identificar. Criei o seguinte script de deploy:</p>
<pre class="prettyprint">
DECLARE
  V_JOB NUMBER;
  V_WHAT VARCHAR2(100) := 'BEGIN MY_PKG.MY_EXEC_PROC; END;';
  V_NEXT_DATE DATE := SYSDATE;
BEGIN
  dbms_output.put_line('Deleting all MY_PKG.MY_EXEC_PROC jobs:');
	FOR jobs_to_delete IN (
    SELECT  job
	    FROM user_jobs 
	    WHERE what like V_WHAT
   ) LOOP
     dbms_output.put_line('...removing MY_PKG.MY_EXEC_PROC job ' || jobs_to_delete.job);
     dbms_job.remove(jobs_to_delete.job);
  END LOOP;
  dbms_output.put_line('Deleted all MY_PKG.MY_EXEC_PROC jobs.');
  commit;
  
  DBMS_JOB.SUBMIT(V_JOB, V_WHAT, V_NEXT_DATE);
  commit;
  dbms_output.put_line('Created MY_PKG.MY_EXEC_PROC job: '||v_job);
END;
/ </pre>
<p>Reparar no loop para resolver o caso de fazerem deploy do mesmo job.<br />
Este script não resolve outro problema: se numa fase de desenvolvimento alterarmos o <code>what</code> do job não iremos remover os jobs antigos &#8211; claro que esta situação tem pouco impacto com algum controlo regular sobre o que existe na base de dados.
</p>
<p>
Este script poderia ser isolado num procedimento com a assinatura</p>
<pre class="prettyprint">
  DEPLOY_JOB(
		job       OUT BINARY_INTEGER,
		what      IN  VARCHAR2,
		next_date IN  DATE DEFAULT sysdate,
		interval  IN  VARCHAR2 DEFAULT 'null',
		job_name  IN  VARCHAR2);   -- 'job_name' serve apenas para dbms_output
</pre>
<p>que não é mais do que estender as funcionalidades do <code>DBMS_JOB.SUBMIT</code>.
</p>
<h3>Oracle 10g: o DBMS_SCHEDULER</h3>
</p>
<p>Mas eis que a 10g apresenta uma solução muito mais completa: o package <code>DBMS_SCHEDULER</code>.
</p>
<p>
Eis o novo script de deploy proposto</p>
<pre class="prettyprint">
DECLARE
  V_JOB_NAME VARCHAR2(100) := 'MY_PKG_MY_EXEC_PROC';
BEGIN
  DBMS_SCHEDULER.DROP_JOB( 
    job_name          =>  V_JOB_NAME );
  DBMS_SCHEDULER.CREATE_JOB(
		job_name          =>  V_JOB_NAME,
		job_type          =>  'PLSQL_BLOCK',
		job_action        =>  'BEGIN MY_PKG.MY_EXEC_PROC; END;');
		start_date        =>  SYSDATE );
END;
/ </pre>
</p>
<p>
<i><b>job_name</b><br />
This attribute specifies the name of the job and uniquely identifies the job.<br />
The name has to be unique in the SQL namespace. For example, a job cannot have the same name as a table in a schema.<br />
<br />
If job_name is not specified, an error is generated. If you want to have a name generated by the Scheduler, you can use the GENERATE_JOB_NAME procedure to generate a name and then use the output in the CREATE_JOB procedure. The GENERATE_JOB_NAME procedure call generates a number from a sequence, which is the job name. You can prefix the number with a string. The job name will then be the string with the number from the sequence appended to it. </i>
</p>
<p>
Além do job ter um identificador descritivo, não é apenas único na lista de jobs mas também em todo o schema.
</p>
<p>
E com o <code>DBMS_SCHEDULER.GENERATE_JOB_NAME</code> nem precisariamos de nos preocupar com o nome do job, similar ao <code>DBMS_JOBS</code>.<br />
E óptimo disponibilizar a geração de valores para <code>job_name</code> com prefixo, muito útil em aplicações que geram internamente jobs e que teriam de implementar esta geração do nome.
</p>
<p>
<strong>Nota importante</strong>: ao contrário do <code>DBMS_JOB.SUBMIT</code>, o <code>DBMS_SCHEDULER.CREATE_JOB</code> faz commit, tentando ser similar a um statement DDL.
</p>
<p><b>Leituras</b></p>
<ul>
<li>[1] Oracle Database Administrator&#8217;s Guide 10g Release 1 (<a target="_blank" href="http://www.oracle.com">http://www.oracle.com</a>)
  </li>
<li>[2] PLSQL Packages and Types Reference 10g Release 1 (<a target="_blank" href="http://www.oracle.com">http://www.oracle.com</a>)
  </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://zonaj.org/2007/05/31/de-dbms_job-para-dbms_scheduler-o-deploy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
