Mejoras en expresiones regulares de las funciones integradas de SQL
El REGEXP_INSTR y REGEXP_SUBSTR funciones incluyen un nuevoSUBEXPR
parámetro que limita la coincidencia de patrón para una subexpresión específico en el patrón de búsqueda. SQL> SELECT REGEXP_INSTR ('1234567890 ',' (123) (4 (56) (78)), 1, 1, 0, 'i', 1) de la doble;
REGEXP_INSTR ('1234567890 ',' (123) (4 (56) (78)) ', 1,1,0,' I ', 1)
-------------------------------------------------- -------
1
Una fila seleccionada.
SQL> SELECT REGEXP_INSTR ('1234567890 ',' (123) (4 (56) (78)), 1, 1, 0, 'i', 3) de la doble;
REGEXP_INSTR ('1234567890 ',' (123) (4 (56) (78)) ', 1,1,0,' I ', 3)
-------------------------------------------------- -------
5
Una fila seleccionada.
SQL> SELECT REGEXP_SUBSTR ('1234567890 ',' (123) (4 (56) (78)), 1, 1, 'i', 0) de la doble;
REGEXP_S
--------
12345678
Una fila seleccionada.
SQL> SELECT REGEXP_SUBSTR ('1234567890 ',' (123) (4 (56) (78)), 1, 1, 'i', 1) de la doble;
REG
---
123
Una fila seleccionada.
SQL> SELECT REGEXP_SUBSTR ('1234567890 ',' (123) (4 (56) (78)), 1, 1, 'i', 3) de la doble;
RE
-
56
Una fila seleccionada.
SQL>
El nuevo REGEXP_COUNT función devuelve el número de veces que el patrón de búsqueda aparece en cadena de origen. SQL> SELECT REGEXP_COUNT ('123 123 123 123 ', '123', 1, 'i') de la doble;
REGEXP_COUNT ('123123123123 ', '123', una 'I')
----------------------------------------
4
Una fila seleccionada.
SQL> SELECT REGEXP_COUNT ('123 123 123 123 ', '123', 9 'i') de la doble;
REGEXP_COUNT ('123123123123 ', '123', 9 'I')
----------------------------------------
2
Una fila seleccionada.
SQL>
SIMPLE_INTEGER tipo de datos
ElSIMPLE_INTEGER
tipo de datos es un subtipo de la PLS_INTEGER
tipo de datos y puede aumentar drásticamente la velocidad de la aritmética de enteros en el código nativo compilado, pero sólo muestra las mejoras de rendimiento marginal en código interpretado. El procedimiento siguiente se compara el rendimiento de la SIMPLE_INTEGER
y PLS_INTEGER
tipos de datos. Cuando se ejecuta en el modo por defecto interpreta la mejora del rendimiento de laCREAR O CAMBIAR simple_integer_test_proc PROCEDIMIENTO AS l_start número; NÚMERO l_loops: = 10000000; l_pls_integer PLS_INTEGER: = 0; l_pls_integer_incr PLS_INTEGER: = 1; l_simple_integer SIMPLE_INTEGER: = 0; l_simple_integer_incr SIMPLE_INTEGER: = 1; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP l_pls_integer: = + l_pls_integer l_pls_integer_incr; END LOOP; DBMS_OUTPUT.PUT_LINE ("PLS_INTEGER: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP l_simple_integer: = + l_simple_integer l_simple_integer_incr; END LOOP; DBMS_OUTPUT.PUT_LINE ("SIMPLE_INTEGER: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END simple_integer_test_proc; /
SIMPLE_INTEGER
tipo de datos no es espectacular. Nos nativa compilar el procedimiento mediante la alteración de laSQL> JUEGO DE serveroutput SQL> EXEC simple_integer_test_proc; PLS_INTEGER: 47 hsecs SIMPLE_INTEGER: 44 hsecs PL / SQL terminado con éxito. SQL>
PLSQL_CODE_TYPE
valor de la sesión y volver a compilar el procedimiento. Compilar de forma nativa el procedimiento produce importantes mejoras de velocidad para ambos tipos de datos, pero más aún para elALTER SET SESSION PLSQL_CODE_TYPE = Nativo; ALTER PROCEDIMIENTO COMPILAR simple_integer_test_proc;
SIMPLE_INTEGER
tipo de datos. Las mejoras de velocidad son el resultado de dos diferencias fundamentales entre los dos tipos de datos. En primer lugar,SQL> JUEGO DE serveroutput SQL> EXEC simple_integer_test_proc; PLS_INTEGER: 10 hsecs SIMPLE_INTEGER: 2 hsecs PL / SQL terminado con éxito. SQL>
SIMPLE_INTEGER
y PLS_INTEGER
tienen el mismo rango (-2.147.483.648 a 2.147.483.647), pero SIMPLE_INTEGER
arropa cuando se excede de sus límites, en lugar de tirar un error como PLS_INTEGER
. En segundo lugar,JUEGO DE serveroutput DECLARE l_simple_integer SIMPLE_INTEGER: = 2147483645; INICIO For i in 1 .. 4 LOOP l_simple_integer: = l_simple_integer + 1; DBMS_OUTPUT.PUT_LINE (to_char (l_simple_integer, 'S9999999999')); END LOOP; For i in 1 .. 4 LOOP l_simple_integer: = l_simple_integer - 1; DBMS_OUTPUT.PUT_LINE (to_char (l_simple_integer, 'S9999999999')); END LOOP; END; / +2147483646 +2147483647 -2147483648 -2147483647 -2147483648 +2147483647 +2147483646 +2147483645 PL / SQL terminado con éxito. SQL>
SIMPLE_INTEGER
nunca puede tener un valor NULL, ya sea cuando se declara, o por la cesión. La eliminación de desbordamiento y el resultado NULL comprobación en una reducción significativa en los gastos generales en comparación conDECLARE l_simple_integer SIMPLE_INTEGER; INICIO NULL; END; / * ERROR en línea 2: ORA-06550: línea 2, columna 20: PLS-00218: una variable declarada como NOT NULL deben tener una asignación de inicialización SQL> DECLARE l_simple_integer SIMPLE_INTEGER: = 0; INICIO l_simple_integer: = NULL; END; / * ERROR en la línea 4: ORA-06550: línea 4, columna 23: PLS-00382: la expresión es de tipo incorrecto ORA-06550: línea 4, columna 3: PL / SQL: Instrucción omite SQL>
PLS_INTEGER
.CONTINUAR Declaración
ElCONTINUE
saltos declaración de la iteración de bucle de corriente y empieza el siguiente. Se puede utilizar por sí mismo, o como parte de un CONTINUE WHEN
la declaración, como se muestra a continuación. Este tipo de proceso siempre ha sido posible utilizandoJUEGO DE serveroutput DECLARE NÚMERO l_number: = 0; INICIO For i in 1 .. 100 LOOP Continuar cuando MOD (i, 2) = 0; - Hacer algo aquí! l_number: = l_number + 1; END LOOP; DBMS_OUTPUT.PUT_LINE ("continuar cuando: '| | l_number); l_number: = 0; For i in 1 .. 100 LOOP SI MOD (i, 2) = 0 THEN CONTINUE; END IF; - Hacer algo aquí! l_number: = l_number + 1; END LOOP; DBMS_OUTPUT.PUT_LINE ("SI .. CONTINUAR: '| | l_number); END; / Continuar cuando: 50 SI .. CONTINUAR: 50 PL / SQL terminado con éxito. SQL>
IF
declaraciones ya sea por su propia cuenta o con las excepciones o GOTO
declaraciones, pero la CONTINUE
declaración es más claro y trae PL / SQL en línea con langauges otros. Los siguientes ejemplos muestran el tipo de código necesario para realizar la misma tarea antes de la CONTINUE
sentencia se añadió a PL / SQL. JUEGO DE serveroutput DECLARE ex_continue excepción; NÚMERO l_number: = 0; INICIO For i in 1 .. 100 LOOP INICIO SI MOD (i, 2)! = 0 THEN RAISE ex_continue; END IF; - Hacer algo aquí! l_number: = l_number + 1; EXCEPCIÓN CUANDO ENTONCES ex_continue NULL; END; END LOOP; DBMS_OUTPUT.PUT_LINE ("Excepción: '| | l_number); l_number: = 0; For i in 1 .. 100 LOOP SI MOD (i, 2)! = 0 THEN - Hacer algo aquí! l_number: = l_number + 1; END IF; END LOOP; DBMS_OUTPUT.PUT_LINE ("SI: '| | l_number); l_number: = 0; For i in 1 .. 100 LOOP SI MOD (i, 2) = 0 THEN GOTO label_continue; END IF; - Hacer algo aquí! l_number: = l_number + 1; <<Label_continue>> NULL; END LOOP; DBMS_OUTPUT.PUT_LINE ("GOTO: '| | l_number); END; / EXCEPCIÓN: 50 SI: 50 GOTO: 50 PL / SQL terminado con éxito. SQL>
Secuencias en PL / SQL Expresiones
ElNEXTVAL
y CURRVAL
pseudocolumnas secuencia de ahora se puede acceder en expresiones PL / SQL, así como consultas. Esto hace que el código de aspecto sencillo, y la documentación sugiere que mejora el rendimiento. El siguiente ejemplo se compara la velocidad de los métodos nuevos y originales de acceder a estos valores de secuencia. Se puede ver que en cuanto al tiempo transcurrido se refiere, hay poca diferencia entre los dos métodos.CREAR inicio de la secuencia test1_seq CON 1.000.000; JUEGO DE serveroutput DECLARE l_start número; NÚMERO l_loops: = 100000; l_value número; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP SELECCIONAR test1_seq.NEXTVAL EN l_value De la doble; END LOOP; DBMS_OUTPUT.PUT_LINE ("NEXTVAL SELECT = '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP l_value: = test1_seq.NEXTVAL; END LOOP; DBMS_OUTPUT.PUT_LINE ("expresión NEXTVAL = '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP SELECCIONAR test1_seq.CURRVAL EN l_value De la doble; END LOOP; DBMS_OUTPUT.PUT_LINE ("CURRVAL SELECT = '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP l_value: = test1_seq.CURRVAL; END LOOP; DBMS_OUTPUT.PUT_LINE ("Expresión CURRVAL = '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END; / NEXTVAL SELECT = 2196 hsecs Expresión NEXTVAL = 2203 hsecs CURRVAL SELECT = 1007 hsecs Expresión CURRVAL = 1003 hsecs PL / SQL terminado con éxito. SQL>
Mejoras en el SQL dinámico
Nativas SQL dinámico y el paquete DBMS_SQL ahora soportan sentencias de SQL dinámico de más de 32 KB. El EXECUTE IMMEDIATE declaración, ABIERTA PARA declaración y DBMS_SQL.PARSEprocedimiento aceptar todas las sentencias SQL en la forma de CLOB.El DBMS_SQL.TO_REFCURSOR función convierte un cursor ID DBMS_SQL en un REF CURSOR.
El DBMS_SQL.TO_CURSOR_NUMBER función convierte un REF CURSOR en un cursor DBMS_SQL ID.JUEGO DE serveroutput DECLARE l_cursor número; l_return número; l_ref_cursor SYS_REFCURSOR; TIPO ES t_emp_tab TABLA DE ROWTYPE% emp; l_emp_tab t_emp_tab; INICIO l_cursor: DBMS_SQL.open_cursor =; DBMS_SQL.parse (l_cursor, 'SELECT * FROM emp ", DBMS_SQL.NATIVE); l_return: DBMS_SQL.EXECUTE = (l_cursor); - Connvert de DBMS_SQL a un REF CURSOR. l_ref_cursor: DBMS_SQL.to_refcursor = (l_cursor); FETCH GRANEL l_ref_cursor reunir en l_emp_tab; DBMS_OUTPUT.PUT_LINE ("número de empleados: '| | l_emp_tab.count); L_ref_cursor cerca; END; / Número de empleados: 14 PL / SQL terminado con éxito. SQL>
Además, el paquete DBMS_SQL ahora soporta todos los tipos de datos con el apoyo de SQL dinámico nativo.JUEGO DE serveroutput DECLARE l_ref_cursor SYS_REFCURSOR; l_cursor número; NÚMERO l_count: = 0; INICIO L_ref_cursor ABIERTO "SELECT * FROM emp; l_cursor: DBMS_SQL.to_cursor_number = (l_ref_cursor); MIENTRAS DBMS_SQL.fetch_rows (l_cursor)> 0 LOOP l_count: = l_count + 1; END LOOP; DBMS_OUTPUT.PUT_LINE ("número de empleados: '| | l_count); DBMS_SQL.close_cursor (l_cursor); END; / Número de empleados: 14 PL / SQL terminado con éxito. SQL>
Generalizada Invocación
Generalizada invocación permite un subtipo para invocar un método de un tipo primario (supertipo) con la siguiente sintaxis.El siguiente ejemplo muestra esto en acción.(AUTO COMO supertype_name). Method_name
En primer lugar, crear un tipo con algunos atributos y una función miembro.
A continuación, crear un subtipo de este objeto, lo que añade un nuevo atributo y método, así como anular laCREAR O CAMBIAR TIPO my_type como objeto ( número de identificación, Descripción VARCHAR2 (50), Show_attributes funciones miembro RETORNO VARCHAR2) NO FINAL; / CREAR O CAMBIAR my_type tipo de cuerpo como Show_attributes funciones miembro RETORNO VARCHAR2 IS INICIO RETURN 'id =' | | Identificación | | 'descripción =' | | descripción; END; END; /
show_attributes
función miembro. Observe el método del tipo de padres que se accede utilizando la sintaxis de invocación generalizada. El código siguiente crea un subtipo, y llama a sus funciones miembro.CREAR O CAMBIAR my_subtype tipo bajo my_type ( short_desc VARCHAR2 (10), ABSOLUTA show_attributes función miembro RETORNO VARCHAR2, Show_parent_attributes funciones miembro RETORNO VARCHAR2); / CREAR O CAMBIAR my_subtype tipo de cuerpo como ABSOLUTA show_attributes miembro de devolución de funciones VARCHAR2 IS INICIO RETURN (yo como my_type) show_attributes | | 'short_desc =' | | short_desc.; END; Show_parent_attributes funciones miembro RETORNO VARCHAR2 IS INICIO RETURN (yo como my_type) show_attributes.; END; END; /
Un tipo se puede invocar a las funciones de miembro de cualquier tipo primario de esta manera, independientemente de la profundidad de la herencia.JUEGO DE serveroutput DECLARE my_subtype l_subtype: = my_subtype (1, 'Descripción extensa para el 1', 'S descripción 1'); INICIO DBMS_OUTPUT.PUT_LINE ("show_attributes = '| | l_subtype.show_attributes); DBMS_OUTPUT.PUT_LINE ("show_parent_attributes = '| | l_subtype.show_parent_attributes); END; / show_attributes = id = 1 Descripción descripción = largo por 1 short_desc Desc = S 1 show_parent_attributes = id = 1 = Descripción detallada descripción de un PL / SQL terminado con éxito. SQL>
La notación con nombre y mixtos en las invocaciones del Subprograma PL / SQL
Antes de 11g, PL / SQL invoca desde SQL tenía que tener sus parámetros pasados usando la notación posicional, lo que hace difícil determinar el significado de los parámetros. Oracle 11g permite la notación posicional, el nombre y la mezcla que se utiliza cuando se llama PL / SQL de SQL, como se muestra a continuación.- Construir una función de prueba con múltiples parámetros. CREAR O CAMBIAR test_func FUNCIÓN (p_value_1 EN INCUMPLIMIENTO número 0, p_value_2 EN número predeterminado 0) Devuelve el número AS INICIO RETORNO p_value_1 + p_value_2; END test_func; / Función creada. SQL> - la notación posicional. SQL> SELECT test_func (10, 20) de la doble; TEST_FUNC (10,20) ---------------- 30 Una fila seleccionada. SQL> - notación mixta. SQL> SELECT test_func (10, p_value_2 => 20) de la doble; TEST_FUNC (10, P_VALUE_2 => 20) --------------------------- 30 Una fila seleccionada. SQL> - nombre de notación. SQL> SELECT test_func (p_value_1 => 10, p_value_2 => 20) de la doble; TEST_FUNC (P_VALUE_1 => 10, P_VALUE_2 => 20) -------------------------------------- 30 Una fila seleccionada. SQL>
Subprograma automática Inlining
Cada llamada a un procedimiento o función produce una leve, pero medible, sobrecarga en el rendimiento, lo que es especialmente notable cuando el subprograma se llama dentro de un bucle. Evitar procedimientos y funciones no es una opción, ya que va contra el concepto de programación modular, por lo que los programas de voluminosos y difíciles de manejar. Inline subprograma automática puede reducir los gastos generales asociados con los subprogramas de llamada, dejando a su código fuente original en su estado modular normal. Esto se hace mediante la sustitución de las llamadas de subprograma con una copia del código en el subprograma en tiempo de compilación.El proceso de inclusión entre líneas subprograma es controlada por el
PLSQL_OPTIMIZE_LEVEL
parámetro y el INLINE
pragma. Cuando PLSQL_OPTIMIZE_LEVEL=2
(por defecto), el INLINE
pragma determina si la siguiente declaración o una declaración debe ser entre líneas o no. Cuando PLSQL_OPTIMIZE_LEVEL=3
, el optimizador de código en línea de forma automática. En este caso el INLINE
pragma se puede desactivar procesos en línea para una declaración, o aumentar la probabilidad de que el optimizador elegirá a una declaración en línea. La relación es más fácil de entender cuando vea el siguiente ejemplo.Estas pruebas utilizan un bloque anónimo con una función definida en el bloque de declaraciones. La función se llama repetidamente en un bucle. Los ajustes para
PLSQL_OPTIMIZE_LEVEL
y el INLINE
pragma son alterados para cambiar subprograma procesos en línea y fuera. En primer lugar, nos aseguramos de PLSQL_OPTIMIZE_LEVEL=2
y ejecutar el código sin INLINE
conjunto pragma. Con estos ajustes, no podemos esperar para ver subprograma inline llevando a cabo. Esto se traduce en un lapso de tiempo de 509 hsecs.ALTER SET SESSION PLSQL_OPTIMIZE_LEVEL = 2; JUEGO DE serveroutput DECLARE NÚMERO l_loops: = 10000000; l_start número; l_return número; Add_numbers FUNCIÓN (p_1 en número, p_2 en número) Devuelve el número AS INICIO RETORNO p_1 + p_2; Add_numbers END; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP - PRAGMA en línea (add_numbers, 'YES'); l_return: = add_numbers (1, i); END LOOP; DBMS_OUTPUT.PUT_LINE ("Tiempo transcurrido: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END; / Tiempo transcurrido: 509 hsecs PL / SQL terminado con éxito. SQL>
A continuación, mantenga la configuración de la optimización de lo mismo, pero incluyen la
INLINE
pragma con un ajuste de "SÍ" para las llamadas a la ADD_NUMBERS
función. Ahora se espera subprograma procesos en línea para tomar su lugar. Esto le da un tiempo transcurrido de 245 HSEC, que es aproximadamente la mitad de la prueba anterior, lo que implica que inline subprograma está llevando a cabo.ALTER SET SESSION PLSQL_OPTIMIZE_LEVEL = 2; JUEGO DE serveroutput DECLARE NÚMERO l_loops: = 10000000; l_start número; l_return número; Add_numbers FUNCIÓN (p_1 en número, p_2 en número) Devuelve el número AS INICIO RETORNO p_1 + p_2; Add_numbers END; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP PRAGMA en línea (add_numbers, 'YES'); l_return: = add_numbers (1, i); END LOOP; DBMS_OUTPUT.PUT_LINE ("Tiempo transcurrido: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END; / Tiempo transcurrido: 245 hsecs PL / SQL terminado con éxito. SQL>
A continuación, asegúrese de que
PLSQL_OPTIMIZE_LEVEL=3
y ejecutar el código sin INLINE
conjunto pragma. Ahora se espera que el optimizador elija implícitamente a la línea ADD_NUMBERS
llamada. Esto le da un tiempo transcurrido de 245 HSEC, lo que implica que inline subprograma está aún en marcha.ALTER SET SESSION PLSQL_OPTIMIZE_LEVEL = 3; JUEGO DE serveroutput DECLARE NÚMERO l_loops: = 10000000; l_start número; l_return número; Add_numbers FUNCIÓN (p_1 en número, p_2 en número) Devuelve el número AS INICIO RETORNO p_1 + p_2; Add_numbers END; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP - PRAGMA en línea (add_numbers, 'YES'); l_return: = add_numbers (1, i); END LOOP; DBMS_OUTPUT.PUT_LINE ("Tiempo transcurrido: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END; / Tiempo transcurrido: 245 hsecs PL / SQL terminado con éxito. SQL>
Por último, nos aseguramos de
PLSQL_OPTIMIZE_LEVEL=3
y ejecutar el código con un INLINE
pragma en "NO". Es de esperar que no haya procesos en línea de la ADD_NUMBERS
llame ahora. Esto le da un tiempo transcurrido de 500 hsecs, lo que implica que inline no se llevó a cabo como se esperaba.ALTER SET SESSION PLSQL_OPTIMIZE_LEVEL = 3; JUEGO DE serveroutput DECLARE NÚMERO l_loops: = 10000000; l_start número; l_return número; Add_numbers FUNCIÓN (p_1 en número, p_2 en número) Devuelve el número AS INICIO RETORNO p_1 + p_2; Add_numbers END; INICIO l_start: DBMS_UTILITY.get_time =; For i in 1 .. l_loops LOOP PRAGMA en línea (add_numbers, 'NO'); l_return: = add_numbers (1, i); END LOOP; DBMS_OUTPUT.PUT_LINE ("Tiempo transcurrido: '| | (DBMS_UTILITY.get_time - l_start) | |' hsecs '); END; / Tiempo transcurrido: 500 hsecs PL / SQL terminado con éxito. SQL>
El
INLINE
pragma sólo afecta a los siguientes tipos de declaraciones. - Asignación
- Llamar
- Condicional
CASE
CONTINUE-WHEN
EXECUTE IMMEDIATE
EXIT-WHEN
LOOP
RETURN
El optimizador puede optar por ignorar una
INLINE
pragma configuración del "SI" si cree inline no es deseable, sino un ajuste de "NO" siempre evitar procesos en línea.El compilador inlines subprogramas temprano en el proceso de optimización, que puede prevenir más tarde, las optimizaciones más poderosa que tienen lugar. Como resultado, el rendimiento casi siempre mejora con la inclusión entre líneas, pero en algunos casos puede no ser eficaz.
PL / Ámbito de aplicación
PL / Scope es una herramienta que recoge información acerca de los identificadores definidos por el usuario en tiempo de compilación. La recopilación de datos PL / Ámbito de aplicación es controlada por elPLSCOPE_SETTINGS
parámetro, que tiene un valor predeterminado de " IDENTIFIERS:NONE
". Cambiar este valor a " IDENTIFIERS:ALL
"para permitir la recopilación. La recolección de datos se realiza para todos los objetos compilados después de la bandera es definida, por lo que ahora debe crear un objeto de reunir algunos datos.SQL> ALTER SESIÓN "IDENTIFICADORES: ALL 'PLSCOPE_SETTINGS =; Sesión alterado. SQL>
Los datos se almacenan en el espacio de tablas SYSAUX, por lo que el espacio actual utilizado para PL / Ámbito de datos se pueden visualizar con la siguiente consulta.CREAR O CAMBIAR test_plscope PROCEDIMIENTO (p_in EN número) l_var número; INICIO l_var: = p_in; l_var: = l_var + 1; END; /
Los datos de PL / Ámbito de aplicación está disponible en el _IDENTIFIERS% puntos de vista. La consulta siguiente muestra los datos recopilados durante la elaboración delSELECCIONAR space_usage_kbytes DESDE $ v sysaux_occupants DONDE occupant_name = 'PL / SCOPE; SPACE_USAGE_KBYTES ------------------ 384 Una fila seleccionada. SQL>
test_plscope
procedimiento. Lo más probable es que la mayoría de los usuarios ver los datos de PL / Ámbito de aplicación a través de un IDE PL / SQL, como SQL Developer.COLUMNA FORMATO nombre A30 SELECCIONAR LPAD ('', nivel * 2, '') | | nombre como nombre, tipo, uso, usage_id, línea, columna DE user_identifiers EMPIECE CON usage_context_id = 0 ANTES DE CONECTAR POR usage_id = usage_context_id; NOMBRE TIPO DE USO USAGE_ID LÍNEA DE COL ------------------------------ ------------------ - --------- ---------- ---------- ---------- TEST_PLSCOPE Declaración de procedimiento 1 1 11 TEST_PLSCOPE procedimiento de definición 2 1 11 FORMAL EN LA DECLARACIÓN P_IN 3 1 25 L_VAR de declaración de variables 4 2 3 L_VAR variable de asignación 5 4 3 FORMAL EN REFERENCIA P_IN 6 4 12 L_VAR variable de asignación 7 6 3 L_VAR variable de referencia de 8 6 12 8 filas seleccionadas. SQL>
La documentación indica que algunos identificadores no inscrito, salvo que el
STANDARD
paquete se vuelve a compilar después de la PLSCOPE_SETTINGS
parámetro se establece de la siguiente manera.Esto se traduce en más de 7.000 objetos no válidos, la mayoría de los cuales no se vuelva a compilar, incluso cuando se utiliza el guión urlrp.sql. No recomiendo este método si desea que una instancia de trabajo.PL / SQL compilador nativo genera código nativo directamente
La compilación nativa de código PL / SQL, como es posible desde Oracle 9i. Ver:En estas versiones de la base de datos, el código PL / SQL se convierte en código C, compilar y ejecutar los procedimientos externos. Compilados de forma nativa utilizando PL / SQL es necesario un compilador de C en el servidor y la intervención del DBA. Además, con compilados de forma nativa PL / SQL en un entorno RAC puede ser problemático.En Oracle 11g, PL / SQL compilación como nativo no requiere compilador de C, sin intervención del DBA y es totalmente compatible en un entorno RAC. Al establecer la
PLSQL_CODE_TYPE
a un valor deNATIVE
, más que el valor predeterminado de INTERPRETED
, el código es compilado en código máquina y se almacena en el tablespace SYSTEM. Cuando el código se llama, se carga en la memoria compartida, por lo que es accesible para todas las sesiones de esa instancia. El %_PLSQL_OBJECT_SETTINGS
vistas incluyen la corriente PLSQL_CODE_TYPE
ajuste para cada objeto de PL / SQL.Recuerde, la compilación nativa mejorará la velocidad de código de procedimiento, pero no tiene efecto sobre el rendimiento de SQL. Cuando el código lleva a cabo muchas operaciones matemáticas, como elSIMPLE_INTEGER ejemplo, la compilación nativa puede producir considerables mejoras de rendimiento. Si el código es predominantemente realizar SQL, poca mejoría se notará.
Al igual que con versiones anteriores de base de datos, es posible compilar de forma nativa todo el código PL / SQL en la base de datos, siempre y cuando siga el procedimiento de apoyo .
Nueva PL / SQL Advertencia del compilador
Un nuevo PL / SQL advertencia del compilador ha sido añadido a identificarWHEN OTHERS
manejadores de excepciones que no hacen re-raise errores usando RAISE
o RAISE_APPLICATION_ERROR
.Manipuladores de tal excepción a menudo puede ocultar los fracasos de código que generan difícil de identificar los errores. El siguiente ejemplo muestra la advertencia del compilador espera que cuando elPLSQL_WARNINGS
bandera está activa. Esto es sólo un mensaje de advertencia, por lo que sólo identifica el código posible problema, no la impide.SQL> ALTER SESIÓN plsql_warnings = SET "permite: todos; Sesión alterado. SQL> CREATE OR REPLACE others_test PROCEDIMIENTO AS 2 EMPEZAR 3 RAISE_APPLICATION_ERROR (-20000, 'Fuerza y de excepción'); 4 EXCEPCIÓN 5 CUANDO OTROS ENTONCES 6 NULL; 7 END; 8 / SP2-0804: Procedimiento creado con advertencias de compilación SQL> SHOW ERRORES Los errores de OTHERS_TEST PROCEDIMIENTO: Line / Error COL -------- ------------------------------------------ ----------------------- 5.8 PLW-06009: Procedimiento "OTHERS_TEST" manejador de los demás no terminan en Suba o RAISE_APPLICATION_ERROR SQL>
PLS-00436 de restricción en los estados ParaTodos eliminado
La restricción de PLS-00436 se ha eliminado, lo que significa que ahora puede hacer referencia a los elementos individuales de una colección en elSET
y WHERE
las cláusulas de una instrucción DML en una ParaTodos construir. Para verlo en acción, crear y rellena una tabla de prueba con el siguiente código. El bloque de PL / SQL a continuación rellena una colección con los datos existentes, que modifica los datos de la colección, a continuación, actualiza la tabla con los datos modificados. La consulta final muestra los datos modificados en la tabla.CREATE TABLE forall_test ( número de identificación, Descripción VARCHAR2 (50) ); INSERT INTO forall_test VALUES (1, 'uno'); INSERT INTO forall_test VALUES (2, 'dos'); INSERT INTO forall_test VALUES (3, 'tres'); INSERT INTO forall_test VALUES (4, 'cuatro'); INSERT INTO forall_test VALUES (5, 'cinco'); COMMIT;
Notificación tanto en elDECLARE TIPO ES t_forall_test_tab TABLA DE ROWTYPE forall_test%; l_tab t_forall_test_tab; INICIO - Recuperar los datos existentes en una colección. SELECT * A GRANEL EN RECOGER l_tab DE forall_test; - Modificar los datos de la colección. For i in l_tab.first .. l_tab.last LOOP l_tab (i) Descripción: = 'Descripción para' | | i;. END LOOP; - Actualización de la tabla utilizando la colección. ParaTodos i EN l_tab.first .. l_tab.last ACTUALIZACIÓN forall_test Descripción SET = l_tab (i). Descripción WHERE id = l_tab (i) Identificación.; COMMIT; END; / SELECT * FROM forall_test; ID DESCRIPCIÓN ---------- --------------------------- 1 Descripción de una 2 Descripción de dos 3 Descripción de tres 4 Descripción de 4 5 Descripción de 5 5 filas seleccionadas. SQL>
SET
y WHERE
cláusulas contienen referencias a columnas individuales de la colección. Esto hace que el uso a granel-se une a DML aún más fácil ya que no es necesario para mantener las colecciones múltiples si es necesario hacer referencia a las columnas de la WHERE
cláusula. También puede mejorar el rendimiento de las actualizaciones, como las versiones anteriores requiere la actualización de toda la fila con el ROW
palabra clave, que incluyen cambios potencialmente innecesario de la clave principal y las columnas de clave