-- Para evitar problemas de rendimiento sobre las tablas que utiliza OEM y hacer que nuestro entorno OEM quede "limpio" de alertas (por ejemplo si hemos estado haciendo pruebas de funcionalidad, recuperación, etc), se pueden borrar alertas obsoletas haciendo uso del procedimiento DELETE_CURRENT_SEVERITY del paquete EM_SEVERITY:
exec SYSMAN.EM_SEVERITY.DELETE_CURRENT_SEVERITY (target_guid , metric_guid , key_value);
Donde los valores para target_guid, metric_guid, key_value los podemos obtener de SYSMAN.MGMT_CURRENT_SEVERITY
martes, 13 de septiembre de 2011
miércoles, 7 de septiembre de 2011
Comprobación variables Bind Oracle
-- La vista DBA_HIST_SQLBIND nos muestra los valores actuales de variables bind, almacenadas según el tiempo de retención AWR:
select count(1) from dba_hist_sqlbind where sql_id='acm0qvuazu...'
select count(1) from dba_hist_sqlbind where sql_id='acm0qvuazu...'
domingo, 14 de agosto de 2011
Instalación - Oracle Restart OHASD
-- Notas Oracle Restart OHASD
Hay que revisar scripts de arranque ohasd:
/etc/init.d/init.ohasd run
Este script en particular busca el fichero : "/etc/oracle/scls_scr/curso/oracle/ohasdrun" el valor contenido en él para intentar el "restart" o símplemente no hacer nada "stop", en cuyo caso se queda el init.ohasd en un "sleep 10" continuo (while (true)).
Una vez arranca ohasd, revisar recursos gestionados, si no arrancan todos, lanzar:
$ORA_CRS_HOME/bin/crsctl start resource -all
Hay que revisar scripts de arranque ohasd:
/etc/init.d/init.ohasd run
Este script en particular busca el fichero : "/etc/oracle/scls_scr/curso/oracle/ohasdrun" el valor contenido en él para intentar el "restart" o símplemente no hacer nada "stop", en cuyo caso se queda el init.ohasd en un "sleep 10" continuo (while (true)).
Una vez arranca ohasd, revisar recursos gestionados, si no arrancan todos, lanzar:
$ORA_CRS_HOME/bin/crsctl start resource -all
Instalación - Oracle GRID Infraestructure 11gR2
-- Notas sobre instalación de Oracle GRID Infraestructure 11gR2
Ips - SCAN, para instalación sin hacer uso de los beneficios de SCAN (Single Client Access Name), antes de lanzar la instalación de Oracle GRID, se debe asociar una IP de SCAN en los ficheros /etc/hosts de cada nodo (la misma ip en cada nodo), pero esa IP no debe estar asignada, en otro caso, fallará el instalador con un mensaje indicando que "ya se está utilizando la ip de scan por algún servidor ".
Posterior a la instalación de Oracle GRID Infraestructure, para que funcionen otros instaladores/configuradores, como la configuración de OEM Database Control RAC, se requiere que la ip de SCAN resuelva a alguna IP, (por ejemplo, a alguna de las VIPs de nuestra configuración), es decir, procederemos a cambiar la ip de scan por alguna VIP de nuestra configuración y lanzaremos el instalador/configurador que corresponda.
Ips - SCAN, para instalación sin hacer uso de los beneficios de SCAN (Single Client Access Name), antes de lanzar la instalación de Oracle GRID, se debe asociar una IP de SCAN en los ficheros /etc/hosts de cada nodo (la misma ip en cada nodo), pero esa IP no debe estar asignada, en otro caso, fallará el instalador con un mensaje indicando que "ya se está utilizando la ip de scan por algún servidor ".
Posterior a la instalación de Oracle GRID Infraestructure, para que funcionen otros instaladores/configuradores, como la configuración de OEM Database Control RAC, se requiere que la ip de SCAN resuelva a alguna IP, (por ejemplo, a alguna de las VIPs de nuestra configuración), es decir, procederemos a cambiar la ip de scan por alguna VIP de nuestra configuración y lanzaremos el instalador/configurador que corresponda.
miércoles, 16 de febrero de 2011
Script - Calculo_MD5_Consulta.sql
-- Función para el cálculo MD5 de una consulta pasada como parámetro:
create or replace function hash_sql(l_query varchar2) return varchar2
is
pragma autonomous_transaction;
l_theCursor integer default dbms_sql.open_cursor;
l_columnValue varchar2(32000);
l_status integer;
l_colCnt number := 0;
l_separator varchar2(1);
l_descTbl dbms_sql.desc_tab;
l_i number:=0;
l_data CLOB:='';
l_checksum CLOB:='';
begin
execute immediate 'alter session set nls_date_format=''dd/mm/yyyy hh24:mi:ss'' ';
dbms_sql.parse( l_theCursor, l_query, dbms_sql.native );
dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );
for i in 1 .. l_colCnt loop
dbms_sql.define_column( l_theCursor, i, l_columnValue, 32000 );
end loop;
l_status := dbms_sql.execute(l_theCursor);
while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor, i, l_columnValue );
l_i:=i;
l_data:=l_data||trim(TO_CHAR(l_columnValue));
end loop;
end loop;
dbms_sql.close_cursor(l_theCursor);
rollback;
return dbms_crypto.hash( src => l_data, typ=>dbms_crypto.hash_md5 );
exception
when others then
return 'ERROR';
end;
/
-- Llamada:
select hash_sql ('SELECT * FROM tabla where columna='||CHR(39)||'VALOR'||CHR(39)||' order by 1 ') md5 from dual
/
-- Funcionamiento/Restricciones:
A) Se basa en el uso del paquete DBMS_CRYPTO de Oracle (ver > 10g)
B) El cálculo MD5 ser realiza sobre la concatenación de todas las columnas devueltas por la consulta y concatenación fila a fila de los resultados, por ejemplo:
column1 column2
------- -------
a b
a2 b2
La cadena sobre la que se aplica el MD5 sería:
"aba2b2"
C) Cada valor de cada fila / columna se convierte en texto y se eliminan espacio finales e iniciales (TRIM(TO_CHAR(...))
D) El formato para la conversión de datos tipo fecha es: "dd/mm/yyyy hh24:mi:ss"
E) Es importante que las consultas tengan una ordenación (Ej.- "ORDER BY NLSSORT(VAL_ELE_COD, 'NLS_SORT = BINARY')"
create or replace function hash_sql(l_query varchar2) return varchar2
is
pragma autonomous_transaction;
l_theCursor integer default dbms_sql.open_cursor;
l_columnValue varchar2(32000);
l_status integer;
l_colCnt number := 0;
l_separator varchar2(1);
l_descTbl dbms_sql.desc_tab;
l_i number:=0;
l_data CLOB:='';
l_checksum CLOB:='';
begin
execute immediate 'alter session set nls_date_format=''dd/mm/yyyy hh24:mi:ss'' ';
dbms_sql.parse( l_theCursor, l_query, dbms_sql.native );
dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );
for i in 1 .. l_colCnt loop
dbms_sql.define_column( l_theCursor, i, l_columnValue, 32000 );
end loop;
l_status := dbms_sql.execute(l_theCursor);
while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor, i, l_columnValue );
l_i:=i;
l_data:=l_data||trim(TO_CHAR(l_columnValue));
end loop;
end loop;
dbms_sql.close_cursor(l_theCursor);
rollback;
return dbms_crypto.hash( src => l_data, typ=>dbms_crypto.hash_md5 );
exception
when others then
return 'ERROR';
end;
/
-- Llamada:
select hash_sql ('SELECT * FROM tabla where columna='||CHR(39)||'VALOR'||CHR(39)||' order by 1 ') md5 from dual
/
-- Funcionamiento/Restricciones:
A) Se basa en el uso del paquete DBMS_CRYPTO de Oracle (ver > 10g)
B) El cálculo MD5 ser realiza sobre la concatenación de todas las columnas devueltas por la consulta y concatenación fila a fila de los resultados, por ejemplo:
column1 column2
------- -------
a b
a2 b2
La cadena sobre la que se aplica el MD5 sería:
"aba2b2"
C) Cada valor de cada fila / columna se convierte en texto y se eliminan espacio finales e iniciales (TRIM(TO_CHAR(...))
D) El formato para la conversión de datos tipo fecha es: "dd/mm/yyyy hh24:mi:ss"
E) Es importante que las consultas tengan una ordenación (Ej.- "ORDER BY NLSSORT(VAL_ELE_COD, 'NLS_SORT = BINARY')"
lunes, 7 de febrero de 2011
Script - DML Paralelo (pipelined funcition + bulk DML)
Extraído de : http://www.asktherealtom.ch/?p=94
-- Tabla de ejemplo
CREATE TABLE TRANSACTION(TRANSACTION_ID NUMBER, PRUEBA VARCHAR2(100)) TABLESPACE ...;
CREATE INDEX I_PK_TRANSID ON TRANSACTION(TRANSACTION_ID) TABLESPACE ...;
-- Rellenamos la tabla
INSERT INTO TRANSACTION SELECT ... FROM ... WHERE ROWNUM <=100000;
CREATE OR REPLACE PACKAGE PKG_PARALLEL AS
TYPE t_parallel_test_row IS RECORD ( TRANSACTION_ID NUMBER(16));
TYPE t_parallel_test_ref_cursor IS REF CURSOR RETURN t_parallel_test_row;
TYPE t_dml_counter IS TABLE OF NUMBER;
TYPE t_TRANSACTIONID_tab IS TABLE OF transaction.TRANSACTION_ID%TYPE INDEX BY BINARY_INTEGER;
v_row1 t_TRANSACTIONID_tab;
v_array_size PLS_INTEGER := 500000;
function ptf_dml(p_cursor IN t_parallel_test_ref_cursor)
return t_dml_counter
pipelined
parallel_enable (PARTITION p_cursor BY ANY );
--parallel_enable (PARTITION p_cursor BY RANGE (TRANSACTIONID));
END PKG_PARALLEL;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY PKG_PARALLEL AS
--create or replace function ptf_dml(p_cursor IN SYS_REFCURSOR)
function ptf_dml(p_cursor IN t_parallel_test_ref_cursor)
return t_dml_counter
pipelined
-- parallel_enable (PARTITION p_cursor BY RANGE (TRANSACTIONID))
parallel_enable (PARTITION p_cursor BY ANY )
is
PRAGMA AUTONOMOUS_TRANSACTION;
r_rowid transaction.TRANSACTION_ID%type;
BEGIN
LOOP
FETCH p_cursor BULK COLLECT INTO v_row1 LIMIT v_array_size;
FORALL i IN 1..v_row1.COUNT
UPDATE transaction t
SET t.PRUEBA = T.PRUEBA||'A'
WHERE TRANSACTION_ID=v_row1(i);
-- rollback;
commit;
pipe row (1);
EXIT WHEN p_cursor%NOTFOUND;
END LOOP;
end ptf_dml;
end PKG_PARALLEL;
/
SHOW ERRORS
alter session force parallel query parallel 4;
select count(*) from table(PKG_PARALLEL.ptf_dml( cursor(select /*+ PARALLEL(t,4) PARALLEL_INDEX(t, I_PK_TRANSID, 4) */ TRANSACTION_ID from TRANSACTION t ) ) );
-- Tabla de ejemplo
CREATE TABLE TRANSACTION(TRANSACTION_ID NUMBER, PRUEBA VARCHAR2(100)) TABLESPACE ...;
CREATE INDEX I_PK_TRANSID ON TRANSACTION(TRANSACTION_ID) TABLESPACE ...;
-- Rellenamos la tabla
INSERT INTO TRANSACTION SELECT ... FROM ... WHERE ROWNUM <=100000;
CREATE OR REPLACE PACKAGE PKG_PARALLEL AS
TYPE t_parallel_test_row IS RECORD ( TRANSACTION_ID NUMBER(16));
TYPE t_parallel_test_ref_cursor IS REF CURSOR RETURN t_parallel_test_row;
TYPE t_dml_counter IS TABLE OF NUMBER;
TYPE t_TRANSACTIONID_tab IS TABLE OF transaction.TRANSACTION_ID%TYPE INDEX BY BINARY_INTEGER;
v_row1 t_TRANSACTIONID_tab;
v_array_size PLS_INTEGER := 500000;
function ptf_dml(p_cursor IN t_parallel_test_ref_cursor)
return t_dml_counter
pipelined
parallel_enable (PARTITION p_cursor BY ANY );
--parallel_enable (PARTITION p_cursor BY RANGE (TRANSACTIONID));
END PKG_PARALLEL;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY PKG_PARALLEL AS
--create or replace function ptf_dml(p_cursor IN SYS_REFCURSOR)
function ptf_dml(p_cursor IN t_parallel_test_ref_cursor)
return t_dml_counter
pipelined
-- parallel_enable (PARTITION p_cursor BY RANGE (TRANSACTIONID))
parallel_enable (PARTITION p_cursor BY ANY )
is
PRAGMA AUTONOMOUS_TRANSACTION;
r_rowid transaction.TRANSACTION_ID%type;
BEGIN
LOOP
FETCH p_cursor BULK COLLECT INTO v_row1 LIMIT v_array_size;
FORALL i IN 1..v_row1.COUNT
UPDATE transaction t
SET t.PRUEBA = T.PRUEBA||'A'
WHERE TRANSACTION_ID=v_row1(i);
-- rollback;
commit;
pipe row (1);
EXIT WHEN p_cursor%NOTFOUND;
END LOOP;
end ptf_dml;
end PKG_PARALLEL;
/
SHOW ERRORS
alter session force parallel query parallel 4;
select count(*) from table(PKG_PARALLEL.ptf_dml( cursor(select /*+ PARALLEL(t,4) PARALLEL_INDEX(t, I_PK_TRANSID, 4) */ TRANSACTION_ID from TRANSACTION t ) ) );
lunes, 17 de enero de 2011
Script - Trasponer_filas_a_columna.sql
Función plsql para transponer los resultados de una consultas (varias filas) al valor de una fila en una columna indicando un carácter separador:
create or replace FUNCTION transponer(vSQL VARCHAR2, vSEP varchar2)
RETURN VARCHAR2 IS
-- vSQL sql dinámico a lanzar cuyo resultado queremos separados por la cadena vSEP
-- vSQL debe devolver una sola columna tipo varchar2 y el total de bytes retornados no debe superar los 32000 y 4000 por registro.
TYPE cv_type IS REF CURSOR;
CV CV_TYPE;
V_RES_VALOR VARCHAR2(32000);
VALOR VARCHAR2(4000);
BEGIN
V_RES_VALOR:='XX';
OPEN CV FOR VSQL;
LOOP
FETCH CV INTO VALOR;
EXIT WHEN CV%NOTFOUND;
IF V_RES_VALOR='XX' THEN
V_RES_VALOR:=VALOR;
ELSE
V_RES_VALOR:=V_RES_VALOR||VSEP||VALOR;
END IF;
END LOOP;
CLOSE CV;
RETURN V_RES_VALOR;
EXCEPTION
WHEN OTHERS THEN
IF SQL%NOTFOUND THEN VALOR:='NO ENCONTRADO';
ELSE
VALOR:='ERROR EN LA CONSULTA, CONSULTE CON EL ADMINISTRADOR';
END IF;
IF nvl(length(V_RES_VALOR),0)=0 THEN
V_RES_VALOR:=VALOR;
ELSE
V_RES_VALOR:=V_RES_VALOR||' '||VSEP||' '||VALOR;
END IF;
RETURN 'ERROR --> '||V_RES_VALOR;
END TRANSPONER;
/
Ejemplo de uso:
select transponer('SELECT table_name FROM user_tables WHERE ROWNUM <=100', '|') FROM DUAL;
TABLA1|TABLA2|TABLA_EJEMPLO|PRUEBA
create or replace FUNCTION transponer(vSQL VARCHAR2, vSEP varchar2)
RETURN VARCHAR2 IS
-- vSQL sql dinámico a lanzar cuyo resultado queremos separados por la cadena vSEP
-- vSQL debe devolver una sola columna tipo varchar2 y el total de bytes retornados no debe superar los 32000 y 4000 por registro.
TYPE cv_type IS REF CURSOR;
CV CV_TYPE;
V_RES_VALOR VARCHAR2(32000);
VALOR VARCHAR2(4000);
BEGIN
V_RES_VALOR:='XX';
OPEN CV FOR VSQL;
LOOP
FETCH CV INTO VALOR;
EXIT WHEN CV%NOTFOUND;
IF V_RES_VALOR='XX' THEN
V_RES_VALOR:=VALOR;
ELSE
V_RES_VALOR:=V_RES_VALOR||VSEP||VALOR;
END IF;
END LOOP;
CLOSE CV;
RETURN V_RES_VALOR;
EXCEPTION
WHEN OTHERS THEN
IF SQL%NOTFOUND THEN VALOR:='NO ENCONTRADO';
ELSE
VALOR:='ERROR EN LA CONSULTA, CONSULTE CON EL ADMINISTRADOR';
END IF;
IF nvl(length(V_RES_VALOR),0)=0 THEN
V_RES_VALOR:=VALOR;
ELSE
V_RES_VALOR:=V_RES_VALOR||' '||VSEP||' '||VALOR;
END IF;
RETURN 'ERROR --> '||V_RES_VALOR;
END TRANSPONER;
/
Ejemplo de uso:
select transponer('SELECT table_name FROM user_tables WHERE ROWNUM <=100', '|') FROM DUAL;
TABLA1|TABLA2|TABLA_EJEMPLO|PRUEBA
Suscribirse a:
Entradas (Atom)