quarta-feira, 10 de abril de 2013

Prompt com --------------------


PessoALL,

estive com um problema em um script de atualização de estrutura de tabela no Oracle, e foi devido ao PROMPT contento uma sequência de --------------------------, isso fez com que a linha seguinte ao PROMPT fosse interpretada como um comentário, engraçado que este erro só ocorre em linha de comando (SQLPlus) no PL/SQL Developer não ocorre, não sei o resultado em outras ferramentas. Vejam as evidências abaixo:

quinta-feira, 14 de março de 2013

Bug de 2013


Pra quem pensa que o Bug do Milênio foi o último envolvendo datas, aí vai a sensação do momento: O Bug de 2013.
O Bug ocorre na seguinte situação:
* O programa X grava dados de data na tabela usando o seguinte formato de datas:  YYYYMMDD.* O programa Y lê dessa tabela usando o formato DDMMYYYY. (Sim, é um erro, um bug no programa).
Até o ano de 2012, este erro não aparecia, veja um exemplo:
* O programa X salva a data 23-abr-2011 =  20110423 (YYYYMMDD)
* Quando essa data era lida pelo programa Y, ele lia  20110423 (DDMMYYYY) = 20-nov-0423. Data errada, mas não acusava erro!
 Pois o ano de 2013 chegou e esse erro apareceu. Veja:
* O programa X salva a data23-abr-2013 =  20130423 (YYYYMMDD)
* Quando essa data era lida pelo programa Y, ele lia  20130423 (DDMMYYYY) = 20-???-0423. Como não existe mês 13, dá erro!
O interessante é que esse bug está aparecendo só agora, depois de muitos anos de erro oculto. Finalmente em 2013 ele está fazendo os programas pararem de rodar.

quarta-feira, 13 de março de 2013

Comparação com NULL


Quando um variável ou um campo no Oracle está NULL, ele não pode ser simplesmente comparado a um outro valor, pois o resultado da comparação também será falso.

Veja abaixo:


DECLARE
  C1 VARCHAR2(20) := NULL;
  C2 VARCHAR2(20) := '13240';
BEGIN
  IF C1 <> C2 THEN
    DBMS_OUTPUT.PUT_LINE('é diferente');
  ELSE
    DBMS_OUTPUT.PUT_LINE('é igual');
  END IF;
END;

Resultado: é igual



DECLARE
  C1 VARCHAR2(20) := NULL;
  C2 VARCHAR2(20) := '13240';
BEGIN
  IF C1 = C2 THEN
    DBMS_OUTPUT.PUT_LINE('é diferente');
  ELSE
    DBMS_OUTPUT.PUT_LINE('é igual');
  END IF;
END;

Resultado: é igual

Em ambos os scripts, mesmo tendo alterado as comparações o resultado sempre entra no else.

Para resolver este problema, sempre que realizar uma comparação e o campo a ser comparado permitir NULL em seu conteúdo deve-se usar a função NVL para trocar o valor NULL por qualquer outro valor (o valor vai depender do tipo de comparação desejada) para que a comparação possa ser feita.


DECLARE
  C1 VARCHAR2(20) := NULL;
  C2 VARCHAR2(20) := '13240';
BEGIN
  IF nvl(C1,'*') <> C2 THEN
    DBMS_OUTPUT.PUT_LINE('é diferente');
  ELSE
    DBMS_OUTPUT.PUT_LINE('é igual');
  END IF;
END;

Restulado: é diferente




segunda-feira, 4 de março de 2013

Flashback

FLASHBACK TABLE serve para restaurar uma tabela a um estado anterior devido a um erro qualquer.

É recomendável que o parâmetro de inicialização UNDO_MANAGEMENT esteja definido como AUTO e   o parâmetro UNDO_RETENTION para um intervalo grande o suficiente para incluir os dados que você imagina que seja necessário, para maiores informações consulte:  UNDO_MANAGEMENT e UNDO_RETENTION.


Veja também:

É necessário ter permissão para executar o FLASHBACK ou o FLASHBACK ANY TABLE.


Exemplos

Restaurar uma tabela para um estado anterior: Exemplos
Os exemplos abaixo criar uma nova tabela, employees_demo , com movimento de linha ativado, atualizar valores dentro da nova tabela, e emitir o FLASHBACK TABLE comunicado.
Criar tabela employees_demo , com movimento de linha habilitada, a partir de tabela employees da amostra hr esquema:

CREATE TABLE employees_demo 
  ENABLE ROW MOVEMENT
  AS SELECT * FROM employees;
Como referência, listar os salários inferiores a 2500:

SELECT salary
  FROM employees_demo
  WHERE salary < 2500;
