<?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>glufke.net &#187; SQL</title>
	<atom:link href="http://glufke.net/category/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://glufke.net</link>
	<description></description>
	<lastBuildDate>Thu, 15 Apr 2010 03:46:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Local Index vs. Global Index em tabela particionada</title>
		<link>http://glufke.net/2010/03/31/local-index-vs-global-indexem-tabela-particionada/</link>
		<comments>http://glufke.net/2010/03/31/local-index-vs-global-indexem-tabela-particionada/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 12:51:45 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[Oracle 10g]]></category>
		<category><![CDATA[Oracle 11g]]></category>
		<category><![CDATA[Partition]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=207</guid>
		<description><![CDATA[A maioria das pessoas tem essas perguntas sobre Index Partition:

O que é um Local Index?
O que é um Global Index?
Quando você forçaria a criação de um Global Index em uma partition table?
Quando você recomendaria criar um Global Index em vez de um Local Index?

Para responder a essas perguntas&#8230;.
1. O que é um Local Index?
Local Indexes [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" src="http://www.cs.duke.edu/courses/fall08/cps274/images/gear.jpg" alt="" width="164" height="164" />A maioria das pessoas tem essas perguntas sobre Index Partition:</p>
<ul>
<li><strong>O que é um Local Index?</strong></li>
<li><strong>O que é um Global Index?</strong></li>
<li><strong>Quando você forçaria a criação de um Global Index em uma partition table?</strong></li>
<li><strong>Quando você recomendaria criar um Global Index em vez de um Local Index?</strong></li>
</ul>
<p>Para responder a essas perguntas&#8230;.</p>
<h3>1. O que é um Local Index?</h3>
<p>Local Indexes particionados são mais fáceis de gerenciar, cada partição do Local Index está associado a uma partição. Eles também oferecem maior disponibilidade e são comuns em ambientes de DSS. Quando tomamos qualquer ação (MERGE, SPLIT,EXCHANGE etc) em um Local Index, isso impacta apenas aquela partição e as outras estarão disponíveis. Nós não podemos adicionar explicitamente um Local Index para uma nova partição. O Local Index será adicionado implicitamente a nova partição, quando for criada uma nova partição na tabela. Da mesma forma, não podemos dropar o índice local em uma partição específica. Ele pode ser dropado automaticamente quando nós dropamos a partição da tabela subjacente. Local Indexes podem ser UNIQUE quando a chave da partição é parte do índice composto. Unique Local Indexes são úteis para o ambiente OLTP. Podemos também criar bitmap indexes em tabelas, com a restrição de que os índices de bitmap deve ser local para a tabela particionada. Eles não podem ser Global Indexes.</p>
<pre class="brush: plain;">SQL&gt; CREATE TABLE employees
2 (employee_id NUMBER(4) NOT NULL,
3 last_name VARCHAR2(10),
4 department_id NUMBER(2))
5 PARTITION BY RANGE (department_id)
6 (PARTITION employees_part1 VALUES LESS THAN (10) TABLESPACE ODS_STAGE_DATA,
7 PARTITION employees_part2 VALUES LESS THAN (20) TABLESPACE ODS_STAGE_DATA,
8 PARTITION employees_part3 VALUES LESS THAN (30) TABLESPACE ODS_STAGE_DATA);

Table created.

SQL&gt; declare
2 v_no number :=1;
3 begin
4 delete employees;
5 for i in 1..10 loop
6 insert into employees values(v_no,'name...',v_no);
7 v_no := v_no+1;
8 end loop;
9 end;
10 /

PL/SQL procedure successfully completed.

SQL&gt;
SQL&gt; create index idx_local on employees(last_name) local;

Index created.

SQL&gt;</pre>
<p><span id="more-207"></span></p>
<div id="ads_336x280"><script type="text/javascript">// <![CDATA[
 google_ad_client = "pub-8964513116661040"; google_alternate_color = "ffffFF"; google_ad_width = 336; google_ad_height = 280; google_ad_format = "336x280_as"; google_ad_type = "text_image"; //2007-09-07: wp_quadrado_gra google_ad_channel = "0247072216"; google_color_border = "FFFFFF"; google_color_bg = "FFFFff"; google_color_link = "4F82CB"; google_color_text = "000000"; google_color_url = "4F82CB";
// ]]&gt;</script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></div>
<h3>2. O que é Global Index?</h3>
<p>Global Indexe são usado em ambientes OLTP e oferecem um acesso eficiente a qualquer registro individual. Temos dois tipos de Global Index: Eles são <strong>global Non-partitioned index</strong> e <strong>Global partitioned index</strong>. Global Non-partitioned index se comportam como um índice não particionado.</p>
<p>A chave de partição de um Global partitioned index é independente da chave de partição da tabela. A maior partição de um Global Index deve ter um limite de partição, cujos todos valores são MAXVALUE. Se você quiser adicionar uma nova partição, sempre, é preciso dividir a partição MAX. Se um Global Index Partition está vazio, você pode dropá-lo explicitamente com um ALTER INDEX DROP PARTITION. Se um Global Index Partition contém dados, ao dropar a partição faz com que a partição mais próxima seja marcada como inutilizável. Não é possível dropar a maior partição de um índice global.</p>
<p><strong>Exemplo de  Global Non-partitioned index:</strong></p>
<pre class="brush: plain;">SQL&gt; CREATE INDEX employees_global_idx ON employees(employee_id);

Index created.

SQL&gt;</pre>
<p><strong>Exemplo de Global Partitioned index:</strong></p>
<pre class="brush: plain;">SQL&gt; CREATE INDEX employees_global_part_idx ON employees(employee_id)
2 GLOBAL PARTITION BY RANGE(employee_id)
3 (PARTITION p1 VALUES LESS THAN(3),
4 PARTITION p2 VALUES LESS THAN(6),
5 PARTITION p3 VALUES LESS THAN(9));
PARTITION p3 VALUES LESS THAN(9))
*
ERROR at line 5:
ORA-14021: MAXVALUE must be specified for all columns

SQL&gt; CREATE INDEX employees_global_part_idx ON employees(employee_id)
2 GLOBAL PARTITION BY RANGE(employee_id)
3 (PARTITION p1 VALUES LESS THAN(3),
4 PARTITION p2 VALUES LESS THAN(6),
5 PARTITION p3 VALUES LESS THAN(11),
6 PARTITION p4 VALUES LESS THAN(20),
7 PARTITION p5 VALUES LESS THAN(MAXVALUE));

Index created.</pre>
<p>Agora a partição p4 está vazia. Vamos dropar a partição vazia e ver o status:</p>
<pre class="brush: plain;">SQL&gt; select count(*) from employees where
2 employee_id between 12 and 20;

COUNT(*)
----------
0
SQL&gt; ALTER index employees_global_part_idx drop partition p4;

Index altered.

SQL&gt; SELECT partition_name,status from user_ind_partitions where
2 index_name='EMPLOYEES_GLOBAL_PART_IDX';

PARTITION_NAME STATUS
------------------------------ --------
P1 USABLE
P2 USABLE
P3 USABLE
P5 USABLE</pre>
<p>Agora vamos dropar a partição P3 e ver o estado. Ao dropar essa partição, isso deve invalidar a partição mais próxima. Aqui a partição P5 é a próxima maior partição.</p>
<pre class="brush: plain;">SQL&gt; alter index employees_global_part_idx drop partition p3;

Index altered.

SQL&gt; SELECT partition_name,status from user_ind_partitions where
2 index_name='EMPLOYEES_GLOBAL_PART_IDX';

PARTITION_NAME STATUS
------------------------------ --------
P1 USABLE
P2 USABLE
P5 UNUSABLE

SQL&gt; alter index employees_global_part_idx rebuild;
alter index employees_global_part_idx rebuild
*
ERROR at line 1:
ORA-14086: a partitioned index may not be rebuilt as a whole

SQL&gt; alter index employees_global_part_idx rebuild partition p5;

Index altered.

SQL&gt; SELECT partition_name,status from user_ind_partitions where
2 index_name='EMPLOYEES_GLOBAL_PART_IDX';

PARTITION_NAME STATUS
------------------------------ --------
P1 USABLE
P2 USABLE
P5 USABLE</pre>
<p>Partition Index podem ser mantidos usando UPDATE GLOBAL INDEXES. Os índice estarão disponíveis durante a manutenção e está disponível online. Nós não precisamos de rebuild o índice após a manutenção do índice.</p>
<p>Por exemplo,</p>
<pre class="brush: plain;">SQL&gt; alter table employees drop partition employees_part3
2 update global indexes;

Table altered.

SQL&gt; SELECT partition_name,status from user_ind_partitions where
2 index_name='EMPLOYEES_GLOBAL_PART_IDX';

PARTITION_NAME STATUS
------------------------------ --------
P1 USABLE
P2 USABLE
P5 USABLE

SQL&gt;</pre>
<h3>3. Quando você forçaria a criação de Global index em uma Partition table?</h3>
<p>Quando você cria uma chave primária, você será forçado a criar um Global Index. Quando você cria Unique Index, você é forçado a criar o Global Index. Manter a coluna única é a razão mais comum para os índices globais. Se você tentar criar um Local Index em chave única, você receberá o erro abaixo.</p>
<pre class="brush: plain;">ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE index</pre>
<p>Assim, podemos criar Local Index em chave única, quando adicionamos a chave de partição como parte da chave composta no índice. Vamos demonstrar isto:</p>
<p><strong>No exemplo abaixo, o Unique Index falhou já que a chave da partição não é parte da chave composta do índice.</strong></p>
<pre class="brush: plain;">SQL&gt; create unique index idx_emp_id on employees(employee_id) local;
create unique index idx_emp_id on employees(employee_id) local
*
ERROR at line 1:
ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE index</pre>
<p>No caso abaixo, ele permite criar um Global Index:</p>
<pre class="brush: plain;">SQL&gt; create unique index idx_emp_id on employees(employee_id);

Index created.

SQL&gt; drop index idx_emp_id;

Index dropped.</pre>
<p>O caso abaixo, o Unique Index é criado com sucesso, pois a chave DEPARTMENT_ID é parte da chave composta.</p>
<pre class="brush: plain;">SQL&gt; create unique index idx_emp_id on employees(employee_id,department_id) local;

Index created.

SQL&gt;</pre>
<h3>4. Quando você recomendaria criar Global Index vs. Local Index?</h3>
<p>Podemos usar Global Index se uma consulta retorna um número pequeno de linhas a partir de um número potencialmente grande de partições.</p>
<p><em>Texto baseado no blog do <a href="http://myorastuff.blogspot.com">Govind</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2010/03/31/local-index-vs-global-indexem-tabela-particionada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PLAN_TABLE faz aniversário de 21 anos em 19-out-2009</title>
		<link>http://glufke.net/2009/10/13/plan_table-faz-aniversario-de-21-anos-em-19-out-2009/</link>
		<comments>http://glufke.net/2009/10/13/plan_table-faz-aniversario-de-21-anos-em-19-out-2009/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 17:00:35 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Curiosidade]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=40</guid>
		<description><![CDATA[Pois é isso mesmo! A querida tabela do ORACLE que nos mostra o plano de execução dos SQLs hoje completa 21 anos!
Hoje eu fui olhar um plano de execução e me deparei com a seguinte mensagem:
SET AUTOTRACE ON
SELECT bla bla bla...

Execution Plan
----------------------------------------------------------

--------------------------------------------------------------
&#124; Id  &#124; Operation          [...]]]></description>
			<content:encoded><![CDATA[<p>Pois é isso mesmo! A querida tabela do ORACLE que nos mostra o plano de execução dos SQLs hoje completa 21 anos!<br />
Hoje eu fui olhar um plano de execução e me deparei com a seguinte mensagem:</p>
<pre class="brush: plain;">SET AUTOTRACE ON
SELECT bla bla bla...

Execution Plan
----------------------------------------------------------

--------------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Cost (%CPU)|
--------------------------------------------------------------
|   0 | SELECT STATEMENT   |            |     1 |   102   (0)|
|   1 |  SORT AGGREGATE    |            |     1 |            |
|   2 |   TABLE ACCESS FULL| TABELA     |  4322 |   102   (0)|
--------------------------------------------------------------

Note
-----
   - 'PLAN_TABLE' is old version</pre>
<p>PLAN_TABLE is old version ???<span id="more-40"></span></p>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//--></script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>Olhei no script de criação da nova PLAN_TABLE e descobri nos comentários a data de cada modificação: 19 de Outubro de 1988 !</p>
<pre class="brush: plain;">
rem
rem $Header: utlxplan.sql 29-oct-2001.20:28:58 mzait Exp $ xplainpl.sql
rem
Rem Copyright (c) 1988, 2001, Oracle Corporation.  All rights reserved.
Rem NAME
REM    UTLXPLAN.SQL
Rem  FUNCTION
Rem  NOTES
Rem  MODIFIED
Rem     mzait      10/26/01  - add keys and filter predicates to the plan table
Rem     ddas       05/05/00  - increase length of options column
Rem     ddas       04/17/00  - add CPU, I/O cost, temp_space columns
Rem     mzait      02/19/98 -  add distribution method column
Rem     ddas       05/17/96 -  change search_columns to number
Rem     achaudhr   07/23/95 -  PTI: Add columns partition_{start, stop, id}
Rem     glumpkin   08/25/94 -  new optimizer fields
Rem     jcohen     11/05/93 -  merge changes from branch 1.1.710.1 - 9/24
Rem     jcohen     09/24/93 - #163783 add optimizer column
Rem     glumpkin   10/25/92 -  Renamed from XPLAINPL.SQL
Rem     jcohen     05/22/92 - #79645 - set node width to 128 (M_XDBI in gendef)
Rem     rlim       04/29/91 -         change char to varchar2
Rem   Peeler     10/19/88 - Creation
Rem
Rem This is the format for the table that is used by the EXPLAIN PLAN
Rem statement.  The explain statement requires the presence of this
Rem table in order to store the descriptions of the row sources.

create table PLAN_TABLE (
	statement_id 	varchar2(30),
	timestamp    	date,
	remarks      	varchar2(80),
	operation    	varchar2(30),
	options       	varchar2(255),
	object_node  	varchar2(128),
	object_owner 	varchar2(30),
	object_name  	varchar2(30),
	object_instance numeric,
	object_type     varchar2(30),
	optimizer       varchar2(255),
	search_columns  number,
	id		numeric,
	parent_id	numeric,
	position	numeric,
	cost		numeric,
	cardinality	numeric,
	bytes		numeric,
	other_tag       varchar2(255),
	partition_start varchar2(255),
        partition_stop  varchar2(255),
        partition_id    numeric,
	other		long,
	distribution    varchar2(30),
	cpu_cost	numeric,
	io_cost		numeric,
	temp_space	numeric,
        access_predicates varchar2(4000),
        filter_predicates varchar2(4000));
</pre>
<p>Atingiu a maioridade! <img src='http://glufke.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   Feliz aniversário PLAN_TABLE!</p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2009/10/13/plan_table-faz-aniversario-de-21-anos-em-19-out-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Melhorias nos EXTERNAL TABLES do 10g</title>
		<link>http://glufke.net/2009/01/13/melhorias-nos-external-tables-do-10g/</link>
		<comments>http://glufke.net/2009/01/13/melhorias-nos-external-tables-do-10g/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 23:48:10 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[External Table]]></category>
		<category><![CDATA[Oracle 10g]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=37</guid>
		<description><![CDATA[A partir do Oracle 9i foi criado o conceito de EXTERNAL TABLES, ou seja, você cria uma tabela baseado num arquivo texto no sistema operacional e pode fazer consultas SQL nessa tabela (ou seja, diretamente no arquivo texto como se fosse uma tabela)
Agora a partir do oracle 10g é possível também criar um arquivo texto [...]]]></description>
			<content:encoded><![CDATA[<p>A partir do Oracle 9i foi criado o conceito de EXTERNAL TABLES, ou seja, você cria uma tabela baseado num arquivo texto no sistema operacional e pode fazer consultas SQL nessa tabela (ou seja, diretamente no arquivo texto como se fosse uma tabela)<br />
Agora a partir do oracle 10g é possível também criar um arquivo texto baseado numa tabela do banco usando o novo driver de Data Pump existente.<span id="more-37"></span> </p>
<p>A possibilidade de gravar um arquivo texto se limita ao CREATE TABLE AS SELECT apenas. Não é permitido fazer UPDATE, DELETE ou INSERT numa external table.</p>
<p>Vamos a um exemplo:</p>
<pre class="brush: sql;">SQL> CREATE DIRECTORY external_directory AS
'c:\oracle\admin\betatwo\directory';

SQL> GRANT READ, WRITE ON DIRECTORY external_directory
TO scott;
SQL> CREATE TABLE emp_history_ext
(ename, retire_date,
last_retirement_pay_date, pay_amount)
ORGANIZATION EXTERNAL
( TYPE oracle_datapump
  DEFAULT DIRECTORY external_directory
LOCATION ('emp_history_01.exp', 'emp_history_02.exp') )
parallel
AS
SELECT a.ename, b.retire_date,
b.last_retirement_pay_date, b.pay_amount
FROM emp a, retire_pay b
WHERE a.empno=b.empno;</pre>
<p>Primeiramente, criamos um DIRECTORY e damos permissão de leitura e escrita. Isso apenas é requerido caso o usuário que criou o diretório não é o usuário que vai criar a external table. Após isso, criamos uma external table que será populada com o SELECT informado!</p>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//--></script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>Após a criação, basta fazer a consulta diretamente no arquivo texto:</p>
<pre class="brush: sql;">SQL> SELECT * FROM emp_history_ext;

ENAME      RETIRE_DA LAST_RETI PAY_AMOUNT
---------- --------- --------- ----------
SMITH      25-NOV-03 15-DEC-03       1000</pre>
<p>A criação dessa external table resulta na criação de um arquivo texto no sistema operacional com os dados informados no SELECT. Também é gerado um arquivo de LOG no mesmo diretório:</p>
<pre class="brush: plain;">C:\> dir c:\oracle\admin\betatwo\directory
 Volume in drive C has no label.
 Volume Serial Number is 3CE9-7321
 Directory of c:\oracle\admin\betatwo\directory
12/15/2003 07:52  PM      90    EMP_HISTORY_EXT_2528_1760.log
12/15/2003 07:52  PM   1,808    emp_history.exp</pre>
<p>Outras informações:<br />
Quando você dropa uma external table os arquivos textos continuam no sistema operacional! Isso pode ser um problema pois caso você execute novamente o comando pra recriar a external table, os arquivos já existirão e ocasionará um ERRO. Você deve excluir esses arquivos manualmente.</p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2009/01/13/melhorias-nos-external-tables-do-10g/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Novas funcionalidades com CONNECT BY</title>
		<link>http://glufke.net/2009/01/12/novas-funcionalidades-com-connect-by/</link>
		<comments>http://glufke.net/2009/01/12/novas-funcionalidades-com-connect-by/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 11:23:42 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Connect By]]></category>
		<category><![CDATA[Oracle 10g]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=38</guid>
		<description><![CDATA[A partir do Oracle 10g temos mais algumas funcionalidades no uso da cláusula CONNECT BY dentro dos comandos SELECT. Essas mudanças se aplicam a queries hiearquicas permitindo o retorno de não apenas PAIS, FILHOS mas também &#8220;ancestrais&#8221;. São 3 as novas cláusulas disponíveis com CONNECT BY. 



connect_by_iscycle
Determina se a linha corrente tem uma linha filha [...]]]></description>
			<content:encoded><![CDATA[<p>A partir do Oracle 10g temos mais algumas funcionalidades no uso da cláusula CONNECT BY dentro dos comandos SELECT. Essas mudanças se aplicam a queries hiearquicas permitindo o retorno de não apenas PAIS, FILHOS mas também &#8220;ancestrais&#8221;. São 3 as novas cláusulas disponíveis com CONNECT BY.<span id="more-38"></span> </p>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p><strong>connect_by_iscycle</strong><br />
Determina se a linha corrente tem uma linha filha que também é seu ancestral.</p>
<pre class="brush: sql;">SQL>  SELECT ename Emp, CONNECT_BY_ISCYCLE leaf, mgr "Manager",
  2     LEVEL-1 "Pathlen", SYS_CONNECT_BY_PATH(empno, '/') "Path"
  3     FROM emp
  4     Where level-1 < 3
  5     CONNECT BY NOCYCLE PRIOR empno = mgr;

EMP              LEAF Manager    Pathlen Path
---------- ---------- ------- ---------- ------------------------------
SCOTT               0    7566          0 /7788
ADAMS               0    7788          1 /7788/7876
FORD                0    7566          0 /7902
SMITH               0    7902          1 /7902/7369
ALLEN               0    7698          0 /7499
WARD                0    7698          0 /7521
MARTIN              0    7698          0 /7654
TURNER              0    7698          0 /7844
JAMES               0    7698          0 /7900
MILLER              0    7782          0 /7934
ADAMS               0    7788          0 /7876
JONES               0    7839          0 /7566
SCOTT               0    7566          1 /7566/7788
ADAMS               0    7788          2 /7566/7788/7876
FORD                0    7566          1 /7566/7902
SMITH               0    7902          2 /7566/7902/7369
BLAKE               0    7839          0 /7698
ALLEN               0    7698          1 /7698/7499
WARD                0    7698          1 /7698/7521
MARTIN              0    7698          1 /7698/7654
TURNER              0    7698          1 /7698/7844
JAMES               0    7698          1 /7698/7900
CLARK               0    7839          0 /7782
MILLER              0    7782          1 /7782/7934
SMITH               0    7902          0 /7369
KING                0                  0 /7839
JONES               0    7839          1 /7839/7566
SCOTT               0    7566          2 /7839/7566/7788
FORD                0    7566          2 /7839/7566/7902
BLAKE               0    7839          1 /7839/7698
ALLEN               0    7698          2 /7839/7698/7499
WARD                0    7698          2 /7839/7698/7521
MARTIN              0    7698          2 /7839/7698/7654
TURNER              0    7698          2 /7839/7698/7844
JAMES               0    7698          2 /7839/7698/7900
CLARK               0    7839          1 /7839/7782
MILLER              0    7782          2 /7839/7782/7934

37 rows selected

SQL> </pre>
<p><strong>connect_by_isleaf</strong><br />
Determina se a linha corrente é uma FOLHA na árvore definida pela operação connect by.</p>
<pre class="brush: sql;">SQL> SELECT ename "Emp", CONNECT_BY_ISLEAF leaf, mgr "Manager",
  2     LEVEL-1 "Pathlen", SYS_CONNECT_BY_PATH(empno, '/') "Path"
  3     FROM emp
  4     Where level-1 < 3
  5     CONNECT BY NOCYCLE PRIOR empno = mgr;

Emp              LEAF Manager    Pathlen Path
---------- ---------- ------- ---------- ------------------------------
SCOTT               0    7566          0 /7788
ADAMS               1    7788          1 /7788/7876
FORD                0    7566          0 /7902
SMITH               1    7902          1 /7902/7369
ALLEN               1    7698          0 /7499
WARD                1    7698          0 /7521
MARTIN              1    7698          0 /7654
TURNER              1    7698          0 /7844
JAMES               1    7698          0 /7900
MILLER              1    7782          0 /7934
ADAMS               1    7788          0 /7876
JONES               0    7839          0 /7566
SCOTT               0    7566          1 /7566/7788
ADAMS               1    7788          2 /7566/7788/7876
FORD                0    7566          1 /7566/7902
SMITH               1    7902          2 /7566/7902/7369
BLAKE               0    7839          0 /7698
ALLEN               1    7698          1 /7698/7499
WARD                1    7698          1 /7698/7521
MARTIN              1    7698          1 /7698/7654
TURNER              1    7698          1 /7698/7844
JAMES               1    7698          1 /7698/7900
CLARK               0    7839          0 /7782
MILLER              1    7782          1 /7782/7934
SMITH               1    7902          0 /7369
KING                0                  0 /7839
JONES               0    7839          1 /7839/7566
SCOTT               0    7566          2 /7839/7566/7788
FORD                0    7566          2 /7839/7566/7902
BLAKE               0    7839          1 /7839/7698
ALLEN               1    7698          2 /7839/7698/7499
WARD                1    7698          2 /7839/7698/7521
MARTIN              1    7698          2 /7839/7698/7654
TURNER              1    7698          2 /7839/7698/7844
JAMES               1    7698          2 /7839/7698/7900
CLARK               0    7839          1 /7839/7782
MILLER              1    7782          2 /7839/7782/7934

37 rows selected

SQL> </pre>
<p><strong>connect_by_root</strong><br />
Retorna o valor da coluna da linha Raíz.</p>
<pre class="brush: sql;">SQL> SELECT ename "Emp", CONNECT_BY_ROOT mgr "Manager",
  2     LEVEL-1 "Pathlen", SYS_CONNECT_BY_PATH(empno, '/') "Path"
  3     FROM emp
  4     Where level-1 < 3
  5     CONNECT BY NOCYCLE PRIOR empno = mgr;

Emp           Manager    Pathlen Path
---------- ---------- ---------- ------------------------------
SCOTT            7566          0 /7788
ADAMS            7566          1 /7788/7876
FORD             7566          0 /7902
SMITH            7566          1 /7902/7369
ALLEN            7698          0 /7499
WARD             7698          0 /7521
MARTIN           7698          0 /7654
TURNER           7698          0 /7844
JAMES            7698          0 /7900
MILLER           7782          0 /7934
ADAMS            7788          0 /7876
JONES            7839          0 /7566
SCOTT            7839          1 /7566/7788
ADAMS            7839          2 /7566/7788/7876
FORD             7839          1 /7566/7902
SMITH            7839          2 /7566/7902/7369
BLAKE            7839          0 /7698
ALLEN            7839          1 /7698/7499
WARD             7839          1 /7698/7521
MARTIN           7839          1 /7698/7654
TURNER           7839          1 /7698/7844
JAMES            7839          1 /7698/7900
CLARK            7839          0 /7782
MILLER           7839          1 /7782/7934
SMITH            7902          0 /7369
KING                           0 /7839
JONES                          1 /7839/7566
SCOTT                          2 /7839/7566/7788
FORD                           2 /7839/7566/7902
BLAKE                          1 /7839/7698
ALLEN                          2 /7839/7698/7499
WARD                           2 /7839/7698/7521
MARTIN                         2 /7839/7698/7654
TURNER                         2 /7839/7698/7844
JAMES                          2 /7839/7698/7900
CLARK                          1 /7839/7782
MILLER                         2 /7839/7782/7934

37 rows selected

SQL> </pre>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2009/01/12/novas-funcionalidades-com-connect-by/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cláusula RETURNING com funções somatórias</title>
		<link>http://glufke.net/2009/01/09/clausula-returning-com-funcoes-somatorias/</link>
		<comments>http://glufke.net/2009/01/09/clausula-returning-com-funcoes-somatorias/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 12:57:54 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Oracle 10g]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=39</guid>
		<description><![CDATA[Oracle 10g agora permite o uso de funções somatórias na cláusula RETURNING. O seguinte exemplo faz um UPDATE no salário de todos empregados e retorna a média salarial resultante para as linhas afetadas. 
SQL> VARIABLE a NUMBER
SQL> UPDATE employee
  2  SET sal=sal*1.10 RETURNING AVG(sal) INTO :a;
SQL> PRINT a
      [...]]]></description>
			<content:encoded><![CDATA[<p>Oracle 10g agora permite o uso de funções somatórias na cláusula RETURNING. O seguinte exemplo faz um UPDATE no salário de todos empregados e retorna a média salarial resultante para as linhas afetadas.<span id="more-39"></span> </p>
<pre class="brush: sql;">SQL> VARIABLE a NUMBER
SQL> UPDATE employee
  2  SET sal=sal*1.10 RETURNING AVG(sal) INTO :a;
SQL> PRINT a
           a
    --------
      655.22</pre>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>O mesmo exemplo acima mostrado dentro de um bloco PL/SQL:</p>
<pre class="brush: sql;">Declare
     a   number;
begin
     update employee set sal=sal*1.10 returning avg(sal) into a;
     dbms_output.put_line(a);
end;</pre>
<p>Lembre-se que essa média é apenas das linhas afetadas pelo UPDATE!</p>
<p>Também é possível utilizar em comandos DELETE:</p>
<pre class="brush: sql;">Declare
     a   number;
begin
     delete from employee where sal > 1000 returning avg(sal) into a;
     dbms_output.put_line(a);
end;</pre>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2009/01/09/clausula-returning-com-funcoes-somatorias/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ignorando Acentos e Maiúsculas/Minúsculas no 10g</title>
		<link>http://glufke.net/2009/01/08/ignorando-acentos-e-maiusculasminusculas-no-10g/</link>
		<comments>http://glufke.net/2009/01/08/ignorando-acentos-e-maiusculasminusculas-no-10g/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 12:19:12 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Acentuação]]></category>
		<category><![CDATA[Oracle 10g]]></category>

		<guid isPermaLink="false">http://glufke.net/?p=36</guid>
		<description><![CDATA[O Oracle 10g agora permite fazer consultas considerando ou não acentos e maiúsculas/minúsculas. Isso é feito pelo uso do parâmetro NLS_SORT. Vamos aos exemplos.
Temos que adicionar o prefixo _ai para &#8220;accent insensitive&#8221; (ignora os acentos). Ou _ci para &#8220;case insensitive&#8221; (ignora se é maiúsculo ou minúsculo).
O nls_sort afeta uma série de funções SQL e operações, [...]]]></description>
			<content:encoded><![CDATA[<p>O Oracle 10g agora permite fazer consultas considerando ou não acentos e maiúsculas/minúsculas. Isso é feito pelo uso do parâmetro <strong>NLS_SORT</strong>. Vamos aos exemplos.<span id="more-36"></span></p>
<p>Temos que adicionar o prefixo <strong>_ai</strong> para &#8220;accent insensitive&#8221; (ignora os acentos). Ou <strong>_ci</strong> para &#8220;case insensitive&#8221; (ignora se é maiúsculo ou minúsculo).</p>
<p>O nls_sort afeta uma série de funções SQL e operações, incluindo essas:<br />
* WHERE<br />
* ORDER BY<br />
* START WITH<br />
* HAVING<br />
* IN / NOT IN<br />
* BETWEEN<br />
* CASE-WHEN</p>
<p>Algumas funções entretanto, não são afetadas pelo nls_sort. (Como LIKE, TRIM, INSTR).</p>
<div id="ads_336x280"><script type="text/javascript">// <![CDATA[
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
// ]]&gt;</script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></div>
<p>Observe o comportamento normal do ORDER BY:</p>
<pre class="brush: sql;">SQL&gt; select * from thomas_teste order by 1;

NOME
-------------------------------------------
THOMAS 2
Thomas 3
thomas 1

SQL&gt; </pre>
<p>Agora, a mesma consulta, mas antes mudamos o NLS_SORT para ignorar os maiúsculos e minúsculos:</p>
<pre class="brush: sql;">SQL&gt; ALTER SESSION SET NLS_SORT=generic_m_ci;

Session altered.

SQL&gt; select * from thomas_teste order by 1;

NOME
-----------------------------------------------
thomas 1
THOMAS 2
Thomas 3

SQL&gt; </pre>
<p>Agora, o mesmo resultado acima SEM mudar a sessão:</p>
<pre class="brush: sql;">SQL&gt; select * from thomas_teste
2  order by nlssort( nome, 'NLS_SORT=generic_m_ci');

NOME
-------------------------------------------------------
thomas 1
THOMAS 2
Thomas 3

SQL&gt; </pre>
<p>E é claro, também pode usar o <strong>_ai</strong> para ignorar os acentos.<br />
NOTA: o <strong>_ai</strong> inclui a funcionalidade do CASE INSENSITIVE também!</p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2009/01/08/ignorando-acentos-e-maiusculasminusculas-no-10g/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Select que retorna os Números Primos</title>
		<link>http://glufke.net/2007/10/11/select-que-retorna-os-numeros-primos/</link>
		<comments>http://glufke.net/2007/10/11/select-que-retorna-os-numeros-primos/#comments</comments>
		<pubDate>Thu, 11 Oct 2007 22:40:31 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Curiosidade]]></category>
		<category><![CDATA[Matemática]]></category>

		<guid isPermaLink="false">http://glufke.net/2007/10/11/select-que-retorna-os-numeros-primos/</guid>
		<description><![CDATA[Esse post vai mais a título de curiosidade. Sabemos que os números primos são números naturais que podem ser divididos apenas por dois números naturais, o 1 (um) e ele mesmo. Pois a tempos que eu queria um SQL que retornasse esses números! 
Após um pouco de tentativas, saiu o SQL abaixo:
select z.zz PRIMOS
from
 (select [...]]]></description>
			<content:encoded><![CDATA[<p>Esse post vai mais a título de curiosidade. Sabemos que os <a href="http://pt.wikipedia.org/wiki/N%C3%BAmero_primo">números primos</a> são números naturais que podem ser divididos apenas por dois números naturais, o 1 (um) e ele mesmo. Pois a tempos que eu queria um SQL que retornasse esses números! <span id="more-20"></span></p>
<p>Após um pouco de tentativas, saiu o SQL abaixo:</p>
<pre class="brush: sql;">select z.zz PRIMOS
from
 (select rownum+1 zz
  from user_tables
  where rownum < 100
 ) z
where zz not in (
                select y.bb
                from (select rownum+1 aa from user_tables a where rownum < 100) x
                ,    (select rownum+1 bb from user_tables b where rownum < 100) y
                where bb<>aa
                  and mod(bb, aa)=0
                  and aa<=bb
                )
/</pre>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>Abaixo, colocaremos uma amostra dos resultados:</p>
<pre class="brush: sql;">SQL> select z.zz PRIMOS
  2  from
  3   (select rownum+1 zz
  4    from user_tables
  5    where rownum < 100
  6   ) z
  7  where zz not in (
  8                  select y.bb
  9                  from (select rownum+1 aa from user_tables a where rownum < 100) x
 10                  ,    (select rownum+1 bb from user_tables b where rownum < 100) y
 11                  where bb<>aa
 12                    and mod(bb, aa)=0
 13                    and aa<=bb
 14                  )
 15  /

   PRIMOS
---------
        2
        3
        5
        7
       11
       13
       17
       19
       23
       29
       31
       37
       41
       43
       47
       53
       59
       61
       67
       71
       73
       79
       83
       89
       97

25 rows selected.
SQL></pre>
<p>Talvez essa não seja a melhor forma de fazer isso (obviamente, que usar SQL pra calcular isso não é a melhor saída). Mesmo assim, fica como um "desafio vencido". </p>
<p>Comentários <a href="http://glufke.net/oracle/viewtopic.php?t=637">aqui</a></p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2007/10/11/select-que-retorna-os-numeros-primos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como usar Índices Virtuais &#8211; NOSEGMENT INDEXES</title>
		<link>http://glufke.net/2007/09/25/como-usar-indices-virtuais-nosegment-indexes/</link>
		<comments>http://glufke.net/2007/09/25/como-usar-indices-virtuais-nosegment-indexes/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 22:49:51 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[DBA]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">http://glufke.net/2007/09/25/como-usar-indices-virtuais-nosegment-indexes/</guid>
		<description><![CDATA[Essa é para quem faz tunning de SQL. Digamos que você quer verificar se a criação de um novo í­ndice vai ser realmente usada pelo otimizador. Antes de criá-lo, você pode testar se ele resolverá seu problema atraves de INDICE VIRTUAL.
O Oracle vai criar o í­ndice no dicionário de dados mas não vai criar o [...]]]></description>
			<content:encoded><![CDATA[<p>Essa é para quem faz tunning de SQL. Digamos que você quer verificar se a criação de um novo í­ndice vai ser realmente usada pelo otimizador. Antes de criá-lo, você pode testar se ele resolverá seu problema atraves de INDICE VIRTUAL.<span id="more-17"></span></p>
<p>O Oracle vai criar o í­ndice no dicionário de dados mas não vai criar o í­ndice fisicamente. Nada será armazenado nem acessado!</p>
<pre class="brush: sql;">SQL> set autotrace traceonly explain

SQL> select name from emp where name = 'Alex';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=164 Card=1 Bytes=500)
   1    0   TABLE ACCESS (FULL) OF 'EMP' (Cost=164 Card=1 Bytes=500)</pre>
<p><strong>Criando o Í­ndice</strong></p>
<pre class="brush: sql;">
SQL> create index emp_vir_idx1 on emp(name) nosegment;

Index created.</pre>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>Agora, vamos ver se ele vai usar:</p>
<pre class="brush: sql;">
SQL> set autotrace traceonly explain

SQL> select name from emp where name = 'Alex';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=164 Card=1 Bytes=500)
   1    0   TABLE ACCESS (FULL) OF 'EMP' (Cost=164 Card=1 Bytes=500)</pre>
<p>Hei! Acesso FULL? Porque o oracle não está usando meu novo í­ndice?<br />
Você deve primeiro alterar sua sessão com o parâmetro oculto &#8220;_use_nosegment_indexes&#8221;.</p>
<pre class="brush: sql;">
SQL> alter session set "_use_nosegment_indexes" = true;

Session altered.

SQL> select name from emp where name = 'Alex';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=500)
   1    0   INDEX (RANGE SCAN) OF 'EMP_VIR_IDX1' (NON-UNIQUE) (Cost=1 Card=1 Bytes=500) </pre>
<p>Comente <a href="http://glufke.net/oracle/viewtopic.php?t=417">aqui</a></p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2007/09/25/como-usar-indices-virtuais-nosegment-indexes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ver Plano de execução de um SQL rodando</title>
		<link>http://glufke.net/2007/09/25/ver-plano-de-execucao-de-um-sql-rodando/</link>
		<comments>http://glufke.net/2007/09/25/ver-plano-de-execucao-de-um-sql-rodando/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 14:36:31 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Trace]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">http://glufke.net/2007/09/25/ver-plano-de-execucao-de-um-sql-rodando/</guid>
		<description><![CDATA[Imagine que você rodou um SQL que está demorando muito. O Trace está desligado e você quer saber o que pode estar errado com o SQL. Com essa dica, você enxerga o plano de execução deste SQL.
1. Escolha o SQL que está rodando
select address, hash_value, child_number, sql_text
from v$sql
where users_executing  0
/



2. Rode o sql abaixo, [...]]]></description>
			<content:encoded><![CDATA[<p>Imagine que você rodou um SQL que está demorando muito. O Trace está desligado e você quer saber o que pode estar errado com o SQL. Com essa dica, você enxerga o plano de execução deste SQL.<span id="more-18"></span></p>
<p><strong>1. Escolha o SQL que está rodando</strong></p>
<pre class="brush: sql;">select address, hash_value, child_number, sql_text
from v$sql
where users_executing <> 0
/</pre>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p><strong>2. Rode o sql abaixo, informando o address, hash_value, child_number retornado do Primeiro SQL.</strong></p>
<pre class="brush: sql;">SET VERIFY OFF
COL id          FORMAT 999
COL parent_id   FORMAT 999 HEADING "PARENT"
COL operation   FORMAT a35 TRUNCATE
COL object_name FORMAT a30
SELECT  id, parent_id, LPAD (' ', LEVEL - 1) ||
        operation || ' ' || options operation, object_name
FROM    (
        SELECT id, parent_id, operation, options, object_name
        FROM   v$sql_plan
        WHERE  address = '&#038;address'
        AND    hash_value = &#038;hash_value
        AND    child_number = &#038;child_number
        )
START WITH id = 0
CONNECT BY PRIOR id = parent_id; </pre>
<p>Obrigado a Roger Schrag que é o autor dessa dica!<br />
Comente <a href="http://glufke.net/oracle/viewtopic.php?t=538">aqui</a></p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2007/09/25/ver-plano-de-execucao-de-um-sql-rodando/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CASE WHEN versus DECODE</title>
		<link>http://glufke.net/2007/09/07/12/</link>
		<comments>http://glufke.net/2007/09/07/12/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 10:14:20 +0000</pubDate>
		<dc:creator>glufke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Funções]]></category>

		<guid isPermaLink="false">http://glufke.net/2007/09/07/12/</guid>
		<description><![CDATA[As vezes o CASE WHEN quebra o galho quando temos que usar condições mais complexas&#8230; Mas o que fazer quando não é possí­vel usá-lo? (como nas versões anteriores ao 8i, e no PL*SQL anterior ao 9i). É muito simples! 
Eis o nosso query:
SQL> select
  2    empno
  3  , sal
 [...]]]></description>
			<content:encoded><![CDATA[<p>As vezes o CASE WHEN quebra o galho quando temos que usar condições mais complexas&#8230; Mas o que fazer quando não é possí­vel usá-lo? (como nas versões anteriores ao 8i, e no PL*SQL anterior ao 9i). É muito simples! <span id="more-12"></span></p>
<p>Eis o nosso query:</p>
<pre class="brush: sql;">SQL> select
  2    empno
  3  , sal
  4  , case
  5      when sal<1000  then 'SALARIO BAIXO'
  6      when sal>=1000 then 'SALARIO ALTO'
  7    end comentario
  8  from emp
  9  /

     EMPNO        SAL COMENTARIO
---------- ---------- -------------
      7369        800 SALARIO BAIXO
      7499       1600 SALARIO ALTO
      7521       1250 SALARIO ALTO
      7566       2975 SALARIO ALTO
      7654       1250 SALARIO ALTO
      7698       2850 SALARIO ALTO
      7782       2450 SALARIO ALTO
      7788       3000 SALARIO ALTO
      7839       5000 SALARIO ALTO
      7844       1500 SALARIO ALTO
      7876       1100 SALARIO ALTO
      7900        999 SALARIO BAIXO
      7902       3000 SALARIO ALTO
      7934       1000 SALARIO ALTO
</pre>
<div id="ads_336x280"><script type="text/javascript"><!--
google_ad_client = "pub-8964513116661040";
google_alternate_color = "ffffFF";
google_ad_width = 336;
google_ad_height = 280;
google_ad_format = "336x280_as";
google_ad_type = "text_image";
//2007-09-07: wp_quadrado_gra
google_ad_channel = "0247072216";
google_color_border = "FFFFFF";
google_color_bg = "FFFFff";
google_color_link = "4F82CB";
google_color_text = "000000";
google_color_url = "4F82CB";
//-->
</script><script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>
<p>E agora um query exatamente IGUAL sem o tal case-when&#8230; </p>
<pre class="brush: sql;">SQL> select
  2    empno
  3  , sal
  4  , decode(sign(sal-1000), -1, 'SALARIO BAIXO', 'SALARIO ALTO')
  5  from emp
  6  /

     EMPNO        SAL DECODE(SIGN(S
---------- ---------- -------------
      7369        800 SALARIO BAIXO
      7499       1600 SALARIO ALTO
      7521       1250 SALARIO ALTO
      7566       2975 SALARIO ALTO
      7654       1250 SALARIO ALTO
      7698       2850 SALARIO ALTO
      7782       2450 SALARIO ALTO
      7788       3000 SALARIO ALTO
      7839       5000 SALARIO ALTO
      7844       1500 SALARIO ALTO
      7876       1100 SALARIO ALTO
      7900        999 SALARIO BAIXO
      7902       3000 SALARIO ALTO
      7934       1000 SALARIO ALTO
SQL> </pre>
<p>Mais uma forma de se fazer isso SEM case-when:</p>
<pre class="brush: sql;">select
  empno
, sal
, decode(greatest(sal,1000), 1000, 'SALARIO BAIXO', 'SALARIO ALTO')
from emp
/
</pre>
<p>Comente <a href="http://glufke.net/oracle/viewtopic.php?t=12">aqui</a></p>
]]></content:encoded>
			<wfw:commentRss>http://glufke.net/2007/09/07/12/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
