tag:blogger.com,1999:blog-268011812024-03-05T23:00:50.266+01:00Programación PL/SQLEl lenguaje de programación de bases de datos Oracle PL/SQL. Librerías y funciones estándar SQL y PLSQL.JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.comBlogger106125tag:blogger.com,1999:blog-26801181.post-32072628701846195562024-02-28T06:30:00.000+01:002024-02-28T08:27:42.551+01:00La funcionalidad de muestreo dinámico o Dynamic Sampling<p>La <b>funcionalidad de muestreo dinámico</b> (<i>Dynamic Sampling</i>) estuvo por primera vez disponible para la <b>release 2 de la bases de datos Oracle 9i</b>. Esta funcionalidad posibilita que el <b>optimizador SQL y PL/SQL basado en costes</b> (CBO) muestree las tablas que utiliza una consulta (<i>query</i>) durante la fase de <a href="/2007/04/fases-durante-el-procesamiento-de-una.html"><i>parsing duro</i></a>, para mejorar los valores estadísticos que utiliza el optimizador al incluir en dichas estadísticas los segmentos no analizados con anterioridad. Como ya he indicado, este muestro sólo ocurre durante la fase de <i>parsing duro</i> y se utiliza para mejorar las estadísticas utilizadas por el optimizador PLSQL, de ahí el nombre de muestro dinámico.</p>
<div class="separator" style="clear: both;"><p><a href="/2009/03/la-funcionalidad-de-muestreo-dinamico-o.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Muestreo dinámico en las bases de dato Oracle para SQL y PL/SQL" title="La funcionalidad de muestreo dinámico o Dynamic Sampling" border="0" width="400" data-original-height="350" data-original-width="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmbmrezUzHUPOayA9uI81cb5ybkskSqYNc5b1TTg3W3NJiRRzze6yc7ZFy3oWdKy7K0vptClj-f0ruMGLTTr2kw_e6VPC2uNB1bioJNDrqql3665XABUGZYL_hQ65tdKfPIEc1GrQmAHbL6mw_HRVpodMZNq8cMlPJbyBdp2TCh7Jr0xIG-43-/s400/Dynamic-Sampling-Oracle.jpg"></a></p></div>
<p>El optimizador de las bases de datos Oracle usa una gran variedad de datos de entradas para generar los planes de ejecución. Utiliza todos los índices y restricciones (<i>constraints</i>) definidos en las tablas, las estadísticas del sistema (velocidad de entrada/salida de los servidores, velocidad de CPU), y las estadísticas recogidas de los segmentos involucrados en la ejecución de la consulta. El optimizador utiliza estas estadísticas para <b>estimar el número de registros</b> involucrados en cada uno de los pasos de los que consta un <b>plan de ejecución</b> específico, siendo este volumen de registros la variable principal a la hora de calcular el coste de ejecución de una consulta. Cuando el optimizador calcula incorrectamente el volumen de registros, probablemente escogerá un plan de ejecución ineficiente causando problemas de rendimiento en la base de datos. De hecho, la principal razón por la que el optimizador Oracle puede decidirse por un plan de ejecución incorrecto, es precisamente por esta causa, es decir, una estimación incorrecta del volumen de registros a procesar en cada paso del plan de ejecución.</p>
<a href="http://www.plsql.biz/2009/03/la-funcionalidad-de-muestreo-dinamico-o.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-31229762106277142992024-02-08T06:30:00.000+01:002024-02-08T11:47:10.437+01:00PLSQL dinámico con las funciones DBM_SESSION.SET_CONTEXT y SYS_CONTEXT (¿Por qué?)<p>En programación PL/SQL siempre tenemos lectores que nos hacen preguntas interesantes, en esta ocasión se nos ha preguntado acerca del motivo por el cual al utilizar <b>PLSQL dinámico</b> hay mucha gente que utiliza las funciones estándar de Oracle <b>SYS_CONTEXT y DBM_SESSION.SET_CONTEXT</b>, de manera que en la cláusula WHERE de cualquier consulta SQL, en lugar de utilizar simplemente literales se utiliza la función SYS_CONTEXT.</p>
<div class="separator" style="clear: both;"><p><a href="/2011/08/dbmssession-setcontext-syscontext.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="505" data-original-width="741" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtjsTYguU8mSOstgQm-KV-RT-ASgBTslyKcPdq_UDZen3DjzSN1tVpWrqSN_wsBHOmF3I4dLIKggxFSaSLiUMhFcJS0FEaWftF3ytUnDG097OCbEEJ0KQwPXmQhu6mc2Y3O0nu2rCSkPjiRbqzXUuogS2izZZHAl56g6oRdCLZG7UpKynVTcPZ/s400/procesamiento-sentencias-SQL-Oracle.JPG"></a></p></div>
<p>Es decir, por qué utilizar <i>"WHERE valor = SYS_CONTEXT('mi_contexto','valor')"</i>, en vez de, por ejemplo, la simple y más corta sentencia <i>"WHERE valor = 15"</i>.</p>
<a href="http://www.plsql.biz/2011/08/dbmssession-setcontext-syscontext.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com2tag:blogger.com,1999:blog-26801181.post-27178454210880776382024-01-23T06:30:00.000+01:002024-01-23T11:15:31.815+01:00El paquete PL/SQL DBMS_SCHEDULER para programación de trabajos<p><b>DBMS_SCHEDULER</b> es el paquete PLSQL que reemplazó en la versión de la base de datos Oracle 10g al paquete <b>DBMS_JOB</b>. Aunque el paquete DBMS_JOB sigue existiendo por razones de compatibilidad, no debe utilizarse ya que es muy probable que deje de existir en futuras versiones de la base de datos Oracle. El paquete <b>DBMS_SCHEDULER</b> permite programar la ejecución, en los instantes que deseemos, de <a href="/2006/10/los-bloques-de-cdigo-plsql.html">bloques PLSQL</a>, así como de <a href="/2007/03/procedimientos-y-funciones-en-plsql.html">procedimientos y funciones PL/SQL</a>. Por otro lado, también permite programar la ejecución de binarios y <i>shell-scripts</i>.</p>
<div class="separator" style="clear: both;"><p><a href="/2009/06/el-paquete-plsql-dbmsscheduler-para.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="DBMS_SCHEDULER programación de trabajos y procesos en PLSQL" title="El paquete PL/SQL DBMS_SCHEDULER para programación de trabajos" border="0" width="400" data-original-height="450" data-original-width="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk67MUjyViLk-S-ad6lZ65Zc8lomO4g1S4P4IoxjR5iLWD41kA_Fy0FGzu3WdFwqYkXcLMN2xCncegDL7ZIwzvMqFI7I1bn27ngZMzbsfrAA1GpDi3oh_g25MoP6kbXAU11-4Gm9IZIGITz9eipDb2Q3jLlNF9nfq41b_SiZg-P7c0j7ggj-na/s400/DBMS_SCHEDULER.jpg"></a></p></div>
<h2 style="font-size:130%">Permisos necesarios</h2>
<p>Con permisos de DBA se tiene acceso a todas las funciones del paquete DBMS_SCHEDULER. Para administrar la programación de procesos se necesita tener la rol (<i>role</i>) de SCHEDULER_ADMIN. Y finalmente, para crear y ejecutar procesos bajo tu propia identidad, se necesita tener el privilegio CREATE JOB. Por otro lado, aprovecho para mencionar que el paquete DBMS_JOB requería la inicialización de un parámetro del sistema, tras lo cual se lanzaba un proceso en <i>background</i> encargado de coordinar la ejecución de los distintos procesos programados, pero esto ya no es necesario si utilizamos Oracle 10g y el paquete DBMS_SCHEDULER.</p>
<a href="http://www.plsql.biz/2009/06/el-paquete-plsql-dbmsscheduler-para.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com2tag:blogger.com,1999:blog-26801181.post-31995466740151030712023-12-21T06:30:00.000+01:002023-12-21T10:51:47.691+01:00Problemas con los triggers SQL<p>Mucha gente piensa que los <a href="/2007/02/triggers-en-plsql.html"><span style="font-weight:bold;">triggers PL/SQL</span></a> son una de las más potentes herramientas de las bases de datos Oracle. De hecho lo son, pero existen dos razones fundamentales por las que, personalmente, trato de evitar la utilización de triggers a la hora de implementar mis proyectos en PL/SQL.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLHMpb48TRXiTEs_bSYLNJHSVvtuCNBpWMp_LK51nqAu_TDe-D6sOoECOzRTdSEKxVkujigR5QbtTI6ENiUiLrBn6FPSNWCynT4QPR998Ep89_ky8uDL3MczRM9slEYP-Vy9_oyxVQ4mp7lWUzGqqTo9_ipMUa0snjSl7JKqCvpy4fKQ617Xu/s777/triggers-plsql-problemas.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="Problemas con los triggers SQL" title="Problemas con los triggers SQL" border="0" width="400" data-original-height="459" data-original-width="777" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLHMpb48TRXiTEs_bSYLNJHSVvtuCNBpWMp_LK51nqAu_TDe-D6sOoECOzRTdSEKxVkujigR5QbtTI6ENiUiLrBn6FPSNWCynT4QPR998Ep89_ky8uDL3MczRM9slEYP-Vy9_oyxVQ4mp7lWUzGqqTo9_ipMUa0snjSl7JKqCvpy4fKQ617Xu/s400/triggers-plsql-problemas.jpg"></a></div>
<h2 style="font-size:130%">Problemas de mantenimiento</h2>
<p>A largo plazo, la utilización de triggers suele causar grandes <a href="https://dolorcabeza.blogspot.com" rel="nofollow">dolores de cabeza</a> a la hora de pensar en el mantenimiento. Al ser piezas del código que sólo ocurren como consecuencia de que se ha realizado otra operación, es muy frecuente que la gente se olvide de que los triggers están allí, y revisar el código pensando en todas las piezas de la base de datos que pueden afectarle, se hace poco menos que imposible.</p>
<a href="http://www.plsql.biz/2008/12/problemas-con-los-triggers-sql.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com4tag:blogger.com,1999:blog-26801181.post-76132087217895578092023-11-28T06:30:00.000+01:002023-11-28T12:29:13.508+01:00Tablas Oracle: Claves naturales o claves sustitutivas<p>En algunas ocasiones me he encontrado con bases de datos en las que se aplica la norma de, a la hora de diseñar una tabla nueva, utilizar siempre una <span style="font-weight: bold;">clave sustitutiva</span> (<i>surrogate key</i>) , incluso existiendo una <span style="font-weight: bold;">clave natural</span> perfectamente aplicable. Cuando he preguntado por el motivo de crear tales claves sustitutivas, la razón ha sido casi siempre la de aumentar la eficiencia de la base de datos eliminando la posibilidad de tener que enlazar dos tablas utilizando más de una columna.</p>
<div class="separator" style="clear: both;"><a href="/2009/01/tablas-oracle-claves-naturales-o-claves.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Claves alternativas y naturales" title="Tablas Oracle: Claves naturales o claves sustitutivas" border="0" width="400" data-original-height="416" data-original-width="681" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwAw3VC2j08pPyW-RxUa7qaXSn44ZnGjsCYrKVIonReZmPpL8iEZnZWwGkGuet5XEoYrq9qNCVbruyw3R_oA2ti_Hmzo_8ARkWSokYGEdH_nyILk4yczOnutK6AJNVcRUNdLAUmOAyzyUCeM6RGiFxGjqpGURfOUDpBQ7zFG2bFt3q5Gh8bh6c/s400/claves-naturales-y-sustitutivas.jpg"></a></div>
<p>Primero aclararé, para aquellos que no lo tengan claro, el <span style="font-weight: bold;">concepto de clave sustitutiva o surrogate key</span>. Una clave sustitutiva no es más que una clave interna, un identificador único, que no tiene significado para el negocio, y que identifica de forma única un registro de una tabla de la base de datos.</p>
<a href="http://www.plsql.biz/2009/01/tablas-oracle-claves-naturales-o-claves.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com2tag:blogger.com,1999:blog-26801181.post-68269244151309405142023-11-09T06:30:00.000+01:002023-11-09T10:37:24.757+01:00Vistas materializadas y la funcionalidad "Query Rewrite"<p>Ya he escrito anteriormente un par de artículos sobre vistas materializadas (<i>materialized views</i>): uno sobre los <a href="/2007/06/vistas-materializadas-materialized.html">aspectos generales de las vistas materializadas en SQL y PLSQL</a> y otro sobre <a href="/2007/12/el-refresco-de-las-vistas.html">el refresco de las vistas materializadas en SQL y PL/SQL</a>. En este artículo voy a tratar una de las funcionalidades soportadas por las vistas materializadas, funcionalidad conocida como <i>QUERY REWRITE</i>.</p>
<div class="separator" style="clear: both;"><a href="/2008/04/vistas-materializadas-y-la.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="La funcionalidad de reescritura de consultas y las vistas materializadas" title="Vistas materializadas y la funcionalidad Query Rewrite" border="0" width="400" data-original-height="262" data-original-width="502" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ5EABs7mMAJd5QFYUD2gfnXbY6cD0dwyEzlZ7h8N6LcQ5Lm5YelXIY8aiUNHxutCzz8te-NiZCpxxU3q6f70-J5Phee5OLmllfrzGSYCG3eviTlMLpWENnvux-qKIclu9IT91wdnWJ5imJ5KZFNBOPH_EJwXPJcc7tnKuSmnsPGOTJhJv5dym/s400/Vistas-Materializadas-Query-Rewrite.png"></a></div>
<h2 style="font-size:130%">Funcionalidad de reescritura de una consulta</h2>
<p>Esta claro que acceder a una vista materializada puede ser significativamente más rápido que acceder a todas las tablas base utilizadas al crear dicha vista materializada. Es por esta causa por la que, si así lo hemos indicado al crear la vista materializada, el <a href="/2006/12/hints-en-plsql-para-el-modo-de.html">optimizador Oracle</a>, si la consulta o <i>query</i> lo permite, puede reescribir el plan de ejecución de dicha consulta para acceder a la vista en lugar de a las tablas base. Obviamente, la reescritura de la consulta es transparente a las aplicaciones que la estén utilizando. Así pues, de alguna manera, el uso del <i>QUERY REWRITE</i> es similar al uso de un índice.</p>
<a href="http://www.plsql.biz/2008/04/vistas-materializadas-y-la.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-77116044402389062542023-10-24T06:30:00.001+02:002023-11-28T13:19:24.003+01:00Tuning o puesta a punto de consultas SELECT COUNT(*) en PL/SQL<p>De vez en cuando recibo consultas sobre cómo sería posible <b>mejorar el rendimiento de sentencias PL/SQL concretas</b>. En la mayoría de los casos contestar a estas preguntas puede ser poco menos que imposible, más que nada porque realizar el <b><i>tuning</i> de una consulta PL/SQL</b> sin conocer el contexto en que se ejecuta dicha consulta resulta muy complicado. Cada vez que esto ocurre siempre me asaltan preguntas como: ¿por qué se ejecuta dicha consulta?, ¿puede eliminarse la consulta y ser incluida en otro proceso?, ¿está la consulta dentro de un bucle LOOP y realmente debe formar parte del bucle?, ¿están creados todos los índices que podrían acelerar su ejecución? Por si esto fuera poco, una vez que tenemos la respuesta a preguntas como las antes mencionadas, sin duda, surgirán nuevas preguntas.</p>
<div class="separator" style="clear: both;"><a href="/2011/04/tuning-consultas-select-count-plsql.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Sintaxis de la cláusula COUNT" title="Tuning o puesta a punto de consultas SELECT COUNT(*) en PL/SQL" border="0" data-original-height="258" data-original-width="580" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNckiYA93PaiSd3k-feislcI8vZ4AdjywbvHuhREMu9Zg1TiM2AZpAZsurUefuZWT4zBktvv-ozxxAZ1Su9bZso5BxN-AkMIp56rQhtelLX-0V8q4lcL7H_BRY9F4sb5VjdmR9Q4o6P1OF40PKPHPK9PD2nf5VnK7Q7ycl1t1IwxBsI3HHyP4h/s1600/SELECT-COUNT.jpg" width="400"></a></div>
<p>No obstante, el otro día un asiduo lector de este blog me envió una <b>consulta SELECT</b> bastante sencilla que, aún utilizando los índices de forma adecuada y ejecutándose bastante rápido, terminaba consumiendo muchos recursos de CPU en su base de datos Oracle debido a que era ejecutaba con mucha frecuencia dentro un procedimiento PLSQL. Dicho lector me pedía ayuda para realizar el <i>tuning</i> o puesta a punto de la mencionada consulta.</p>
<a href="http://www.plsql.biz/2011/04/tuning-consultas-select-count-plsql.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com5tag:blogger.com,1999:blog-26801181.post-50379224728763398952023-10-03T06:30:00.000+02:002023-10-03T15:55:05.433+02:00Optimización SQL y PL/SQL - Código compartido<p>Cuando alguien solicita la ejecución de algún código SQL o PL/SQL, Oracle busca dicho código o sentencia en el área de SQL compartido. Si la sentencia y su correspondiente análisis sintáctico (<i>parsing</i>) existen en la librería caché de la base de datos, entonces Oracle reutiliza el ejecutable correspondiente. Dentro de este área de SQL compartido, cada sentencia SQL ocupa un espacio determinado conocido como área contextual o, en terminología inglesa, <i>cursor</i> (ojo, esto no tiene nada que ver con los <a href="/2006/12/cursores-en-plsql.html">cursores PL/SQL</a>). <span style="font-weight:bold;">Cada <i>cursor</i> localizado en el área de SQL compartido contiene la siguiente información</span>:</p>
<div class="separator" style="clear: both;"><p><a href="/2008/01/optimizacin-sql-y-plsql-cdigo.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Optimización de la base de datos Oracle mediante el uso de código compartido o los shared cursors" title="Optimización SQL y PL/SQL - Código compartido" border="0" data-original-height="350" data-original-width="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI-QVbhFuHeImVqrLGeT5Z_fnfTZcmqHszekp8OM2LXQXJ6kAWsxtrEEHL3VgvfPcZvYrSBt3V0gQWMTwPTuf_74qYbbjGFq-Nia8CTWmf6b46clGf2QLW1dVwmWVGJD-Uns54BF1uahKQQrO6mo_bL0UitO1Pz8qcwsuMUEIvl5lWG88HppAh/s1600/shared-pool.png"></a></p></div>
<p>- El análisis sintáctico de la sentencia SQL (ver artículo sobre <a href="/2007/04/fases-durante-el-procesamiento-de-una.html">las fases del procesamiento de una sentencia SQL</a>).</p>
<p>- El <a href="/2007/05/cmo-obtener-el-plan-de-ejecucin-de-una.html">plan de ejecución</a>.</p>
<p>- La lista de objetos de la base de datos que son referenciados por la sentencia.</p>
<p>Si dos usuarios ejecutan la misma sentencia SQL o PL/SQL, entonces ambos utilizaran el mismo <i>cursor</i>. Los <span style="font-weight:bold;">beneficios de los <i>cursores</i> compartidos</span> son evidentes:</p>
<a href="http://www.plsql.biz/2008/01/optimizacin-sql-y-plsql-cdigo.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com3tag:blogger.com,1999:blog-26801181.post-59665365555032389692023-09-05T06:30:00.000+02:002023-09-05T11:06:31.983+02:00El optimizador PL/SQL basado en normas (Rule-Based Optimizer)<p>En este artículo voy a mencionar algunas de las características del <span style="font-weight:bold;">optimizador PL/SQL basado en normas</span> (<i>Rule-Based Optimizer</i>). Lo primero que quiero mencionar es que Oracle recomienda utilizar el optimizador PLSQL basado en costes (<i>cost-based optimizer</i>), no obstante, en algunos casos, el hecho de tener que activar las estadísticas de la base de datos para poder utilizar este último optimizador, puede hacer que resulte interesante utilizar el optimizador basado en normas y dejar las estadísticas desactivadas para no afectar al <a href="/2006/08/bucles-y-problemas-de-rendimiento.html">rendimiento de la base de datos</a>.</p>
<div class="separator" style="clear: both;"><p align="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzA0kA22gqn9H01wvnxlxgoMH9afitvu0-B37g-NvWYHWJQmowqSo5ezYgYHA8uzoPrZ1QuDOOYXEXR9osrZ-j5yBpo1YrnYWCLHMLCGQqNbswPwX2CUPmp3exIFjlcNTreNcT6JYDpVW5_R-FcAU29nadjw9KsmGu0rmZ2RgNG2OWm8lfhk6e/s484/componentes-optimizador.jpg"><img alt="Componentes del Optimizador Oracle" title="El optimizador PL/SQL basado en normas (Rule-Based Optimizer)" border="0" width="400" data-original-height="375" data-original-width="484" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzA0kA22gqn9H01wvnxlxgoMH9afitvu0-B37g-NvWYHWJQmowqSo5ezYgYHA8uzoPrZ1QuDOOYXEXR9osrZ-j5yBpo1YrnYWCLHMLCGQqNbswPwX2CUPmp3exIFjlcNTreNcT6JYDpVW5_R-FcAU29nadjw9KsmGu0rmZ2RgNG2OWm8lfhk6e/s400/componentes-optimizador.jpg"/></a><br />
<b>Componentes del Optimizador Oracle</b></p></div>
<p>El optimizador PLSQL basado en normas utiliza siempre que puede los índices, incluso cuando las tablas son pequeñas o cuando el número de registros que devuelve la sentencia <i>SELECT</i> es un porcentaje elevado con respecto al número total de registros de la tabla, casos para los que es mejor realizar un escaneado total (<i>full scan</i>) ya que la respuesta es más rápida (mejora el rendimiento). Esto es debido a que el optimizador basado en normas no hace uso de valores estadísticos, tales como el <a href="/2007/06/identificacin-de-tablas-y-columnas-en.html">número total de registros de una tabla</a>.</p>
<p><p>El optimizador PL/SQL basado en normas hace uso del siguiente orden de prioridades para determinar cual va a ser la forma de acceder a las tablas y determinar finalmente cual va a ser el <a href="/2007/05/cmo-obtener-el-plan-de-ejecucin-de-una.html">plan de ejecución</a>:</p>
<blockquote style="font-family: courier new; font-size:85%;">Prio Forma de acceso<br />
1 Single row by ROWID<br />
2 Single row by cluster join<br />
3 Single row by hash cluster key with unique or<br />
primary key<br />
4 Single row by unique or primary key<br />
5 Cluster join<br />
6 Hash cluster key<br />
7 Indexed cluster key<br />
8 Composite index<br />
9 Single-column index<br />
10 Bounded range search on indexed column<br />
11 Unbounded range search on indexed column<br />
12 Sort-merge join<br />
13 MAX or MIN of indexed column<br />
14 ORDER BY on indexed column<br />
15 Full table scan</blockquote>
<p>Los distintos métodos de acceso los he dejado en inglés, ya que es bastante complicado traducir esta terminología. En el presente artículo no voy a explicar cuales son las diferencias existentes entre las distintas formas de acceso. No obstante, en sucesivos artículos pondré algunos ejemplos que permitirán diferenciar estos conceptos.</p>
<p>Siguiendo con el tema que concierne a este <i>post</i>, el optimizador basado en normas analiza la sintaxis de la sentencia SQL para establecer los distintos métodos de acceso a las tablas. Básicamente lo que hace es determinar todas las formas de acceso posibles y escoger aquella que tiene una prioridad menor.</p>
<p>Este esquema siempre asume que un escaneado total (<i>full scan</i>) es el peor método de accesso (prioridad 15). Sin embargo, ya he mencionado al principio del artículo que esto no siempre es verdad.</p>
<p>Estos métodos de acceso, así como otros adicionales, están también disponibles para el optimizador PL/SQL basado en costes. Sin embargo, este optimizador ignora las prioridades, y determina el coste esperado de ejecución de la sentencia SQL para cada uno de las formas de acceso posibles basándose en las estadísticas, escogiendo después aquella forma de acceso con el menor coste estimado. Muchas funcionalidades del Oracle, como los <i>hash joins</i>, <i>star queries</i> e histogramas, sólo están disponibles para el optimizador PLSQL basado en costes.</p>
<p>Artículos relacionados: <br />
- <a href="/2006/12/hints-en-plsql-para-el-modo-de.html">Hints PLSQL para determinar el modo de optimización</a>.<br />
- <a href="/2007/01/hints-en-plsql-para-determinar-el-mtodo.html">Hints PL/SQL para forzar la forma de accesso</a>.</p>
JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-76358838388074957872023-07-24T06:30:00.001+02:002023-07-24T09:51:18.125+02:00El paquete estándar DBMS_LOCK para sincronizar procesos<p>Hace unas semanas alguien me preguntó como se podía determinar si un procedimiento PL/SQL (<i>procedure PLSQL</i>) estaba siendo ejecutado para evitar tener dos instancias del mismo proceso corriendo simultáneamente. Para manejar este tipo de situaciones, así como situaciones en las que queramos ejecutar procedimientos y funciones de forma secuencial y sincronizar diferentes procesos, Oracle dispone de el paquete de funciones y procedimientos <b>DBMS_LOCK</b>.</p>
<div class="separator" style="clear: both;"><p><a href="/2009/02/el-paquete-estandar-dbmslock-para.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Paquete estandar Oracle PL/SQL DBMS_LOCK" title="El paquete estándar DBMS_LOCK para sincronizar procesos" border="0" width="400" data-original-height="533" data-original-width="799" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6h-wHlP6zcFzMsEHnK20gYf0qq494_oFGhywtjFTEB5e3sap2h3kb0Ol12mdcN1amWb13FQ0TjZ9vZBkhGrSMihY578uWbdyU6snb82LXitKRJcdsogCy7Ce3wUzAjTDlPUdXY6fUIxy-c6GCwiKb1p3Jo_Vfn7ayQXUdKH7tvY0bSzgwBfQP/s400/dbms_lock.jpg"></a></p></div>
<p>Con el paquete <b>DBMS_LOCK</b> podemos establecer bloqueos de usuario (<i>PL/SQL User Locks (UL)</i>) con los que podremos parar la ejecución de un procedure si al ejecutarlo nos encontramos con que un determinado bloqueo o <i>lock</i> está en proceso.</p>
<a href="http://www.plsql.biz/2009/02/el-paquete-estandar-dbmslock-para.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com3tag:blogger.com,1999:blog-26801181.post-81450906582309897462023-07-05T06:30:00.000+02:002023-07-05T12:40:35.805+02:00Cambios de rendimiento en una sentencia SQL al activar el trazado<p>Hace unos días un lector del blog me enviaba un email contándome un <i>"extraño"</i> problema de rendimiento que tenía con una sentencia SQL o PL/SQL. Dicha sentencia SQL tardaba mucho tiempo en devolver resultados y, tras activar la <a href="/2007/05/como-usar-la-utilidad-de-trazado-del.html">utilidad de trazado SQL</a> (<i>SQL_TRACE=TRUE</i>), el problema desaparecía y la respuesta de la sentencia SQL era inmediata.</p>
<div class="separator" style="clear: both;"><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSnwcWTBL2KwJgQZgi9U9PtTXOFUvK-r2O6x_fXKdjRt5-KZsZd2dJqBo1CLrNKm-vzYWwy9eZ7-cBHh1hVsVtoGPx7m_4jHZQ0ohcjaI_KZKs_oBGy2Lud5PxN0TmOig4zSU2PioH28ENPGn3gO2fR1hA3IUVKfSPCltQlRiYa72b8lzu-rn6/s840/Activar-SQL-Trace.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="Cambios de rendimiento en una sentencia SQL al activar el trazado" title="Cambios de rendimiento en una sentencia SQL al activar el trazado" border="0" width="400" data-original-height="526" data-original-width="840" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSnwcWTBL2KwJgQZgi9U9PtTXOFUvK-r2O6x_fXKdjRt5-KZsZd2dJqBo1CLrNKm-vzYWwy9eZ7-cBHh1hVsVtoGPx7m_4jHZQ0ohcjaI_KZKs_oBGy2Lud5PxN0TmOig4zSU2PioH28ENPGn3gO2fR1hA3IUVKfSPCltQlRiYa72b8lzu-rn6/s400/Activar-SQL-Trace.jpg"></a></p></div>
<p>La verdad es que el fenómeno no es tan extraño una vez que se conoce la causa. Cuando se activa el trazado haciendo <i>SQL_TRACE=TRUE</i>, lo que ocurre es que la sesión Oracle utiliza una nueva <a href="/2008/01/optimizacin-sql-y-plsql-cdigo.html">área de SQL compartido</a>. Esto supone que el <i>parsing</i> (ver artículo sobre las <a href="/2007/04/fases-durante-el-procesamiento-de-una.html">fases durante el procesamiento de una sentencia SQL</a>) de cualquier sentencia SQL que se ejecute después de activar el trazado vuelva a tener lugar o que, de existir una versión de dicha sentencia SQL ya <i>parseada</i> en la nueva área de SQL compartido, dicha versión no coincida con la versión existente cuando el trazado no está activo. Esto causa que, cuando la sentencia SQL utiliza variables (<i>bind variables</i>), puesto que los valores reales de dichas variables son tomados en el momento del <i>parsing</i>, muy probablemente, los <a href="/2007/05/cmo-obtener-el-plan-de-ejecucin-de-una.html">planes de ejecución</a> de la misma sentencia SQL sean diferentes antes y después de activar el trazado al haberse generado utilizando valores de variable distintos.</p>
<a href="http://www.plsql.biz/2008/01/cambios-de-rendimiento-en-una-sentencia.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com3tag:blogger.com,1999:blog-26801181.post-56511508247186352022023-06-15T06:30:00.000+02:002023-06-15T16:04:55.346+02:00El refresco de las vistas materializadas en SQL y PL/SQL<p>Ya he hablado en otro artículo acerca del <a href="/2007/06/vistas-materializadas-materialized.html">funcionamiento básico de las vistas materializadas</a> (<a href="/2007/06/vistas-materializadas-materialized.html"><i>materialized views</i></a>), en éste voy a exponer los distintos tipos de refresco en SQL y PLSQL que se pueden utilizar para actualizar una vista materializada con los cambios provocados por las actualizaciones en las tablas base utilizadas en la misma. <span style="font-weight:bold;">El tipo de refresco que debemos elegir dependerá de la frecuencia de actualización de las tablas base y de las necesidades que tengamos de disponer de datos exactos</span>.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhwgUAoD3eT489i4lVtU3m0UMGcFE0Sgdlc6HRwW-veyqjK4HZl97HTZ1tjfQCZWYCGsXHgtSAnGg9x_1wDKrNs4Gn5D3GLUdPUkigGcbBWfXgDqHtA4OnlEoe92NdM42GPb1fGyFqhz_f4SohbW3EaFVvTNmdTpd6b6O7CVSSJpx9juJAyA/s765/refresh-materialized-views.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="Materialized View Refresh" title="El refresco de las vistas materializadas en SQL y PL/SQL" border="0" width="400" data-original-height="635" data-original-width="765" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhwgUAoD3eT489i4lVtU3m0UMGcFE0Sgdlc6HRwW-veyqjK4HZl97HTZ1tjfQCZWYCGsXHgtSAnGg9x_1wDKrNs4Gn5D3GLUdPUkigGcbBWfXgDqHtA4OnlEoe92NdM42GPb1fGyFqhz_f4SohbW3EaFVvTNmdTpd6b6O7CVSSJpx9juJAyA/s400/refresh-materialized-views.png"></a></div>
<h2 style="font-size:130%">Tipos de refresco</h2>
<p><span style="font-weight: bold;">COMPLETE</span>: Este tipo de refresco implica el borrado de los datos existentes y la reinserción de todos los datos mediante la reejecución de la consulta <i>SELECT</i> que define la vista materializada.</p>
<a href="http://www.plsql.biz/2007/12/el-refresco-de-las-vistas.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com30tag:blogger.com,1999:blog-26801181.post-79866344202560156572023-05-30T06:30:00.000+02:002023-05-30T17:12:40.058+02:00Funcionalidad errorlogging del SQL*Plus<p>Hasta la versión de la base de datos Oracle 10g Release 2 no era posible <b>capturar en SQL*Plus los errores que se generan cuando escribíamos incorrectamente una sentencia SQL</b>. Es decir, los errores conocidos como SP2 no podían ser gestionados por las funcionalidades estándar del SQL*Plus OSERROR o SQLERROR. Esto era algo normal ya que los errores SP2 no son errores del tipo OS, como el típico error "<i>unable to open spool file</i>", ni tampoco son errores de tipo SQL o PLSQL, ya que la sentencia que hemos escrito incorrectamente en realidad no se trata de ningún comando SQL y nunca llegó a alcanzar la capa SQL o PL/SQL de la base de datos Oracle.</p>
<div class="separator" style="clear: both;"><a href="/2010/10/set-errorlogging-sql-plus-oracle-11g.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Funcionalidad errorlogging del SQL*Plus de Oracle" title="Funcionalidad errorlogging del SQL*Plus" border="0" width="400" data-original-height="571" data-original-width="833" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN9aqr3Tdpn67bVZsD1LkDuSgeeYc9a1gGCBB8lX7DVcYEtjiSjcboUqPwzJhsOXic7YJbVUYysg9Q-7BJ8Not78EWoyPKUEQrVbI9oL_boXh2dmmee2olmv9esKLuqDGsq8967oO94RhIAEsBKiZVAOQsQcjsf0IU6Yu8n23S4RVhrx8QAw/s400/funcionalidad-errorlogging.jpg"></a></div>
<p>Para los que todavía estén un poco confundidos y aún no hayan identificado cuáles son <b>los errores SQL de tipo SP2</b> os dejo el siguiente ejemplo:</p>
<a href="http://www.plsql.biz/2010/10/set-errorlogging-sql-plus-oracle-11g.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-17862010008981150072023-05-10T06:30:00.001+02:002023-05-10T10:22:56.056+02:00SQL y PL/SQL - La sentencia INSERT multitabla<p>La versión 9i de las bases de datos Oracle introdujo la posibilidad de utilizar sentencias <i>INSERT</i> multitabla. Así pues, la sentencia SQL o PLSQL <i>INSERT... SELECT</i> cambió ligeramente su sintaxis, de manera que ahora permite la inserción de datos en más de una tabla de la base de datos de forma paralela. Existen dos formas de utilizar el comando <i>INSERT</i> multitabla: no condicional y condicional. En la forma no condicional, una cláusula compuesta <i>INTO</i> se ejecuta cada vez que la consulta <i>SELECT</i> devuelve un registro. En la forma condicional, las cláusulas compuestas <i>INTO</i> figuran dentro de cláusulas <i>WHEN</i> a partir de las que se determina si la correspondiente cláusula compuesta <i>INTO</i> se ejecuta o no.</p>
<div class="separator" style="clear: both;"><a href="/2007/11/sql-y-plsql-la-sentencia-insert.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="332" data-original-width="612" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU2jUX0awM1-YJxux_3JZF9UA_j5mB48RpwECZQ2MTxAwUa5lnunxUEG6ebPhgk0s8bjxqY0BPI5COM8nbZJ44wUAYCYTbummSjMAt67Beccs2R2BjaN85RnQKtPqJVUgwGg917ovT0TX1S2WPlXHYKnuOdSilFeoPA0JGBrdmMQ4YzcGgwg/s400/Sentencia-INSERT-Multitabla.png" title="SQL y PL/SQL - La sentencia INSERT multitabla" alt="Sentencia INSERT multitabla"></a></div>
<p>Una claúsula compuesta <i>INTO</i> consiste de una o más cláusulas <i>INTO</i>. Una cláusula <i>INTO</i> debe especificar la tabla de la base de datos sobre la que se van a insertar los datos. Esta cláusula no admite alias. La cláusula <i>INTO</i> tambien proporciona el valor del los campos a ser insertados mediante la cláusula <i>VALUES</i>. La expresiones usadas en la cláusula <i>VALUE</i> pueden tratarse de cualquier expresión permitida, pero siempre debe hacer referencia a columnas devueltas por la consulta <i>SELECT</i> incluida en el <i>INSERT</i>.</p>
<a href="http://www.plsql.biz/2007/11/sql-y-plsql-la-sentencia-insert.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-19163875234008123702023-04-19T06:30:00.000+02:002023-04-19T11:15:28.127+02:00Ejecución de cursores PLSQL y sentencias DML utilizando SQL dinámico nativo (Native Dynamic SQL)<p>Una de las preguntas más frecuentes que me suele hacer la gente es acerca de la posibilidad de <b>definir un <a href="/2007/03/procedimientos-y-funciones-en-plsql.html">procedimiento PL/SQL</a> en el que se declaren múltiples <a href="/2006/12/cursores-en-plsql.html">cursores</a></b> en base al valor de los parámetros de entrada de dicho procedimiento. Las preguntas suelen incluir condiciones muy variadas, pero lo normal es que los implicados sólo necesiten hacer variable la cláusula WHERE y que el resto del cuerpo del cursor PLSQL se mantenga fijo. Cuando esto ocurre yo siempre contesto remitiendo a los que preguntan al artículo que escribí sobre el <a href="/2008/08/paquete-dbmssql-para-utilizar-sql.html"><b>paquete estándar PL/SQL DBMS_SQL</b></a>, un paquete que <b>permite crear sentencias SQL dinámicas</b>.</p>
<div class="separator" style="clear: both;"><p><a href="/2010/09/sql-dinamico-nativo-cursor-dml-update.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="SQL dinámico en Oracle" title="Ejecución de cursores PLSQL y sentencias DML utilizando SQL dinámico nativo (Native Dynamic SQL)" border="0" width="400" data-original-height="450" data-original-width="550" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDW82IpAygWTrxpJ3SOBHz3VT5qft9AGXhvutTZsu4T6ir_KWrUIoH9TEnW5DWuLIiGo0rFq7OjSAvkInoerXJs85jjPmUZMWyWwzJCJXbKYOWIHAwyckPH0Rtpy3x0JinKh-40gTdAFsPRGWv-rEoSbYjAU9OLszUET33hg_Zo150EVeXOg/s400/SQL-Dinamico.png"></a></p></div>
<p>Si he decidido escribir un artículo nuevo al respecto es por el hecho de que <b>resulta mucho más legible un código que utilice directamente SQL dinámico nativo</b>, es decir, un código en el que no se utiliza el paquete estándar DBMS_SQL. A continuación os dejo un sencillo ejemplo de cómo se podría construir, utilizando SQL dinámico nativo, un <b>procedimiento PLSQL en el que se define un cursor cuya cláusula WHERE varíe en función de un parámetro</b>.</p>
<a href="http://www.plsql.biz/2010/09/sql-dinamico-nativo-cursor-dml-update.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com15tag:blogger.com,1999:blog-26801181.post-15559081256720646672023-03-27T06:30:00.000+02:002023-03-27T15:34:40.903+02:00Cláusula DEFAULT para definición de columnas - Base de datos Oracle 12c<p>Las mejoras fundamentales que aporta la <b>cláusula DEFAULT de la versión 12c</b> de las bases de datos Oracle para definición de las columnas: una significativa <b>mejora del rendimiento</b> y una mayor facilidad para inicializar los datos de los registros de una tabla, lo que al final implica <b>menos líneas de código</b>.</p>
<div class="separator" style="clear: both; text-align: center;"><p><a href="/2016/08/clausula-default-para-definicion-de-columnas.html#more" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm3DPuQ6wlOcnFaeQ59MhcuqhHIjXubDzqfthhbQA77N710qg92p0WYNDwkRxy1rmXFgBIkF8K_DpElBH0embVjDJXVpg0SvxSTT_9kifBGqRK12zu6ljUTngZRqzmFhsonu3b/s400/clausula-default.jpg" width="400" height="211" alt="Cláusula DEFAULT" title="Cláusula DEFAULT para definición de columnas - Base de datos Oracle 12c"></a></p></div>
<p>Supongamos que para una tabla concreta necesitamos que, cuando se inserta un nuevo registro, un campo determinado tome el valor de una secuencia. La forma en que implementaríamos este requerimiento en versiones anteriores a la 12c sería mediante un <a href="/2007/02/triggers-en-plsql.html">trigger PLSQL</a>.</p>
<a href="http://www.plsql.biz/2016/08/clausula-default-para-definicion-de-columnas.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-69451987619905576012023-03-09T06:30:00.000+01:002023-03-09T14:24:05.440+01:00Cláusula BULK COLLECT para mejorar el rendimiento al realizar procesamiento masivo<p>Yo siempre he dicho que cuando para hacer algo se pueden utilizar sentencias SQL sencillas, no resulta conveniente emplear complicados <a href="/2007/03/procedimientos-y-funciones-en-plsql.html">procedimientos PL/SQL</a> que implementen la misma solución. Sin embargo, hay situaciones en que para mejorar el rendimiento de determinados bucles FOR en los que se realizan actualizaciones masivas sobre una determinada tabla de la base de datos Oracle, resulta conveniente utilizar <b>técnicas PLSQL de procesamiento masivo</b> (lo que en inglés se denomina <b><i>BULK COLLECT</i></b>).</p>
<div class="separator" style="clear: both;"><p><a href="/2011/09/clausula-bulk-collect-plsql.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Arquitectura PL/SQL" title="Cláusula BULK COLLECT para mejorar el rendimiento al realizar procesamiento masivo" border="0" width="400" data-original-height="304" data-original-width="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUVTlW7qvOlhdnWzA0LArWPpQOlFbE311hlrINyJPMrFLPMvi8wGN8lzFFJJ2eNQevb-WaJwHbtLAla9RnIm5NTDm5x-sFV-jz_N7j6Ho8TD8Z4gbebg2Z6PJemptixmEpkn9NF8PldUnexqLYaJl0kmDnhi0ab6eoAjoM2OYOwMUDC1dUKg/s400/arquitectura-plsql.jpg"></a></p></div>
<p>Para entender mejor en qué consiste esta técnica, primero hay que comprender los motivos por los que un simple bucle FOR puede generar importantes problemas de rendimiento. Veamos el siguiente código PL/SQL:</p>
<a href="http://www.plsql.biz/2011/09/clausula-bulk-collect-plsql.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com23tag:blogger.com,1999:blog-26801181.post-72680107637749603522023-02-21T06:30:00.000+01:002023-02-21T15:29:46.858+01:00La cláusula PIPELINED en las funciones PL/SQL y la excepción NO_DATA_NEEDED<p>En esta entrada explicaré para que sirve la <b>cláusula PIPELINED</b> en las <a href="/2007/03/procedimientos-y-funciones-en-plsql.html"><b>funciones PL/SQL</b></a>, y como se debe utilizar la excepción <b>NO_DATA_NEEDED</b>, que nada tiene que ver con la excepción NO_DATA_FOUND, para controlar las funciones PLSQL que incluyen dicha cláusula y que en inglés se denominan <b><i>pipelined functions</i></b>. Primero quiero remarcar que la funcionalidad <i>pipelined</i> fue introducida por primera vez en la versión 9i de las bases de datos Oracle. Básicamente, el uso de la cláusula PIPELINED resulta de gran utilidad y es prácticamente imprescindible cuando necesitamos que en lugar de una tabla sea una rutina PL/SQL la que nos sirva como fuente de datos.</p>
<div class="separator" style="clear: both;"><a href="/2010/07/pipelined-funcion-plsql-no-data-needed.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Pipelined functions o funciones tubería en PL/SQL" title="La cláusula PIPELINED en las funciones PL/SQL y la excepción NO_DATA_NEEDED" border="0" width="400" data-original-height="525" data-original-width="829" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdrIpLZMFj1I-dxe8EUOr3rHvrBD36EDRMkFCyZ4LgL4oPUeTB-Ctf5BbAbGb7TMNI2TvrSZHUJ1nxX6_iHQkcMDQjdbT6eKBLCAoMSDoIlDULVHKUQmd7tPg6fLDIl2gW71y4JmmI1dVbsFFMJ9xQZo7EB1Cyl9SO93mZAW1bh6Yjff8N_w/s400/pipelined-table-function.jpg"></a></div>
<p>La mejor forma de explicar el funcionamiento de esta cláusula es con un <span style="font-weight:bold;">ejemplo</span>. </p>
<a href="http://www.plsql.biz/2010/07/pipelined-funcion-plsql-no-data-needed.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com7tag:blogger.com,1999:blog-26801181.post-66956152489766740252023-01-18T06:30:00.000+01:002023-01-18T08:51:28.364+01:00¿Qué es mejor para el rendimiento, utilizar consultas PLSQL con subqueries o con joins?<p>Alguna vez me han llegado cuestiones en la que se me preguntaba qué es mejor, en términos de rendimiento de las bases de datos Oracle, <span style="font-weight:bold;">si utilizar en las consultas PLSQL subqueries</span> (subconsultas) <span style="font-weight:bold;">o utilizar joins</span> (es decir, listar todas las tablas en la clausula FROM y unirlas en el WHERE). Lo primero que hay que tener claro es que escribir una consulta PL/SQL utilizando subqueries o utilizando joins es semánticamente diferente; además, utilizar una u otra forma puede derivar en que ambas consultas devuelvan resultados diferentes y que no sean directamente intercambiables.</p>
<div class="separator" style="clear: both;"><p><a href="/2011/03/subqueries-o-joins-rendimiento-plsql.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Subqueries vs Joins" title="Qué utilizar en PLSQL, subqueries o joins" border="0" width="400" data-original-height="526" data-original-width="819" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioHzT0ijMcwltdN9TvMQXrWgNCoMGgsVq618suFFEfeMQEYC1BRGzqt2KdRJ2TRseq2i2_eJzyeoS3kd78gIW8I6_g4x7i5fTMXjSTyWULlDIc9zqiZ5hFaBhWhyX4rPbe6QbSQNIzIDQk9TR0JNTJl6EHC9xXQqE501ffCzugev8XvyKcng/s400/subqueries-joins.png"></a></p></div>
<p>Lo que yo recomiendo para elegir entre un tipo de consulta u otro es, en general, hacer lo siguiente:</p>
<ul><li><span style="font-weight:bold;">Utilizar una subquery o subconsulta</span> cuando no se necesita ninguna columna de la tabla que es referenciada en la subquery.</li>
<li><span style="font-weight:bold;">Utilizar un join</span> en caso de necesitar alguna de las columnas.</li></ul>
<a href="http://www.plsql.biz/2011/03/subqueries-o-joins-rendimiento-plsql.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com3tag:blogger.com,1999:blog-26801181.post-30179093957703854512022-12-21T06:30:00.000+01:002022-12-21T17:37:34.654+01:00SQL y PL/SQL - La sentencia MERGE<p>La sentencia <i>MERGE</i>, a la que muchos denominan <i>UPSERT</i> debido a su funcionalidad, está disponible desde la aparición de la versión 9i de la base de datos Oracle. Se trata de una de las funcionalidades del <i>kernel</i> de Oracle más utiles a la hora de permitir el uso de la <a href="https://es.wikipedia.org/wiki/ETL" target="_blank" rel="nofollow">tecnología <i>ETL</i></a> (<i>Extract, Transform and Load</i> - Extraer, Transformar y Cargar) con las bases de datos Oracle. Este tipo de tecnología puede utilizarse y está especialmente enfocada para ser usada en aplicaciones de <a href="https://es.wikipedia.org/wiki/Almac%C3%A9n_de_datos" target="_blank" rel="nofollow"><i>data warehousing</i></a> (almacen de datos). Básicamente, <b>lo que permite la sentencia SQL <i>MERGE</i> es, dependiendo de una condición lógica, actualizar registros (<i>UPDATE</i>) cuando la condición se cumple, o insertar registros (<i>INSERT</i>) cuando dicha condición no se cumple</b>, de ahí surge la denominación de <i>UPSERT</i>.</p>
<div class="separator" style="clear: both;"><p><a href="/2007/11/sql-y-plsql-la-sentencia-merge.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="MERGE" titl="SQL y PL/SQL - La sentencia MERGE" border="0" width="400" data-original-height="382" data-original-width="688" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3W2zkSMIxkUTHtlwjSAMwJy7Zx5Tja7rSX9vdkgHW9HHDaWpljojSZW4TXcOAhfwe9GLo2ZiRuiq-Vt8VXzfjx2xfks3eMKdmNLDPxBbX6DQnAHRqw5Zy6SdVSmMyBV9DNZwEzJSCVfJc33HHWgz4R7sT13yrqXbKVNu0nS3J5rqKrxeu_A/s400/sentencia-MERGE.jpg"></a></p></div>
<p>Anteriormente a la versión 9i de Oracle, la alternativa en SQL era ejecutar dos sentencias DML, un <i>UPDATE</i> y un <i>INSERT</i>, cada una utilizando condiciones lógicas opuestas. En cuanto a las alternativas en PL/SQL eran: bien intentar insertar un registro y si la sentencia <i>INSERT</i> fallaba debido a una <a href="/2007/01/manejo-de-excepciones-el-plsql.html">excepción PLSQL</a> del tipo <i>DUP_VAL_ON_INDEX</i>, entonces realizar un <i>UPDATE</i> del registro en cuestión; bien intentar actualizar un registro y si la sentencia <i>UPDATE</i> devolvía <i>SQL%NOTFOUND</i>, entonces ejecutar la correspondiente sentencia <i>INSERT</i>.</p>
<a href="http://www.plsql.biz/2007/11/sql-y-plsql-la-sentencia-merge.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com13tag:blogger.com,1999:blog-26801181.post-30807585255460237682022-11-24T06:30:00.000+01:002022-11-24T14:08:41.782+01:00Hints avanzados en PL/SQL para forzar la forma de acceder a una tabla<p>Ya he hablado anteriormente acerca de los <a href="/2007/01/hints-en-plsql-para-determinar-el-mtodo.html"><i>hints</i> PLSQL más comunes (<i>FULL, ROWID, INDEX, NO_INDEX</i>) para forzar el método de accesso a una tabla</a> Oracle. En este artículo voy a presentar algunos <i>hints</i> más de este tipo, que se utilizan menos frecuentemente, pero no por ello menos útiles.</p>
<div class="separator" style="clear: both;"><a href="/2007/08/hints-avanzados-en-plsql-para-forzar-la.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Hash Hint" title="Hints avanzados en PL/SQL para forzar la forma de acceder a una tabla" border="0" width="400" data-original-height="419" data-original-width="662" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEavgNsNgR-3MtuxUtAtWye6970vZtzoSJou3QyOGRmjbaNXxVq5LSl8oOjHEO-z_gRzicMQzFunBGMjrnv29LQYnTlZ58tZ_MJZUxqTQVRvUdpiLO5r0EbyxHERt-hOxAX4NbKC_XW0kTEe7IyMDdECrWPMzaL_7vXZrO88jCF6suPMw3JA/s400/Hash-Hint.jpg"></a></div>
<p><span style="font-weight: bold; font-style: italic;">CLUSTER (nombre_de_tabla)</span>: Fuerza el accesso a la tabla indicada utilizando un índice de tipo <i>cluster</i>. Los índices de este tipo se utilizan para localizar registros que comparten valores comunes de una forma rápida. La clave del índice <i>cluster</i> puede estar constituida por una o más columnas de la tabla. Los registros de la tabla son agrupados según la clave y almacenados físicamente juntos en el disco duro. </p>
<a href="http://www.plsql.biz/2007/08/hints-avanzados-en-plsql-para-forzar-la.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-35614392019042518322022-10-31T06:30:00.000+01:002022-10-31T16:59:23.209+01:00Identificación de tablas y columnas en una base de datos Oracle mediante sentencias SQL<p>Una vez que una tabla Oracle es creada utilizando el comando <i>CREATE TABLE</i>, la estructura de dicha tabla se puede visualizar utilizando las siguientes vistas (<i>views</i>) del sistema de la base de datos Oracle:</p>
<div class="separator" style="clear: both;"><a href="/2007/06/identificacin-de-tablas-y-columnas-en.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="DBA_TABLE - ALL_TABLES - USER_TABLES" title="Identificación de tablas y columnas en una base de datos Oracle mediante sentencias SQL" border="0" width="400" data-original-height="431" data-original-width="745" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcbL046-slR_rmQ9UeuspIs1CZM8WthhharCuxdnnSDtuDzeEnGj6an45R5nuf01dppwue0lhaMwJH7xVi7fO9lNsu6zBMd2h3DuCIW_YXHR2bbw_Bu8mZZRW7L0-lBGghJJ78JJESSlZqhPk1cN1y_30a3Enva8nQRPN6fB5RNImJpBh5aw/s400/DBA_TABLES-Oracle.jpg"></a></div>
<p><i style="font-weight: bold;">DBA_TABLES</i>: Muestra la información de la tabla a nivel de cabecera.</p>
<p><i style="font-weight: bold;">DBA_TAB_COLUMNS</i>: Muestra la información de la tabla a nivel de columna.</p>
<p><i style="font-weight: bold;">DBA_TAB_PRIVS</i>: Muestra los privilegios de acceso a las tablas de los usuarios de la base de datos.</p>
<p><i style="font-weight: bold;">DBA_COL_PRIVS</i>: Muestra los privilegios de acceso a nivel de columna. Es bastante raro tener la necesidad de definir permisos a nivel de columna, de hecho, yo nunca me he encontrado con una bases de datos Oracle que utilice esta funcionalidad.</p>
<a href="http://www.plsql.biz/2007/06/identificacin-de-tablas-y-columnas-en.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com3tag:blogger.com,1999:blog-26801181.post-36746200736390941792022-10-06T06:30:00.000+02:002022-10-06T10:33:12.901+02:00Cómo analizar la interdepencia entre los objetos de una base de datos Oracle<p>Para analizar y conocer las <b>dependencias existentes entre funciones, procedimientos, paquetes y triggers</b> a los que tiene acceso un usuario de la base de datos Oracle se debe utilizar la vista <b>USER_DEPENDENCIES</b>.</p>
<div class="separator" style="clear: both; text-align: center;"><p><a href="/2014/08/interdependencia-objetos-bases-de-datos-oracle.html#more" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0B5EDSAh9Cro23RDfIF1iSXe3gTl-zlZBtK4xRtMC-eEJzlOMVNb9PUPRyiyQXrKae3i9ZZWO1Rgo7c297sZ9nVk3vcLIk5XRdWBb_E2ObbyVs1whx-VndCi9m2yseB0TWQiu/s1600/USER_DEPENDENCIES.jpg" alt="USER_DEPENDENCIES" title="Como analizar la interdepencia entre los objetos de una base de datos Oracle"></a></p></div>
<p>Esta vista, sin ir más lejos, se puede utilizar para realizar un <b>análisis de nuestro código PL/SQL</b>, permitiendo por ejemplo identificar que programas necesitan ser revisados y actualizados si realizamos algún tipo de cambio sobre una tabla determinada de la base de datos.</p>
<a href="http://www.plsql.biz/2014/08/interdependencia-objetos-bases-de-datos-oracle.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com0tag:blogger.com,1999:blog-26801181.post-87598658612163326652022-09-20T06:30:00.000+02:002022-09-20T11:08:22.848+02:00La claúsula WITH en SQL y PL/SQL<p>La versión 9i de las bases de datos Oracle permite el uso de la claúsula <i>WITH</i> en SQL y PLSQL. Este comando permite reusar una consulta <i>SELECT</i> cuando esta hay que utilizarla más de una vez en una sentencia o consulta SQL compleja. Los resultados de la consulta definida en la claúsula <i>WITH</i> son almacenados en una tabla temporal pudiendo de esta forma mejorar el rendimiento de la sentencia principal.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPRSp4ewZ9Yf9rfIbiZvxThg9YEA5SlbDy1mLt-r8T5AACXxbtnagI2wnsPTWfFOHAvQBPVOlSPTHdXBY6R1gCfK8aUcTae9rN81KAi2cc2MHQBJ8cxTf8KbYbZCaq0Wu3nW02v_e0K-z6R5n6dgSxjNhNARjlT_2BjMYU1kQ4dBuYeW6wzg/s615/Clausula-WITH-AS.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="Claúasula WITH AS" title="La claúsula WITH en SQL y PL/SQL" border="0" width="400" data-original-height="464" data-original-width="615" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPRSp4ewZ9Yf9rfIbiZvxThg9YEA5SlbDy1mLt-r8T5AACXxbtnagI2wnsPTWfFOHAvQBPVOlSPTHdXBY6R1gCfK8aUcTae9rN81KAi2cc2MHQBJ8cxTf8KbYbZCaq0Wu3nW02v_e0K-z6R5n6dgSxjNhNARjlT_2BjMYU1kQ4dBuYeW6wzg/s400/Clausula-WITH-AS.jpg"></a></div>
<p>Aunque no siempre conseguiremos mejorar el rendimiento utilizando la claúsula <i>WITH</i>, lo que sin duda facilitaremos es la lectura y el mantenimiento del código PL/SQL o SQL. Dentro de la claúsula <i>WITH</i> daremos un nombre a las consultas <i>SELECT</i> a reutilizar (<i>WITH</i> admite la definición de múltiples consultas con sólo separarlas por comas), dicho nombre será visible para todas las consultas definidas posteriormente dentro del mismo <i>WITH</i>. Obviamente, también será visible para la sentencia o consulta principal.</p>
<a href="http://www.plsql.biz/2007/09/la-clasula-with-en-sql-y-plsql.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com7tag:blogger.com,1999:blog-26801181.post-43975663768597154602022-09-01T06:30:00.000+02:002022-09-01T14:14:12.982+02:00Operaciones aritméticas con fechas y la función TRUNC del PL/SQL<p>Siguiendo con el tema de algunos de los artículos de este blog, hoy pretendemos dejar ya zanjado el tutorial sobre como podemos trabajar en PL/SQL con los campos tipo DATE y TIMESTAMP de las bases de datos Oracle. En esta ocasión empezaremos hablando de las <b>operaciones aritméticas</b> que podemos realizar con estos campos y terminaremos escribiendo sobre la <b>función estándar del PLSQL TRUNC</b>.</p>
<div class="separator" style="clear: both;"><p><a href="/2012/04/operaciones-aritmeticas-fechas-trunc.html#more" style="display: block; padding: 1em 0; text-align: center; "><img alt="Funciones fecha en PLSQL" title="Operaciones aritméticas con fechas y la función TRUNC del PL/SQL" border="0" width="400" data-original-height="386" data-original-width="683" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTwKAr2XywXpwl6Nn4Woav21OjhpVVZX9yK9j47UrI0gex8OlTsdan4yqn3HHiopNSj8kNZWBUdO8M2UcePEhlMuhVw0KcL38evQOEGTuPAhevnjKgTRVgVwxOJx02xfaRcUJca1uAM17ZxG99EMWZnS-CDbdD1E4nwbrjc6H4r66Z3cxOhA/s400/funciones-fecha.png"></a></p></div>
<p>Las bases de datos Oracle permiten realizar una gran variedad de operaciones aritméticas con los tipos de datos DATE y TIMESTAMP, pudiendo realizar dichas operaciones de diversas maneras.</p>
<a href="http://www.plsql.biz/2012/04/operaciones-aritmeticas-fechas-trunc.html#more">Haz clic aquí para leer todo el artículo</a>JLPMhttp://www.blogger.com/profile/00891045835734721638noreply@blogger.com6