SALARY ---------- 2400 2200 2100 2400 2200

Nota:
Para dar tempo para o SCN para propagar a tabela de mapeamento usado pelo FLASHBACK TABLE declaração, espere um mínimo de 5 minutos antes de emitir a seguinte declaração. Esta espera não seria necessária se uma tabela previamente existentes foram usados ​​neste exemplo.
Emitir um aumento salarial de 10% aos funcionários que ganham menos de 2500:

UPDATE employees_demo
  SET salary = salary * 1.1
  WHERE salary < 2500;

5 rows updated.
COMMIT;
Como referência segunda, listar os salários que permanecem menos de 2500 na sequência do aumento de 10%:

SELECT salary
  FROM employees_demo
  WHERE salary < 2500;
SALÁRIO ---------- 2420 2310 2420
Restaurar a tabela employees_demo ao seu estado de um minuto antes da hora do sistema atual:

FLASHBACK TABLE employees_demo
  TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' minute);
Listar esses salários inferiores a 2500. Após o FLASHBACK TABLE comunicado emitido, esta lista deve coincidir com a lista na primeira referência.

SELECT salary
  FROM employees_demo
  WHERE salary < 2500;
SALÁRIO ---------- 2400 2200 2100 2400 2200

Recuperando uma tabela descartada: Exemplo
Se você acidentalmente deixar cair o hr.employees tabela e deseja recuperá-lo, emitir a seguinte declaração:

FLASHBACK TABLE employees TO BEFORE DROP;
Se outra employees tabela foi criada na hr esquema, use a RENAME TO cláusula para renomear a tabela acessado:

FLASHBACK TABLE employees TO BEFORE DROP RENAME TO employees_old;
Se você sabe que a tabela de funcionários foi derrubado várias vezes, e você deseja recuperar a versão mais antiga, consultar o USER_RECYLEBIN tabela para determinar o nome gerado pelo sistema e, em seguida, usar esse nome no FLASHBACK TABLE comunicado. (Sistema de nomes gerados em seu banco de dados diferentes daqueles mostrados aqui.)

SELECT object_name, droptime FROM user_recyclebin 
   WHERE original_name = 'employees';
DROPTIME OBJECT_NAME ------------------------------------------------- RB $ 45703 $ $ TABELA $ 0 2003-06-03:15:26:39 RB 45704 $ $ $ $ 0 TABELA 2003-06-12:12:27:27 RB 45705 $ $ $ $ 0 TABELA 2003-07-08:09:28:01



quinta-feira, 28 de fevereiro de 2013

Procedure CREATE_NEW_USER

Procedure para criar usuário


CREATE OR replace PROCEDURE Create_new_user(p_username VARCHAR2) 
IS 
BEGIN 
    
EXECUTE IMMEDIATE 'CREATE USER '|| p_username|| 
' identified BY atos DEFAULT tablespace USERS temporary tablespace TEMP profile DEFAULT' 
; 

-- EXECUTE IMMEDIATE 'grant/Revoke role privileges 
    
EXECUTE IMMEDIATE 'grant CONNECT TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant RESOURCE TO '|| p_username|| ''; 

-- EXECUTE IMMEDIATE 'grant/Revoke system privileges 
    
EXECUTE IMMEDIATE 'grant CREATE PROCEDURE TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant CREATE sequence TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant CREATE synonym TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant CREATE TABLE TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant CREATE TRIGGER TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant CREATE view TO '|| p_username|| ''; 

    
EXECUTE IMMEDIATE 'grant unlimited tablespace TO '|| p_username|| ''; 
END create_new_user; 

Alterando Senhas do SYS e SYSTEM


Alterando Senhas do SYS e SYSTEM no ORACLE

É necessário ter acesso ao servidor para fazer esta alteração.

entrar no SQLPLUS (pelo p prompt ou shell) com a opção /NOLOG, Assim:

SQLPLUS /NOLOG

quando estiver no sqlplus, digite:

CONNECT / AS SYSDBA

se conectar você está como SYS o usuário mas poderoso do banco de dados daí você pode trocar a senha do SYSTEM:

ALTER USER SYSTEM IDENTIFIED BY SENHA_NOVA;

pronto, pode trocar a senha do SYS também se quiser, ou conectar sempre assim.

Caso tenha ocorrido o erro ORA-01031: insufficient privileges, quando você tentou conectar como SYSDBA, é porque devem ter definido uma senha para o arquivo PWD do Oracle então faça assim:

Copie o nome do arquivo, você irá usá-lo depois, certifique-se de realmente copiar, pois o novo arquivo que iremos criar deverá ter o nome exatamente igual, inclusive letras maiúsculas e minúsculas, depois remova o arquivo PWD, ele geralmente fica no $ORACLE_HOME/database ou $ORACLE_HOME/dbs o nome dele geralmente é PWD<INSTANCE>.ORA. 

Agora você deve criar um novo arquivo com a nova senha, ou deixar sem o arquivo, se quiser que o SYS não tenha senha. 

Para criar uma nova senha vá no prompt ou shell e digite:


ORAPWD file=PWD<INSTANCE>.ORA password=NOVA_SENHA
substitua PWD<INSTANCE>.ORA pelo arquivo que você copiou.

Pronto, agora entre no sqlplus usando o usuário e nova senha.

Vale lembrar que você precisa ter acesso ao equipamento, isso não dá pra fazer remoto.

quarta-feira, 6 de fevereiro de 2013

Cursores do Oracle


Exemplo de cursores.

Meu amigo Kleber pediu uma ajudinha para aprender a usar cursores, então montei isso para ele.


CREATE OR REPLACE PROCEDURE SQ_PROC_CURSORES (p_acao char) AS
  V_EVENTO_MESTRE CHAR(1) := 'N';

v_ano VARCHAR2(4);

CURSOR creby IS (SELECT CD_EVENTO, CD_MESTRE
                   FROM BIG_OUTAGE
                  WHERE EXTRACT(YEAR FROM DT_PROCESSAMENTO) = v_ano
                    AND EXTRACT(MONTH FROM DT_PROCESSAMENTO) IN (10, 11));


CURSOR krebe IS (SELECT CD_EVENTO, CD_MESTRE
                   FROM BIG_OUTAGE
                  WHERE EXTRACT(YEAR FROM DT_PROCESSAMENTO) = v_ano
                    AND EXTRACT(MONTH FROM DT_PROCESSAMENTO) IN (10, 11));
reg_krebe krebe%ROWTYPE;

forca_erro EXCEPTION;

-- Criado para fazer a mudança de linha ----
crlf  varchar2(2)      := chr(13) || chr(10);
--------------------------------------------

BEGIN

  IF p_acao = '1' THEN
      FOR RS IN (SELECT CD_EVENTO, CD_MESTRE
                   FROM BIG_OUTAGE
                  WHERE /*CD_MESTRE = V_EVENTO_MESTRE
                    AND*/ EXTRACT(YEAR FROM DT_PROCESSAMENTO) = '2012'
                    AND EXTRACT(MONTH FROM DT_PROCESSAMENTO) IN (10, 11)) LOOP

        DBMS_OUTPUT.PUT_LINE(RS.CD_EVENTO || ' - ' || RS.CD_MESTRE);

        IF RS.CD_EVENTO IN (2744055, 2744083, 2744061) THEN
          UPDATE SQ_TESTE SET LOG_ERROS = RS.CD_EVENTO
          WHERE CD_EVENTO = RS.CD_EVENTO;
        END IF;
      END LOOP;
  ELSIF p_acao = 2 THEN
        v_ano := 2012;
       FOR reg_creby IN creby LOOP
          IF reg_creby.CD_EVENTO IN (2744055, 2744083, 2744061) THEN
            UPDATE SQ_TESTE SET LOG_ERROS = 'cursor 2'
            WHERE CD_EVENTO =reg_creby.CD_EVENTO;
          END IF;
       END LOOP;
  ELSIF p_acao =3 THEN
        v_ano := 2012;
        OPEN krebe;
        LOOP
            FETCH krebe INTO reg_krebe;
            EXIT WHEN krebe%NOTFOUND;
            
            IF reg_krebe.CD_EVENTO IN (2744055, 2744083, 2744061) THEN
              UPDATE SQ_TESTE SET LOG_ERROS = 'cursor 2'
              WHERE CD_EVENTO =reg_krebe.CD_EVENTO;
            END IF;        
           
         END LOOP;
  ELSIF p_acao = 4 THEN
        v_ano := 2012;
        OPEN krebe;
        LOOP
            FETCH krebe INTO reg_krebe;
            EXIT WHEN krebe%NOTFOUND;
            
            IF reg_krebe.CD_EVENTO = 2744055 THEN
               RAISE forca_erro;
            END IF;        
           
         END LOOP;        
             
  END IF;
  EXCEPTION
  WHEN forca_erro THEN
       RAISE_application_error (-20004,'Krebynhu - encontrado o evento ' ||
                               reg_krebe.CD_EVENTO || crlf ||
                               '------------------------------------------------' || crlf ||
                               'Código do erro: ' ||  SQLCODE || crlf ||
                               'Descrição do erro: ' || SQLERRM || crlf ||
                               '------------------------------------------------' || crlf );
END;
Related Posts Plugin for WordPress, Blogger...