/*Delphi-like function para converter string para inteiro*/function StrToInt($value){return (int)$value; } /* Função para validar CPF. Baseado na função validaCPF (Delphi) do PoliGestor da empresa Polidados Informática Ltda. */ function validaCPF($cpf){ $CPFInvalido = array ('00000000000', '11111111111', '22222222222', '33333333333', '44444444444', '55555555555', '66666666666', '77777777777', '88888888888', '99999999999'); $digitado = ""; $calculado = ""; $Result = false; try { // verifica CPF inválido for ($i = 0; $i < 9; $i++) if ($cpf == $CPFInvalido[$i]) return false; if ($cpf != ''){ $n1 = StrToInt($cpf[0]); $n2 = StrToInt($cpf[1]); $n3 = StrToInt($cpf[2]); $n4 = StrToInt($cpf[3]); $n5 = StrToInt($cpf[4]); $n6 = StrToInt($cpf[5]); $n7 = StrToInt($cpf[6]); $n8 = StrToInt($cpf[7]); $n9 = StrToInt($cpf[8]); $d1 = $n9*2+$n8*3+$n7*4+$n6*5+$n5*6+$n4*7+$n3*8+$n2*9+$n1*10; $d1 = 11-($d1 % 11); if ($d1>=10) $d1 = 0; $d2 = $d1*2+$n9*3+$n8*4+$n7*5+$n6*6+$n5*7+$n4*8+$n3*9+$n2*10+$n1*11; $d2 = 11-($d2 % 11); if ($d2>=10) $d2 = 0; $calculado = $d1 . $d2; $digitado = $cpf[9] . $cpf[10]; return ($calculado == $digitado) ? true : false; } } catch (Exception $e) { $Result = false; } } ?>
Pesquisar este blog
sábado, 11 de setembro de 2010
Função para validar CPF em PHP
sábado, 4 de setembro de 2010
Principais Visões para ORACLE
Fonte: http://www.techonthenet.com/oracle/sys_tables/index.php
ALL_ARGUMENTS Arguments in object accessible to the user
ALL_CATALOG All tables, views, synonyms, sequences accessible to the user
ALL_COL_COMMENTS Comments on columns of accessible tables and views
ALL_CONSTRAINTS Constraint definitions on accessible tables
ALL_CONS_COLUMNS Information about accessible columns in constraint definitions
ALL_DB_LINKS Database links accessible to the user
ALL_ERRORS Current errors on stored objects that user is allowed to create
ALL_INDEXES Descriptions of indexes on tables accessible to the user
ALL_IND_COLUMNS COLUMNs comprising INDEXes on accessible TABLES
ALL_LOBS Description of LOBs contained in tables accessible to the user
ALL_OBJECTS Objects accessible to the user
ALL_OBJECT_TABLES Description of all object tables accessible to the user
ALL_SEQUENCES Description of SEQUENCEs accessible to the user
ALL_SNAPSHOTS Snapshots the user can access
ALL_SOURCE Current source on stored objects that user is allowed to create
ALL_SYNONYMS All synonyms accessible to the user
ALL_TABLES Description of relational tables accessible to the user
ALL_TAB_COLUMNS Columns of user's tables, views and clusters
ALL_TAB_COL_STATISTICS Columns of user's tables, views and clusters
ALL_TAB_COMMENTS Comments on tables and views accessible to the user
ALL_TRIGGERS Triggers accessible to the current user
ALL_TRIGGER_COLS Column usage in user's triggers or in triggers on user's tables
ALL_TYPES Description of types accessible to the user
ALL_UPDATABLE_COLUMNS Description of all updatable columns
ALL_USERS Information about all users of the database
ALL_VIEWS Description of views accessible to the user
DATABASE_COMPATIBLE_LEVEL Database compatible parameter set via init.ora
DBA_DB_LINKS All database links in the database
DBA_ERRORS Current errors on all stored objects in the database
DBA_OBJECTS All objects in the database
DBA_ROLES All Roles which exist in the database
DBA_ROLE_PRIVS Roles granted to users and roles
DBA_SOURCE Source of all stored objects in the database
DBA_TABLESPACES Description of all tablespaces
DBA_TAB_PRIVS All grants on objects in the database
DBA_TRIGGERS All triggers in the database
DBA_TS_QUOTAS Tablespace quotas for all users
DBA_USERS Information about all users of the database
DBA_VIEWS Description of all views in the database
DICTIONARY Description of data dictionary tables and views
DICT_COLUMNS Description of columns in data dictionary tables and views
GLOBAL_NAME global database name
NLS_DATABASE_PARAMETERS Permanent NLS parameters of the database
NLS_INSTANCE_PARAMETERS NLS parameters of the instance
NLS_SESSION_PARAMETERS NLS parameters of the user session
PRODUCT_COMPONENT_VERSION version and status information for component products
ROLE_TAB_PRIVS Table privileges granted to roles
SESSION_PRIVS Privileges which the user currently has set
SESSION_ROLES Roles which the user currently has enabled.
SYSTEM_PRIVILEGE_MAP Description table for privilege type codes. Maps privilege type numbers to type names
TABLE_PRIVILEGES Grants on objects for which the user is the grantor, grantee, owner, or an enabled role or PUBLIC is the grantee
TABLE_PRIVILEGE_MAP Description table for privilege (auditing option) type codes. Maps privilege (auditing option) type numbers to type names
terça-feira, 31 de agosto de 2010
Exemplo de Midlet
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.util.Date; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; /** * @author agilar */ public class CadastroCliente extends MIDlet { private Display display; private Form frmCadastro; private TextField txtNome, txtEndereco, txtFone, txtEmail; private DateField txtDtCadastro; private ChoiceGroup sexo, casado; private void createGUI(){ txtNome = new TextField("Nome", "", 70, TextField.ANY); frmCadastro.append(txtNome); txtEndereco = new TextField("Endereço", "", 70, TextField.ANY); frmCadastro.append(txtEndereco); txtFone = new TextField("Fone", "", 20, TextField.PHONENUMBER); frmCadastro.append(txtFone); txtEmail = new TextField("E-mail", "", 30, TextField.EMAILADDR); frmCadastro.append(txtEmail); txtDtCadastro = new DateField("Data Cadastro", DateField.DATE); txtDtCadastro.setDate(new Date()); frmCadastro.append(txtDtCadastro); sexo = new ChoiceGroup("Sexo", ChoiceGroup.EXCLUSIVE); sexo.append("Masculino", null); sexo.append("Feminino", null); frmCadastro.append(sexo); casado = new ChoiceGroup("Casado", ChoiceGroup.EXCLUSIVE, new String[] {"Sim", "Não"}, null); frmCadastro.append(casado); } public void startApp() { display = Display.getDisplay(this); frmCadastro = new Form("Cadastro de Clientes"); createGUI(); display.setCurrent(frmCadastro); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
quinta-feira, 12 de agosto de 2010
Arvore binária simples com os três métodos de caminhamento
/* * Árvore binária simples com os três métodos de caminhamento: * Pré-Fixado * Central * Pós-Fixado * * Autor: Everton Agilar * Data: 12/08/2010 * */ package aula.arvore; public class Arvore { int valor; Arvore esq; Arvore dir; public Arvore(int valor){ this.valor = valor; this.esq = null; this.dir = null; } public void add(Arvore no){ if (no.valor < this.valor){ if (esq == null){ esq = no; }else { esq.add(no); } } else { if (no.valor > this.valor){ if (dir == null){ dir = no; } else { dir.add(no); } } } } public void caminhamentoPreFixado(){ System.out.printf("%d%n", valor); // a raiz é acessada por primeiro if (esq != null) esq.caminhamentoPreFixado(); if (dir != null) dir.caminhamentoPreFixado(); } public void caminhamentoCentral(){ if (esq != null) esq.caminhamentoCentral(); System.out.printf("%d%n", valor); // a raiz é acessada no meio if (dir != null) dir.caminhamentoCentral(); } public void caminhamentoPosFixado(){ if (esq != null) esq.caminhamentoPosFixado(); if (dir != null) dir.caminhamentoPosFixado(); System.out.printf("%d%n", valor); // a raiz é a última acessada } public static void main(String[] args) { System.out.println("Demonstração de formas de caminhamento em árvore binária\n"); Arvore arv = new Arvore(10); arv.add(new Arvore(8)); arv.add(new Arvore(12)); arv.add(new Arvore(4)); arv.add(new Arvore(14)); arv.add(new Arvore(2)); arv.add(new Arvore(1)); System.out.println("Caminhamento Pré-Fixado:"); arv.caminhamentoPreFixado(); System.out.println("\nCaminhamento In-Fixado ou Central:"); arv.caminhamentoCentral(); System.out.println("\nCaminhamento Pós-Fixado:"); arv.caminhamentoPosFixado(); } }
quarta-feira, 11 de agosto de 2010
Regras Firewall Pessoal - iptables
# Regras de Firewall
# Autor: Everton Agilar
# Última alteração: 11/08/2010
# Limpa todas as tabelas
iptables -t filter -F INPUT
iptables -t filter -F OUTPUT
iptables -t filter -F FORWARD
# Define política padrão (DROP)
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP
# Permite pacotes de loopback
iptables -t filter -A INPUT -i lo -j ACCEPT
# Permite pacotes de entrada gerados dentro da rede
iptables -t filter -A INPUT -i wlan0 -p tcp -m state --state related,established -j ACCEPT
iptables -t filter -A INPUT -i wlan0 -p udp -m state --state related,established -j ACCEPT
iptables -t filter -A INPUT -i wlan0 -p icmp -m state --state related,established -j ACCEPT
iptables -t filter -A INPUT -i wlan0 -p tcp --sport 20:21 -j ACCEPT
iptables -t filter -A INPUT -i wlan0 -p tcp --sport 1863 -j ACCEPT
iptables -t filter -A INPUT -i wlan0 -p tcp --sport 443 -j ACCEPT
# Permite pacotes de saída para icmp,www,domain,ftp,msn,https
iptables -t filter -A OUTPUT -o wlan0 -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -o wlan0 -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -o wlan0 -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o wlan0 -p tcp --dport 20:21 -j ACCEPT
iptables -t filter -A OUTPUT -o wlan0 -p tcp --dport 1863 -j ACCEPT
iptables -t filter -A OUTPUT -o wlan0 -p tcp --dport 443 -j ACCEPT
segunda-feira, 26 de julho de 2010
Exemplo de Applet e os eventos de ativação
package aula.applet; import java.applet.*; import java.awt.Graphics; public class HelloWorldApplet extends Applet implements Runnable { Thread anime = null; public void init(){ System.out.println("Inicializando..."); } public void start(){ System.out.println("Startando..."); if (anime == null){ System.out.println("Cria animador..."); anime = new Thread(this); anime.start(); }; } public void stop(){ System.out.println("Parando..."); anime.interrupt(); anime = null; } public void destroy(){ System.out.println("Morrendo..."); } public void paint(Graphics g){ int x = new java.util.Random().nextInt(100); int y = new java.util.Random().nextInt(100); g.drawString("Ola Mundo", x, y); System.out.println("pintando..."); } @Override public void run() { while (!Thread.currentThread().isInterrupted()){ try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { } if (isActive()) repaint(); else { break; } } System.out.println("Finalizando animador..."); return; } }
sexta-feira, 23 de julho de 2010
Comandos diversos
ls -l | grep "^d"
Sinopse: ^ significa primeira letra, que nesse caso é d
2 - Para listar somente arquivos executáveis
ls -l | grep "^-..x"
Sinopse: ^ significa lista primeira letra, nesse caso - significa arquivo comum, pula
dois caracteres de permissão (rw) e encontra o x se o arquivo estiver com permissão de
executável
3 - Como listar arquivos somente em uma linha
ls -1
Sinopse: -1 significa 1 linha
4 - Como listar arquivos pelo mais recente (o que foi modificado por último)
ls -1t
Sinopse: Use -1 para listar apenas uma coluna e -t para listar pela data de modificação
5 - Como alterar a data/hora
date 092713202006
clock -w
Sinopse: O comando date serve para alterar a data/hora.
Foi passado no formato mêsdiahoraminutoano.
Logo em seguinda foi usado o comando clock -w para gravar a data/hora na bios.
6 - Copiando usando tar
Use o comando tar.
$ (cd /origem && tar cf - . ) | (cd /destino && tar xvfp -)
Preste atenção nos parêntesis, eles fazem com que a operação seja executada em uma subshell,
não afetando a shell que vc está usando.
7 - Como saber o tamanho de um diretório em MB?
du -sm nome_do_diretório
8 - Como se tornar o root sem efetuas logou
su root ou su -
Sinopse: Digite o comando e após informe a senha
RPM
-------------------------------------------------
8 - Saber se um arquivo pertence a um pacote
rpm -qf nomearquivo
9 - Saber os arquivos de um pacote
rpm -ql koules-1.2-2.i386.rpm
10 - Obter informações sobre um pacote
rpm -qi coreutils
11 - Ver uma lista de todos os pacotes instalados
rpm -qa
12 - Como instalar, atualizar e remover pacotes
rpm -ivh nompacote.rpm
rpm -U nomepacote.rpm
rpm -e nomepacote
13 - Como testar se um pacote pode ser instalado corretamente
rpm -i --test nomepacote.rpm
14 - Reinstalar um pacote
rpm -U --replacedpkgs nomepacote.rpm
Redes
---------------------------------------------------
1 - Como saber as portas TCP abertas
netstat -an | grep LISTEN
diff e patch
-------------------------------------------------------------------
1 - Como comparar dois arquivos e gerar um arquivo das diferenças
diff -a arq1 arq2 > dif.txt
Sinopse: A opção -a foi usada para ser modo texto
G++
-------------------------------------------------------------------
1 - Compilar um programa usando uma bibliteca externa
g++ -o app1.exe -Wl,--add-stdcall-alias,L.,-msgdll app1.c
2 - Compilar sem usar a rtl cygwin1.dll
Incluir a opção -mno-cygwin no g++
--------------------------------------------------------------------
1 - Como redirecionar dispositivos no Windows
Ver comando MODE
Ex.: MODE LPT1:=COM1:
Este comando redireciona tudo que vai para LPT1 para COM1
terça-feira, 6 de julho de 2010
Criando objetos com javascript
// Classe Pessoa
function pessoa(nome, idade, endereco){
this.nome = nome; this.idade = idade; this.endereco = endereco; function gritar(){ if (this.idade >= 30) document.write("aaaaaaaaaaaaaaaa! "); else document.write("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa! "); } this.gritar = gritar; }
// Classe Calc function Calc(){ function add(x, y){ return x + y; } function subtract(x, y){ return x - y; } this.add = add; this.subtract = subtract; }
// instância a calculadora e faz cálculos matemáticos var c = new Calc(); document.write("2+2=" + c.add(2, 2) + " "); document.write("2-2=" + c.subtract(2, 2) + " ");
// instância pessoas e imprime seus nomes var joao = new pessoa("Joao", 30, "rua X"); document.write(" My name is " + joao.nome + " e tenho " + joao.idade + " anos "); joao.gritar(); // instância Maria e imprime seu nome var maria = new pessoa("Maria", 25, "rua Y"); document.write(" My name is " + maria.nome + " e tenho " + maria.idade + " anos "); maria.gritar();
sábado, 26 de junho de 2010
Base de fatos e regras família em Prolog
homem(joao).
homem(marcos).
homem(jader).
homem(henrique).
homem(jonas).
homem(leo).
homem(rodrigo).
mulher(thaise).
mulher(mara).
mulher(carol).
mulher(melina).
marido(everton, thaise).
marido(joao, carol).
esposa(mara, jader).
filho(henrique, everton).
filho(jonas, marcos).
filho(leo, melina).
filho(rodrigo, mara).
casado_com(X, Y):- homem(X),
mulher(Y),
marido(X, Y), !.
casado_com(X, Y):- homem(X),
mulher(Y),
esposa(Y, X), !.
casado_com(X, Y):- mulher(X),
homem(Y),
esposa(X, Y), !.
casado_com(X, Y):- mulher(X),
homem(Y),
marido(Y, X), !.
tem_filho(X):- homem(X),
filho(Y, X), !.
tem_filho(X):- mulher(X),
filho(Y, X), !.
tem_filho(X):- casado_com(X, Y),
filho(K, Y), !.
sábado, 19 de junho de 2010
Questões sobre Gerenciamento de Projetos
É um esforço progressivo e temporário para criar um produto ou serviço único.
2 - O QUE É GERENCIAMENTO DE PROJETOS
É a aplicação de ferramentas, técnicas, conhecimentos e habilidades de gerência de projetos
a fim de atender a seus requisitos.
3 - QUAIS OS PROCESSOS DO GERENCIAMENTO DE PROJETOS
São cinco: iniciação, planejamento, execução, controle e encerramento
4 - QUAIS AS ÁREAS DE CONHECIMENTO DO GERENCIAMENTO DO PROJETO
São nove áreas:
* Gerenciamento de Integração - processos necessários para gerenciar e coordenar
os diversos grupos do gerenciamento de projetos;
Palavra chaves: Termo de abertura, plano de gerenciamento de projeto,
controle e monitoramento.
* Gerenciamento do Escopo - processos envolvidos na verificação de que o projeto
inclui todo o trabalho e somente o necessário para concluir com sucesso.
Palavras chaves: coletar requisitos, definir escopo, criar EAP, verificar e controlar escopo.
* Gerenciamento do Tempo - processos necessários para assegurar o termino
do projeto no tempo definido.
Palavras chaves: Definir e sequenciar atividades, estimar recursos e duração das atividades,
desenvolver e controlar cronograma.
* Gerenciamento de Custos - processos envolvidos no planejamento, estimativa, orçamentação
e controle de custos de modo que o projeto termine dentro do orçamento aprovado.
Palavras chaves: estimar custo, determinar orçamento, controlar custo.
* Gerenciamento da Qualidade - processos envolvidos na garantia de que o projeto
irá satisfazer os objetivos para os quais foi realizado.
Palavras chaves: Planejar qualidade, realizar garantia e controle da qualidade.
* Gerenciamento de Recursos Humanos - processos que organiza e gerencia a equipe do projeto.
Palavras chaves: desenvolver plano de RH, mobilizar equipe, desenvolver e gerenciar equipe.
* Gerenciamento das comunicações - processos relativos a geração e disseminação da informação
do projeto as pessoas interessadas.
Palavras chaves: Identificar interessados, planejar comunicação, reportar desempenho,
gerenciar expectativas.
* Gerenciamento de Riscos - processos para realizar o gerenciamento dos riscos do projeto.
Palavras chaves: planejar e identificar riscos, fazer análise
qualitativa e quantitativa dos riscos, monitorar e controlar riscos.
* Gerenciamento de Aquisições - processos para compra e aquisição de produtos, serviços,
resultados e contratos.
Palavras chaves: planejar e realizar aquisições, administrar e encerrar aquisições.
5 - QUAIS AS HABILIDADES DE UM GERENTE DE PROJETO
São cinco:
Habilidades organizacionais - organização e planejamento
Habilidades para finanças e contabilidade - estimar custos e desenvolver orçamentos
Habilidades de liderar - direcionamento e envolvimento da equipe
Habilidades de negociar e influênciar - dialogar e obter consenso
Habilidades de comunicação - comunicação clara e objetiva
6 - DEFINA O CONTEXTO DO GERENCIAMENTO
São cinco:
Portfólio - carteira de negócios (conj. de programas e/ou projetos)
Programas - são conj. de projetos administrados juntos. Ex.: Programa Educacional
Projeto - é um esforço progressivo e temporário para criar um produto ou serviço único.
Tarefa - elemento de trabalho com duração, custo e recurso definido.
Pacote de trabalho - menor unidade de trabalho possível de ser planejada, controlada e executada.
7 - O QUE É UM PMO
Escritório de projetos. Orienta e fornece suporte aos gerentes de projeto.
8 - PORQUE ESTUDAR GERENCIAMENTO DE PROJETOS
Porque falhas em projetos em suas definições de tempo, prazo e custo são elevadas
quando não se aplicam técnicas consistentes de gerenciamento de projetos. Estudos
mostram que o uso de gerenciamento de projetos aumenta as chances do projeto concluir no prazo e no orçamento estipulado.
9 - PARA GESTÃO DE UM PROJETO, QUAIS OS CICLOS DE VIDA QUE PRECISAMOS CONSIDERAR
São três:
Ciclo de vida do produto - permanência do produto no mercado
Palavras chaves: idealização, concepção, construção, uso e descarte.
Ciclo de vida do projeto - descreve o que deve ser feito para completar o projeto (definem inicio, meio e fim)
Palavras chaves: Termo de abertura, plano do projeto, declaração do escopo, progresso, aceitação, aprovação, entrega
Cicle de vida da GP - descreve o que deve ser feito para gerenciar o projeto (grupos de processos)
Palavras chaves: iniciação, planejamento, execução, controle, encerramento.
10 - CARACTERÍSTICAS DO CICLO DE VIDA DE UM PROJETO DE SOFTWARE
- fases geralmente sequenciadas
- custos e uso do pessoal baixos no início, aumentam durante a execução e cai rapidamente no final
- no início do projeto, nível de incerteza e riscos maiores e caem no final
- capacidade dos stakeholders em influênciar no projeto são maiores no início
- mudanças tem maior impacto a medida que a execução do projeto avança
11 - QUEM SÃO OS STAKEHOLDERS
São os interessados no projeto, ou seja, pessoas ou organizações que influênciam
ou são influênciados, positivamente ou negativamente, pelos resultados de um projeto.
12 - QUEM SÃO OS PRINCIPAIS STAKEHOLDERS
Gerente do projeto, cliente, usuário, membros da equipe, patrocinador, fornecedores, PMOs.
13 - QUAIS OS FATORES DE SUCESSO DE UM PROJETO
- seleção dos processos adequados
- uso de abordagem definida
- atendimento aos requisitos do cliente
- balançeamento de interesses entre os vários interessados
14 - FATORES QUE DETERMINAM A NECESSIDADE OU NÃO DE GERENCIAMENTO DE PROJETO
- Tamanho do empreendimento
- Importãncia do empreendimento
- Reputação da organização
- Compartilhamento de recursos
- Não familiaridade - empreendimento completamente novo
15 - TIPOS DE PROCESSOS
- Orientado ao Projeto - Iniciação, planejamento, execução, controle, monitoramento, encerramento.
- Orientado ao Produto - Especificação e criação do produto do projeto.
quarta-feira, 12 de maio de 2010
Formatando datas no ORACLE para importar scripts do IBExpert
Dois parâmetros no ORACLE devem ser configurados:
- nls_date_format
- nls_timestamp_format
A máscara default utilizado pelo IBExpert para formatar as datas é 'YYYY-MM-DD' para o tipo DATE e 'YYYY-MM-DD HH:MI:SS' para o tipo TIMESTAMP. No ORACLE pode-se executar os seguintes comandos para configurar as máscaras:
Para o tipo DATE:
ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD';
Para o tipo TIMESTAMP:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS';
Seguindo estes procedimentos, consegue-se importar registros que contém campos de data e timestamp de forma simples.
Uma observação é quanto ao tipo TIME do Firebird, inexistente no ORACLE. Para este tipo de dados pode-se armazenar como VARCHAR2(8).
Até o próximo post!
sexta-feira, 7 de maio de 2010
Oracle Pipelined Table Functions
http://www.akadia.com/services/ora_pipe_functions.html
http://mail.firebase.com.br/pipermail/lista_firebase.com.br/2008-February/049950.html
quinta-feira, 6 de maio de 2010
Ativar teclas de atalho para o sqlplus no Linux
Recentemente descobri uma software que pode ser instalado, que permite ativar as teclas de atalho para o sqlplus. Para instalar digite o seguinte comando no prompt de comando.
sudo apt-get install rlwrap
Após instalado, precisamos invocar o sqlplus desta forma:
rlwrap sqlplus user/senha
Com isso, teremos um histórico de comandos da mesma forma que em ambiente Windows.
quarta-feira, 5 de maio de 2010
Usando sudo para executar comandos como root no Linux
Para que qualquer usuário possa utiliza-lo é necessário informar ao Linux que o usuário pertence ao grupo sudo. Podemos fazer isso através do usuário root da seguinte forma:
usermod -G sudo agilar
O comando acima adiciona o usuário agilar no grupo sudo. A partir dai, pode-se utilizar sudo toda vez que precisarmos executar um comando com permissões de root para o usuário agilar.
domingo, 7 de março de 2010
Windows Seven com Delphi 7
A pasta SysWOW64 contém as DLLs de 32 bits. Já a pasta C:\Windows\System32 contém arquivos DLLs de 64 bits. Quando um programa necessita de uma DLL de 32 bits, automaticamente é redirecionado para a pasta C:\Windows\SysWOW64. Pode parecer estranho, mas é assim que o Windows funciona. A pasta C:\Windows\System32 ainda continua existindo, mas seu conteúdo é de 64 bits!
2 - Como substituir o QuickReport do Delphi 7 por outra versão.
Antes de instalar a bpl qrpt70.bpl deve-se primeiro excluir o arquivo c:\windows\SysWOW64\qrpt70.dll e reabrir o Delphi.
3 - Mostrar arquivos e pastas ocultas do Windows
No Windows Explorer, clique no botão Organizar, Opções de pasta e pesquisa. Na janela "Opções de Pasta" possui diversos opções para mostrar pastas e arquivos ocultos.
4 - Como acessar a pasta "Arquivos de Programas" no menu Executar.
Digite "program files".
Obs.: Se você digitar "arquivos de programas" como no Windows XP, aparece a mensagem acesso negado.
quarta-feira, 10 de fevereiro de 2010
Transações em PostgreeSQL
segunda-feira, 25 de janeiro de 2010
Usando condições ANY ou SOME
Dado o esquema a seguir:
SQL> desc valores Nome Nulo? Tipo ------------------- -------- --------- V NUMBER(38) SQL> select * from valores; V ---------- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 linhas selecionadas. SQL>
Exemplos de Condições SQL
EXEMPLO 1 SQL> select * from valores 2 where v = some(1, 3, 10); V ---------- 1 3 10 3 linhas selecionadas. EXEMPLO 2 1 select * from valores 2* where v > some(3, 10, 11) SQL> / V ---------- 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 15 linhas selecionadas. EXEMPLO 3 1 select * from valores 2* where v > all(3, 10, 11) SQL> / V ---------- 12 13 14 15 16 17 18 7 linhas selecionadas.
sexta-feira, 22 de janeiro de 2010
Desafio SQL: Alias em SQL
Considere a seguinte questão:
SQL>
1 select id "Produto ID", sum(preco) "Preco"
2 from estoque
3 where Preco > 50
4 group by "Produto ID"
5* order by sum(preco)
Qual linha causa um erro ?
Analisando a questão, pode-se perceber várias partes que podem dar a entender estar errado. Olhando o SQL, vemos que os campos utilizam-se de alíases, e o campo preco tem um alias semelhante ao nome do campo: "Preco". Isso pode passar despercebido ou confundir, fazendo alguém pensar que a linha 3 está errado, pois o alias está sendo referênciado.
Então a primeira regra que temos que saber: na cláusula WHERE, devemos referênciar o campo e não o alias, senão um erro ocorre.
Na consulta acima, agora não resta dúvida, estamos acessando o campo preco, pois SQL é case insensitive, não importa como escrevemos: preco, Preco, PRECO, PReco, etc. Com isso, podemos concluir também que, se fizermos uma prova para certificação em SQL e aparecer um alias na cláusula WHERE, é certo que há um erro ai.
Para não restar dúvida, segue um SQL de exemplo:
SQL> select codigo "Codigo" from estoque 2 where "Codigo" <> 0; where "Codigo" <> 0 * ERRO na linha 2: ORA-00904: "Codigo": identificador invßlido
Seguindo o exercício da questão, alguns podem dizer que a linha 4 está errado. E de fato, está. A mesma regra do WHERE vale no GROUP BY, na cláusula WHERE e GROUP BY, devemos referênciar o campo e não o alias, senão um erro ocorre.
Segue dois exemplos, o primeiro SQL referenciou um alias no group by e o segundo o próprio campo:
EXEMPLO 1: SQL> 1 select codigo as num 2 from estoque 3* group by num SQL> / group by num * ERRO na linha 3: ORA-00904: "NUM": identificador invßlido EXEMPLO 2: SQL> 1 select codigo as num 2 from estoque 3* group by codigo SQL> / NUM ------------- 1255 124 126 125
Bom, sabemos que o erro na questão está na linha 4, onde é referênciado o alias "Produto ID". Mas quero mostrar outra regra, que nesta questão não se aplica, mas que devemos saber mesmo assim:
Na cláusula ORDER BY, podemos acessar tanto o campo, como o alias ou um número que indica a posição do campo na cláusula SELECT.
Isso pode confundir muitos, pois porque não podemos acessar o alias no WHERE e no GROUP BY mas podemos acessar no ORDER BY. E ainda, podemos acessar o campo pela sua posição na lista de campos do SELECT.
Isso mesmo, segue vários exemplos que mostram isso na prática:
EXEMPLO 1: SQL> 1 select codigo as num 2 from estoque 3* order by codigo SQL> / NUM ------------- 124 124 124 125 125 125 1255 126 8 linhas selecionadas. EXEMPLO 2: SQL> 1 select codigo as num 2 from estoque 3* order by num SQL> / NUM ------------- 124 124 124 125 125 125 1255 126 8 linhas selecionadas. EXEMPLO 3: SQL> 1 select codigo as num 2 from estoque 3* order by 1 SQL> / NUM ------------- 124 124 124 125 125 125 1255 126 8 linhas selecionadas. SQL>
Então como vemos, o ORDER BY é a cláusula mais flexivel de todas, podemos acessar os campos da consulta de qualquer maneira e vai funcionar. A cláusula ORDER BY tem como finalidade ordenar as tuplas de uma relação, portanto, ela é a última etapa executada e consegue ver a relação pronta, ao contrário das demais cláusulas.
Mais uma vez, espero ter ajudado a comunidade de desenvolvedores, sempre tive muita dúvida a respeito disso, até que resolvi escrever este post e testar de diversas maneiras, vários SQL e terminar de uma vez por todas, estas dúvidas sobre o uso do alias em consultas SQL.
Até o próximo post!
Números randômicos em ORACLE
Neste post, vamos ver uma dica para obter números aleatórios. A ORACLE disponibiliza a package DBMS_RANDOM. Vamos consultar as funções disponíveis usando o seguinte comando no SQL-Plus:
SQL> desc dbms_random PROCEDURE INITIALIZE Nome do Argumento Tipo In/Out Default? ------------------------------ ----------------------- ------ -------- VAL BINARY_INTEGER IN FUNCTION NORMAL RETURNS NUMBER FUNCTION RANDOM RETURNS BINARY_INTEGER PROCEDURE SEED Nome do Argumento Tipo In/Out Default? ------------------------------ ----------------------- ------ -------- VAL BINARY_INTEGER IN PROCEDURE SEED Nome do Argumento Tipo In/Out Default? ------------------------------ ----------------------- ------ -------- VAL VARCHAR2 IN FUNCTION STRING RETURNS VARCHAR2 Nome do Argumento Tipo In/Out Default? ------------------------------ ----------------------- ------ -------- OPT CHAR IN LEN NUMBER IN PROCEDURE TERMINATE FUNCTION VALUE RETURNS NUMBER FUNCTION VALUE RETURNS NUMBER Nome do Argumento Tipo In/Out Default? ------------------------------ ----------------------- ------ -------- LOW NUMBER IN HIGH NUMBER IN
Como se pode ver, existem diversas funções para gerar números aleatórios. No exemplo a seguir, vou demonstrar como gerar números aleatórios inteiros entre 1 e 100:
SQL> select trunc(dbms_random.value(1, 100)) num from dual; NUM ---------- 89 SQL> select trunc(dbms_random.value(1, 100)) num from dual; NUM ---------- 9 SQL> select trunc(dbms_random.value(1, 100)) num from dual; NUM ---------- 39
No exemplo, três instruções SQL consecutivas exibem como a função DBMS_RANDOM.VALUE funciona. Ela retorna um valor NUMBER. Como sabemos o tipo NUMBER pode armazenar tanto números inteiros como números ponto flutuante. Para retornar um inteiro, foi utilizado a função TRUNC. A função utilizada permite passar o range da randomização, o que pode ser muito útil.
É isso ai, espero ter ajudado a quem procura uma maneira de gerar números randômicos em ORACLE.
Até mais!
SQL - Verificar duplicidade de código de barra
Últimamente alguns clientes estão reclamando que há mais de 1 produto com o mesmo código. O Analista, ao verificar o banco de dados, descobre que não existe uma chave única no campo do código de barra. Como podemos saber quais são os produtos que possuem o código duplicado ?
Resposta: Existem várias maneiras de construir um SQL para verificar duplicidade de valor em uma coluna. Uma das maneiras que vou ensinar é usar subquery e a cláusula group by como segue:
select id, codigo, nome from estoque where codigo in (select codigo from estoque group by codigo having count(codigo) > 1)
Analisando a consulta, verifique que estamos buscando todos os produtos da tabela estoque que tem o código na sub-consulta. A sub-consulta, por sua vez, lista os códigos da tabela estoque que possuem duplicidade.
Para entender a sub-consulta, é simples, baste dizer que "select codigo from estoque group by codigo" lista todos os códigos sem duplicidade e "having count(codigo) > 1" filtra somente os códigos que existe em mais de 1 tupla na tabela estoque.
Ainda me lembro há 5 anos atraz de um programa em Clipper para fazer isso. Apenas um comando SQL fez todo trabalho!
É isso ai, até o próximo post, com mais dicas!
quarta-feira, 20 de janeiro de 2010
Vou ter que ensinar o Firebird a fazer aritmética
Eis a expressão no código fonte:
Lucro:= TruncFloat((ADO_EstoquePRC_VENDA.AsCurrency - ADO_EstoquePRC_CUSTO.AsCurrency) / ADO_EstoquePRC_CUSTO.AsCurrency * 100, 9);
A mesma expressão em um formato mais legível é:
vLucro:= trunc(((prc_venda - prc_custo) / prc_custo) * 100, 9); Resultado no Delphi usando o tipo REAL para vLucro: 80,375180375
Esta expressão é truncada para 9 casas para ter uma precisão boa em nosso sistema. Então qual é o problema ? Se executarmos esta mesma expressão no servidor RDBMS Firebird, o resultado é 80.370000000 em uma stored procedure (codificando vLucro com tipo NUMERIC(12, 9)) ou 80.37 quando executado via SQL.
A instrução SQL é a seguinte:
select ((200 - 110.88)/110.88)*100 from rdb$database Resultado: 80.37 Versão do Firebird: 2.5
SOLUÇÂO
A solução encontrada foi ensinar o Firebird a fazer a aritmética, promovendo um número da expressão, como segue:
select ((cast(200 as numeric(12, 9)) - 110.88)/110.88)*100 from rdb$database Resultado: 80,375180375
Esta solução funcionou mas me deixou preocupado com os demais cálculos realizados pelo sistema. Sabemos que o Firebird realiza cálculos com precisão diferente de outros bancos e de outras linguagens de programação e isso pode acarretar problemas em arredondamentos e cálculos de porcentagens.
CONCLUSÂO
Sabe-se que cada RDBMS usa um esquema diferente para promover seus tipos. A conversão implícita (automática), nem sempre é o que queremos. No ORACLE, por exemplo, é recomendado usar to_number para fazer as conversões. Depois de fazer a promoção de uma parte da expressão para NUMERIC(12, 9) o cálculo ficou correto porque foi informado ao Firebird que os cálculos devem ser entre números com tipos NUMERIC(12, 9).É isso ai, até mais!
terça-feira, 19 de janeiro de 2010
Dicas e Truques PL/SQL - Parte 3
Function ASCII - retorna o código ASCII do caracter. SQL> select ascii('A') from dual; ASCII('A') ---------- 65 Function CHR - Retorna um caracter quando recebe seu valor ASCII. SQL> select chr(65) from dual; C - A Function CONCAT - Concatena duas strings. SQL> select concat('ORACLE ', 'PL/SQL') texto from dual; TEXTO ------------- ORACLE PL/SQL Function INITCAP - Primeiro caracter de cada palavra de uma string em maiúsculo. SQL> select initcap('everton de vargas agilar') my_name from dual; MY_NAME ------------------------ Everton De Vargas Agilar Function INSTR - Retorna a localização de uma string dentro de outra string. EXEMPLO 1 SQL> select instr('ABCDEFGHIJLMNOPQRSTUVXZabcdefghijlmnopqrstuvxzABCDEFGHIJKLMNOPQRSTUVXZ', 'DEF') pos from dual; POS ---------- 4 EXEMPLO 2 SQL> select instr('ABCDEFGHIJLMNOPQRSTUVXZabcdefghijlmnopqrstuvxzABCDEFGHIJKLMNOPQRSTUVXZ', 'DEF', 5) pos from dual; POS ---------- 50 EXEMPLO 3 SQL> 1 create or replace procedure print_values( 2 pValues in varchar2, 3 pDesconsiderar in varchar2) 4 is 5 v char; 6 begin 7 for i in 1..length(pValues) loop 8 v:= substr(pValues, i, 1); 9 if instr(pDesconsiderar, v) = 0 then 10 dbms_output.put_line(v); 11 end if; 12 end loop; 13* end; SQL> / Procedimento criado. SQL> execute print_values('12345', '4'); 1 2 3 5 Procedimento PL/SQL concluÝdo com sucesso. Function LPAD - Preenche uma string no lado esquerdo de caracteres com qualquer string especificada. SQL> select lpad('789123', 13) codigo from dual; CODIGO ------------- 789123 SQL> select lpad('789123', 13, '0') codigo from dual; CODIGO ------------- 0000000789123 SQL> select lpad('789123', 13, '01') codigo from dual; CODIGO ------------- 0101010789123 SQL> select lpad('789123', 13, '*') codigo from dual; CODIGO ------------- *******789123 Function RPAD - Preenche uma string no lado direito de caracteres com qualquer string especificada. SQL> select rpad('789123', 13) codigo from dual; CODIGO ------------- 789123 SQL> select rpad('789123', 13, '0') codigo from dual; CODIGO ------------- 7891230000000 SQL> select rpad('789123', 13, '01') codigo from dual; CODIGO ------------- 7891230101010 SQL> select rpad('789123', 13, '-') codigo from dual; CODIGO ------------- 789123------- SQL> select rpad('789123', 13, '*') codigo from dual; CODIGO ------------- 789123******* Function LENGTH - Retorna o comprimento de uma string. SQL> select length('ORACLE 10g') text from dual; TEXT ---------- 10 Function REPLACE - Substitui toda ocorrência de uma string por outra string. SQL> select replace('ORACLE 10g', '10g', '11g') text from dual; TEXT ---------- ORACLE 11g Function TRANSLATE - Igual a REPLACE mas opera a nível de caracter. Veja um exemplo com REPLACE e TRANSLATE. -- Converte ad para x. Somente uma ocorrência a ser encontrada. SQL> select replace('abcdabada', 'ad', 'x') from dual; REPLACE( -------- abcdabxa -- Converte o caracter "a" ou o caracter "d" para x. Várias ocorrências são encontradas. SQL> select translate('abcdabada', 'ad', 'x') from dual; TRANSLA ------- xbcxbxx Function SOUNDEX - Retorna a representação fonética de uma string. Útil nas palavras que têm ortografia diferente mas com som parecido. SQL> 1 select * from ( 2 select 'Agilar' as nome from dual 3 union 4 select 'Aguilar' as nome from dual 5 union 6 select 'Stefanello' as nome from dual 7 union 8 select 'Agilare' as nome from dual 9 ) 10* where soundex(nome) = soundex('Agilar') SQL> / NOME ---------- Agilar Agilare Aguilar Function SUBSTR - Retorna uma parte de uma string de dentro de uma string. SQL> select substr('ORACLE 11g', 8, 3) from dual; SUB --- 11g Function TRIM, LTRIM, RTRIM - Remove espaços de uma string em ambos lados, a esquerda ou a direita. SQL> select trim(' 8976 ') texto from dual; TEXT ---- 8976 SQL> select ltrim(' 8976 ') text from dual; TEXT ----------- 8976 SQL> select rtrim(' 8976 ') text from dual; TEXT ---------- 8976 Function UPPER, LOWER - Converte a string para maiúsculo ou minúsculo. SQL> select upper('oracle') texto from dual; TEXTO ------ ORACLE SQL> select lower('Oracle') texto from dual; TEXTO ------ oracle Function ABS - Retorna o valor absoluto de um número. SQL> select abs(-11) from dual; ABS(-11) ---------- 11 SQL> select abs(11) from dual; ABS(11) ---------- 11 Function FLOOR - Retorna o maior integer menor ou igual a um valor decimal. Function CEIL - Retorna o menor integer maior ou igual a um valor decimal. SQL> select floor(12345.56) from dual; FLOOR(12345.56) --------------- 12345 SQL> select ceil(12345.56) from dual; CEIL(12345.56) -------------- 12346 Function ROUND - Retorna um número arredondado para n casas. SQL> select round(10.126, 2) from dual; ROUND(10.126,2) --------------- 10,13 SQL> select round(10.126, 2) value from dual; VALUE ---------- 10,13 SQL> select round(10.126, 3) value from dual; VALUE ---------- 10,126 Function Trunc - Retorna um número truncado em n casas. SQL> select trunc(10.126, 3) from dual; TRUNC(10.126,3) --------------- 10,126 SQL> select trunc(10.126, 2) from dual; TRUNC(10.126,2) --------------- 10,12 SQL> select trunc(10.126, 1) from dual; TRUNC(10.126,1) --------------- 10,1 SQL> select trunc(123456, -1) from dual; TRUNC(123456,-1) ---------------- 123450 SQL> select trunc(123456, -2) from dual; TRUNC(123456,-2) ---------------- 123400 SQL> select trunc(123456, -3) from dual; TRUNC(123456,-3) ---------------- 123000 Function SIGN - Determina se um número é positivo, negativo ou zero. SQL> select sign(10) from dual; SIGN(10) ---------- 1 SQL> select sign(-10) from dual; SIGN(-10) ---------- -1 SQL> select sign(0) from dual; SIGN(0) ---------- 0 Function ADD_MONTHS - Adiciona mês a uma data. SQL> select add_months(to_date('31/01/2010', 'dd/mm/yyyy'), 1) from dual; ADD_MONT -------- 28/02/10 SQL> select add_months(to_date('31/01/2010', 'dd/mm/yyyy'), -1) from dual; ADD_MONT -------- 31/12/09 Function LAST_DAY - Retorna a data do último dia do mês. SQL> select last_day(to_date('19/01/2010', 'dd/mm/yyyy')) from dual; LAST_DAY -------- 31/01/10 SQL> select last_day(to_date('01/02/2010', 'dd/mm/yyyy')) from dual; LAST_DAY -------- 28/02/10 Function MONTHS_BETWEEN - Calcula os meses entre duas datas. SQL> select months_between(to_date('01/03/2010', 'dd/mm/yyyy'), to_date('01/04/2010', 'dd/mm/yyyy')) meses from dual; MESES ---------- -1 SQL> select months_between(to_date('01/04/2010', 'dd/mm/yyyy'), to_date('01/03/2010', 'dd/mm/yyyy')) meses from dual; MESES ---------- 1 Function NEXT_DAY - Retorna a data do primeiro dia da semana especificado em uma string após a data inicial. SQL> select next_day(sysdate, 'SEXTA') from dual; NEXT_DAY -------- 22/01/10 SQL> select next_day(sysdate, 'DOMINGO') from dual; NEXT_DAY -------- 24/01/10 Function TO_CHAR - Converte um número ou data para string. EXEMPLOS COM DATA SQL> select to_char(sysdate, 'Month') dt from dual; DT ------------------------------------ Janeiro SQL> select to_char(sysdate, 'MON') dt from dual; DT ------------ JAN SQL> select to_char(sysdate, 'MONTH') dt from dual; DT ------------------------------------ JANEIRO SQL> select to_char(sysdate, 'MM') dt from dual; DT -- 01 SQL> select to_char(sysdate, 'YYYY') dt from dual; DT ---- 2010 SQL> select to_char(sysdate, 'YYY') dt from dual; DT --- 010 SQL> select to_char(sysdate, 'YY') dt from dual; DT -- 10 SQL> select to_char(sysdate, 'RR') dt from dual; DT -- 10 SQL> select to_char(sysdate, '"Data: "DD/MM/YYYY') dt from dual; DT ---------------- Data: 19/1/2010 SQL> select to_char(sysdate, 'FMDay, Month, YYYY') dt from dual; DT ------------------------------------------------------------------- Terþa-Feira, Janeiro, 2010 SQL> select to_char(sysdate, 'Day, Month, YYYY') dt from dual; DT ------------------------------------------------------------------- Terça-Feira , Janeiro , 2010 EXEMPLOS COM NÚMEROS SQL> select to_char(12345.23, '99999999') from dual; TO_CHAR(1 --------- 12345 SQL> select to_char(12345.23, '99999D99') from dual; TO_CHAR(1 --------- 12345,23 SQL> select to_char(12345.23, '99999D999') from dual; TO_CHAR(12 ---------- 12345,230 SQL> select to_char(12345.23, '99999D000') from dual; TO_CHAR(12 ---------- 12345,230 SQL> select to_char(12345, '99999D000') from dual; TO_CHAR(12 ---------- 12345,000 SQL> select to_char(12345, '$99999D000') from dual; TO_CHAR(123 ----------- $12345,000 SQL> select to_char(12345, 'L99999D000') from dual; TO_CHAR(12345,'L9999 -------------------- R$12345,000 -- OBS: Se a máscara for menor que o número, o caracter # será impresso! SQL> select to_char(12345, '999') from dual; TO_C ---- ####
segunda-feira, 18 de janeiro de 2010
Dicas e Truques PL/SQL - Parte 2
1 - Uso do WHILE com EXIT WHEN SQL> 1 create or replace 2 function conta_ate_espaco(texto in varchar2) return number is 3 i number := 1; 4 vResult number := 0; 5 begin 6 while i <= length(texto) loop 7 if substr(texto, i, 1) != ' ' then 8 vResult:= vResult + 1; 9 i:= i+1; 10 end if; 11 exit when substr(texto, i, 1) = ' '; -- vai sair do loop quando encontrar um espaço 12 end loop; 13 -- return é executado após o fim do loop ou quando exit when da linha 11 é executado. 14 return vResult; 14* end; SQL> 2 - Usando rótulos para identificar loops. EXEMPLO 1: SQL> 1 create or replace 2 function conta_ate_espaco(texto in varchar2) return number is 3 i number := 1; 4 vResult number := 0; 5 begin 6 <<conta_char>> -- define um rótulo 7 while i <= length(texto) loop 8 if substr(texto, i, 1) != ' ' then 9 vResult:= vResult + 1; 10 i:= i+1; 11 end if; 12 exit when substr(texto, i, 1) = ' '; 13 end loop conta_char; -- finalize o loop e opcionalmente informe o nome do rótulo 14 return vResult; 15* end; SQL> / EXEMPLO 2: SQL> 1 create or replace procedure imprime_tabuada is 2 vNumero number := 1; 3 i number := 1; 4 begin 5 <<inicio_rotina>> 6 for vNumero in 1..10 loop 7 i := 1; 8 <<tabuada>> 9 loop 10 dbms_output.put_line(to_char(vNumero) || 'x' || 11 to_char(i) || ' = ' || to_char(vNumero*i)); 12 exit tabuada when i = 10; 13 i := i + 1; 14 end loop tabuada; 15 end loop inicio_rotina; 16* end; SQL> EXEMPLO 3 SQL> 1 create or replace procedure conta_ate_10 is 2 i number := 1; 3 begin 4 <<conta>> 5 loop 6 dbms_output.put_line(i); 7 exit when i = 10; 8 i := i + 1; 9 end loop; 10* end; SQL> 3 - Usando a instrução GOTO. SQL> 1 create or replace procedure conta_ate_10_com_goto is 2 i number := 1; 3 begin 4 loop 5 dbms_output.put_line(i); 6 if i = 10 then 7 goto fim; 8 end if; 9 i := i + 1; 10 end loop; 11 <<fim>> 12 null; -- necessário uma instrução após o rótulo ou um erro é gerado 13* end; SQL>
domingo, 10 de janeiro de 2010
Dicas e Truques PL/SQL - Parte 1
1 - Nunca esqueça de usar o ; para finalizar uma bloco PL/SQL. SQL> begin 2 dbms_output('não esqueça de usar ;'); 3 end 4 / end * ERRO na linha 3: ORA-06550: linha 3, coluna 3: PLS-00103: Encontrado o símbolo "end-of-file" quando um dos seguintes símbolos era esperado: ;O símbolo ";" foi substituído por "end-of-file" para continuar. SQL> begin 2 dbms_output.put_line('o ; finaliza um bloco PL/SQL'); 3* end; SQL> / Procedimento PL/SQL concluído com sucesso. SQL> 2 - Uma tipo VARCHAR2 tem 4000 bytes de comprimento no banco mas em PL/SQL o limite sobe para 32767 bytes. 3 - Existem dois subtipos para o tipo VARCHAR2: VARCHAR e STRING. A ORACLE recomenda que não se usem estes dois subtipos, pois existe apenas para compatibilidade com outras marcas de banco de dados e também com o padrão SQL. SQL> 1 declare 2 x varchar2(100); 3 y string(100); 4 z varchar(100); 5 begin 6 x:= 'Use sempre o tipo VARCHAR2 '; 7 y:= 'em vez de subtipos STRING '; 8 z:= 'ou VARCHAR.'; 9 dbms_output.put_line(x || y || z); 10* end; SQL> / Use sempre o tipo VARCHAR2 em vez de subtipos STRING ou VARCHAR. Procedimento PL/SQL concluído com sucesso. SQL> 4 - Ao declarar uma variável VARCHAR2 dentro de um procedimento armazenado sempre especifique o comprimento ou um erro ocorrerá. 5 - Ao invocar uma função que não retorne valor um erro será levantado. 6 - A comparação entre variáveis VARCHAR2 e CHAR pode retornar falso, pois o tipo CHAR é fixo. SQL> declare 2 x1 varchar2(10); 3 x2 char(10); 4 begin 5 x1:= 'agilar'; 6 x2:= 'agilar'; 7 if x1 = x2 then 8 dbms_output.put_line('exatamente iguais'); 9 else 10 dbms_output.put_line('diferente!'); 11 end if; 12 end; 13 / Procedimento PL/SQL concluído com sucesso. SQL> set serveroutput on SQL> / diferente! Procedimento PL/SQL concluído com sucesso. 7 - Use funções e procedimentos aninhados para obter modularidade. SQL> 1 declare 2 x1 number; 3 x2 number; 4 procedure troca(x in out number, y in out number) 5 as 6 temp number; 7 begin 8 temp:= x; 9 x:= y; 10 y:= temp; 11 end; 12 begin 13 x1:= 100; 14 x2:= 200; 15 dbms_output.put_line(x1); 16 dbms_output.put_line(x2); 17 troca(x1, x2); 18 dbms_output.put_line(x1); 19 dbms_output.put_line(x2); 20* end; SQL> / 100 200 200 100 Procedimento PL/SQL concluído com sucesso. 8 - Não use os tipos obsoletos: LONG, RAW e LONG RAW. 9 - Use PLS_INTEGER em vez de BINARY_INTEGER em aplicativos novos para obter performance. 10 - Cuidado com o escopo das variáveis. Uma variável pode ser referenciada apenas dentro do bloco em que foi declarado. SQL> 1 declare 2 x varchar2(10):= 'everton'; 3 begin 4 declare 5 y varchar2(10):= 'agilar'; 6 begin 7 dbms_output.put_line(x); 8 dbms_output.put_line(y); 9 end; 10 dbms_output.put_line(y); -- erro pois y está declarado dentro do bloco anterior 11* end; SQL> / dbms_output.put_line(y); * ERRO na linha 10: ORA-06550: linha 10, coluna 23: PLS-00357: A referência 'Y' Ó Tabela, View ou Seqência não permitida neste contexto ORA-06550: linha 10, coluna 2: PL/SQL: Statement ignored SQL> 11 - Exemplos de uso da função CAST SQL> select cast(123.1254 as number(12,3)) as num from dual; NUM ---------- 123,125 SQL> select cast(123.1254 as number(12,2)) as num from dual; NUM ---------- 123,13 SQL> select cast(123.1254 as number(12,1)) as num from dual; NUM ---------- 123,1 SQL> select cast(123.1254 as number(12,0)) as num from dual; NUM ---------- 123 SQL> select cast(123.1254 as number(12,-1)) as num from dual; NUM ---------- 120 SQL> select cast(123.1254 as number(12,-2)) as num from dual; NUM ---------- 100 SQL> select cast(123.1254 as number(12,-3)) as num from dual; NUM ---------- 0 SQL> 12 - Você pode usar o operador de exponenciação em PL/SQL mas não em SQL. SQL> l 1 declare 2 x number:= 10; 3 y number:= 2; 4 begin 5 dbms_output.put_line(x**y); 6* end; SQL> / 100 Procedimento PL/SQL concluído com sucesso. SQL> select 10**2 from dual; select 10**2 from dual * ERRO na linha 1: ORA-00936: expressão não encontrada 13 - É possível atribuir um valor durante a declaração da variável. SQL> l 1 declare 2 pi number:= 3.14; 3 x number; 4 y number:= 10; 5 begin 6 dbms_output.put_line('O número PI is '|| to_char(pi)); 7* end; SQL> 14 - Operadores de desigualdade da PL/SQL: <>, != e ~= 1 begin 2 if 1 != 2 then 3 dbms_output.put_line('diferente'); 4 end if; 5 if 1 <> 2 then 6 dbms_output.put_line('diferente'); 7 end if; 8 if 1 ~= 2 then 9 dbms_output.put_line('diferente'); 10 end if; 11* end; SQL> 15 - Expressões envolvendo NULL em PL/SQL SQL> 1 declare 2 a number; 3 b number; 4 begin 5 -- Atribui 10 a variável A mas deixa B null. 6 a:= 10; 7 -- A lógica dos três valores diz que o resultado 8 -- de uma expressão pode ser true, false ou null. 9 if a = b then 10 dbms_output.put_line('a = b is true'); 11 elsif a <> b then 12 dbms_output.put_line('a = b is not true'); 13 else 14 dbms_output.put_line('a = b is null'); 15 end if; 16 -- Eis uma expressão que muitos esperam ser true 17 if (a = b) or (a <> b) then 18 dbms_output.put_line('true'); 19 else 20 dbms_output.put_line('is not true'); 21 end if; 22* end; SQL> / a = b is null is not true Procedimento PL/SQL concluído com sucesso. SQL> 16 - Oracle considera uma string vazia como sendo null. SQL> 1 declare 2 x varchar2(10); 3 y varchar2(10); 4 begin 5 -- Oracle considera uma string vazia como sendo null 6 x:= ''; 7 if x = '' then 8 dbms_output.put_line('x is vazio'); 9 elsif x is null then 10 dbms_output.put_line('x is null'); 11 else 12 dbms_output.put_line('x contém algo?'); 13 end if; 14 -- Comparação entre duas variáveis vazias 15 y:= ''; 16 if x = y then 17 dbms_output.put_line('x = y'); 18 elsif x is null then 19 dbms_output.put_line('x is null'); 20 else 21 dbms_output.put_line('x <> y'); 22 end if; 23* end; SQL> / x is null x is null Procedimento PL/SQL concluído com sucesso. SQL> 17 - NULL não se propaga na concatenação de strings em ORACLE. Em outros RDBMS o valor retornado é NULL. SQL> 1* select 'everton ' || 'agilar' || null from dual; 'EVERTON'||'AG -------------- everton agilar SQL> begin 2 dbms_output.put_line('everton ' || 'agilar' || null); 3 end; 4 / everton agilar Procedimento PL/SQL concluído com sucesso. SQL> 18 - Use a função NVL ou COALESCE para trocar valores nulls por outro valor. SQL> select nvl(null, 10) from dual; NVL(NULL,10) ------------ 10 SQL> select coalesce(null, 10) from dual; COALESCE(NULL,10) ----------------- 10 19 - Como comparar duas datas em PL/SQL para saber se o ano é o mesmo ? SQL> 1 declare 2 d1 date; 3 d2 date; 4 begin 5 d1:= to_date('30/03/2010', 'dd/mm/yyyy'); 6 d2:= sysdate; 7 if trunc(d1, 'yyyy') = trunc(d2, 'yyyy') then 8 dbms_output.put_line('ano igual...'); 9 else 10 dbms_output.put_line('ano diferente...'); 11 end if; 12* end; SQL> / ano igual... Procedimento PL/SQL concluído com sucesso. SQL> 20 - Obtendo as partes de uma data através da função TO_CHAR. SQL> select to_char(to_date('10/01/2010', 'dd/mm/yyyy'), 'dd') from dual; TO -- 10 SQL> select to_char(to_date('10/01/2010', 'dd/mm/yyyy'), 'mm') from dual; TO -- 01 SQL> select to_char(to_date('10/01/2010', 'dd/mm/yyyy'), 'yyyy') from dual; TO_C ---- 2010 SQL>
quinta-feira, 7 de janeiro de 2010
Criando e usando um repositório Subversion
A equipe de desenvolvimento pode trabalhar em diversos arquivos e após sincronizar estes arquivos com o repositório que mantém a cópia oficial do projeto. Cada usuário trabalha em uma cópia local (Work Copy), realizando as alterações necessárias e depois comitando com o repositório.
Abaixo, segue algumas dicas sobre a implantação de um repositório SVN em minha empresa divididos em etapas que devem ser seguidas passo a passo.
Onde posso baixar o Subversion
O Subversion pode ser encontrado no link http://subversion.tigris.org/. É um produto open-source disponibilizado gratuitamente. Existem também diversos outros pacotes de software disponível e plugins para várias IDEs.Pacotes Necessários para Implantação do Subversion
Servidor VisualSVN - http://www.visualsvn.com/visualsvn/download/
Cliente TortoiseSVN - http://tortoisesvn.tigris.org/
O que é o VisualSVN
Conjunto de ferramentas necessárias para implementar o SVN junto com um servidor Web para administração remota. Este software é necessário no servidor onde será instalado o SVN.
O que é o TortoiseSVN
Plugin Windows para ter acesso ao repositório através do Windows Explorer. É independente de IDE e os desenvolvedores podem ter acesso aos comandos do SVN de forma muito fácil. Somente este plugin é necessário nas estações de trabaho dos desenvolvedores mas pode ser instalado também no servidor para facilitar o uso do SVN.
Sobre o servidor VisualSVN
Existem diversos pacotes e plugins disponíveis ficando as vezes complicado a escolha de qual instalar. Ao implantar o Subversion optei por instalar o VisualSVN. O link direto pode ser encontrado em: http://www.visualsvn.com/visualsvn/download/.
A escolha do VisualSVN foi permitir gerenciar os usuários e criar o repositório em uma ferramenta visual, ter acesso aos comandos standalone svn e svnadmin quando necessário e ainda permitir gerenciar o repositório remotamente. Os comandos svn, svnadmin são muito úteis para administração do repositório via linha de comando. A Fig. 1 exibe a tela do VisualSVN.
Para instalar o servidor é preciso apenas executar seu setup. Um serviço será instalado chamado VisualSVN. Você pode verificar o serviço através do utilitário services.msc. Durante a instalação é necessário selecionar a porta do serviço ou deixar a porta padrão 443 se a opção SSL for selecionada.
Com o servidor instalado, já podemos abrir o aplicativo VisualSVN Server Manager e criar um repositório SVN.
Instalando o cliente TortoiseSVN
Apos instalado o VisualSVN, vamos instalar o plugin TortoseSVN. Através deste plugin podemos fazer praticamente qualquer atividade necessária: criar um repositório, criar um pasta de trabalho, etc. A intenção de utilizar o TortoiseSVN é aumentar a produtividade no dia-dia, pois não será necessário usar o prompt de comando para sincronizar os fontes com a equipe. Este plugin pode ser instalado tanto no servidor, se também for um ambiente de desenvolvimento como nas demais estações de trabalho.
Para instalar o TortoiseSVN basta executar o setup e sequir confirmando as opções do instalador. Com a instalação concluída perceba que se você clicar no botão direito do mouse verá o menu TortoiseSVN. É através deste menu que você tem acesso a todos os recursos do Subversion para gerenciar o seu SVN. A Fig. 2 exibe o menu com a opção TortoiseSVN e SVN Checkout....
Entendendo o Repositório
Pense no repositório como um banco de dados. Dentro do banco de dados você vai inserir (usamos o termo importar no SVN) a pasta raiz do seu projeto e então poderá através do TortoiseSVN criar uma pasta "local" em qualquer computador na sua rede exatamente igual a pasta importada do seu projeto. Esta pasta local será a Work Copying, ou seja, cópia de trabalho. Você, desenvolvedor, poderá trabalhar nela e alterar qualquer arquivo sem interferir no servidor SVN. Quando desejar poderá querer salvar (comitar) as alterações realizadas com o servidor, quando então, o Subversion vai persistir os arquivos alterados no repositório do projeto.
A cada commit, o Subversion gera uma nova versão. Através deste esquema de geração de versão, pode-se rapidamente "navegar" entre as versões do projeto com muita facilidade e sem medo de perda de dados, uma vez que estamos apenas trabalhando em uma cópia local.
O Subversion tem total controle do que a equipe de desenvolvimento está fazendo. Por exemplo, se dois usuários tentarem comitar um mesmo arquivo sendo alterado, o desenvolvedor será avisado que o arquivo foi alterado por mais de 1 usuário e oferecerá várias opções para eliminar o conflito. Em meus vários testes, obtive muito exito. De fato, o TortoiseSVN oferece uma quantidade enorme de ferramentas, incluindo ferramentas que mostram o que mudou de um arquivo para outro (Diffs).
Criando um Repositório
Com o servidor VisualSVN e o cliente TortoiseSVN instalados vamos criar um repositório no servidor para gerenciar um projeto. Para isto é preciso definir onde será o repositório. O repositório pode ser criado de varias maneiras:
- com o VisualSVN - No VisualSVN você pode criar o repositório facilmente. Será necessário criar pelo menos um usuário antes realizar a criação do repositório. Vários outros usuários podem ser criados para utilizar o SVN.
- com o TortoiseSVN - Através do menu TortoseSVN selecione a opção "Create repository here". A criação do repositório pelo Tortoise seria útil para um desenvolvedor. Para uma equipe use o VisualSVN.
- Pode-se usar a opção de linha de comando - svnadmin create d:\repo
Importando o projeto para o repositório
Para importar o projeto para o repositório navegue até a pasta do projeto e com a opção "Import" do TortoseSVN, informe o repositório onde será armazenado o projeto. Informe o caminho no seguinte formato: https://hostname/svn/nome_repositorio. Clique no botão Ok e aquarde o projeto ser importado para dentro do repositório. Após importado já é possível criar uma pasta de trabalho em qualquer estação de trabalho.
Criando a pasta de trabalho (Working Copy)
Novamente, utilizando o plugin TortoiseSVN, selecione a opção SVN Checkout em alguma pasta vazia, onde será definido a pasta de trabalho. Aguarde a criação de pasta de trabalho e após já pode começar a trabalhar nos fontes.
Pode-se utilizar a linha de comando. Segue um exemplo abaixo:
svn checkout https://pc01/svn/poligestor d:\Projetos\PoliGestor
Comitando as alterações no Repositório
Após qualquer alteração nos fontes do projeto, pode-ser, através da opção SVN Commit, comitar as alterações realizadas no repositório.
Atualizando a pasta de trabalho
Em uma equipe de desenvolvimento vários desenvolvedores estão trabalhando em um mesmo projeto. Para sincronizar a pasta de trabalho com o servidor faz-se um update através do TortoseSVN. A opção utiliada é SVN Update no menu.
Conclusão
O gerenciamento de projeto com SVN torna-se uma necessidade cada vez maior em projetos atuais, pois elimina quande parte da complexidade do gerenciamento e facilita o compartilhamento dos fontes. Espero que com este artigo poder ter ajudo a vários que já tiveram a idéia de implantar um SVN para uma equipe de desenvolvedores e não encontraram material que torna-se fácil esta tarefa.
quarta-feira, 6 de janeiro de 2010
Exemplo de Programa em JAVA usando JDBC para conectar ao ORACLE
O programa abaixo, demonstra os passos necessários para fazer conexão usando JDBC ao ORACLE.
import java.sql.*; /* * Programa ConexaoOracle.java * * Demonstrar a utilização do driver JDBC para conexão ao ORACLE * * Data: 06/01/2010 * Autor: Everton de Vargas Agilar * * Para executar este programa execute o seguinte no prompt de comando: * java -classpath "c:\Arquivos de programas\java\jdk1.7.0\jdbc\ojdbc6.jar"; ConexaoOracle * * Obs.: a opção -classpath informa o caminho do driver JDBC para o ORACLE. * * Biblioteca Necessária: Driver JDBC para Oracle * http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/ * */ public class ConexaoOracle { public static void main(String[] args) { System.out.println("Conexão Oracle"); Connection conn = null; Statement smnt = null; ResultSet rs = null; String sql = null; try { Class.forName("oracle.jdbc.OracleDriver"); } catch (ClassNotFoundException e) { System.out.println("Driver para ORACLE não encontrado!\nErro interno: "); e.printStackTrace(); } try { conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "gestorerp", "gestorerp"); } catch (SQLException e) { System.out.println("Erro ao obter conexão ao banco de dados XE\nErro interno: "); e.printStackTrace(); } System.out.println("Conexão bem sucedida!"); try { smnt = conn.createStatement(); } catch (SQLException e) { System.out.println("Erro ao criar instrução SQL\nErro interno: "); e.printStackTrace(); } sql = "select * from sequence"; try { rs = smnt.executeQuery(sql); while (rs.next()){ System.out.println("SEQ_NAME "+ rs.getString("SEQ_NAME")); } } catch (SQLException e) { System.out.println("Ocorreu erro ao executar sql!\nErro interno: "); e.printStackTrace(); } try { conn.close(); } catch (SQLException e) { System.out.println("Ocorreu erro ao terminar a conexão ao banco de dados!\nErro interno: "); e.printStackTrace(); } System.out.println("FIM..."); } }
Dor de cabeça com -classpath com apenas 1 biblioteca
Hoje me deparei com uma situação interessante que pode ser uma dor de cabeça para quem está informando as bibliotecas na opção de linha de comando -classpath ou -cp da máquina virtual Java.
Acontece que precisei informar apenas uma biblioteca para meu aplicativo e o seguinte erro estava ocorrendo: Error: Could not find main class MeuAplicativo
Percebi que ao informar um ; no final da string dos caminhos o erro não acontecia. Veja abaixo as linhas de comando com erro e sem erro:
- Este comando não executa:
C:\>java -classpath "c:\Arquivos de programas\java\jdk1.7.0\jdbc\ojdbc6.jar" MeuAplicativo Error: Could not find main class MeuaAplicativo Exception in thread "main" java.lang.NoClassDefFoundError: MeuaAplicativo at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:198) Caused by: java.lang.ClassNotFoundException: MeuaAplicativo at java.net.URLClassLoader$1.run(URLClassLoader.java:299) at java.net.URLClassLoader$1.run(URLClassLoader.java:288) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:287) at java.lang.ClassLoader.loadClass(ClassLoader.java:422) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:325) at java.lang.ClassLoader.loadClass(ClassLoader.java:355) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:195)
C:\>java -classpath "c:\Arquivos de programas\java\jdk1.7.0\jdbc\ojdbc6.jar"; MeuAplicativo
C:\>java -classpath "c:\Arquivos de programas\java\jdk1.7.0\jdbc\ojdbc6.jar";. MeuAplicativo
Ainda bem que logo ao tentar executar o comando pela segunda vez coloquei o ";". Isso poderia ser uma dor de cabeça sem tamanho, você sabe que a sintaxe do comando está certo mas a máquina virtual não consegue executar o aplicativo. Talvez isso seja o fato do parser do programa java.exe não saber tratar bem o -classpath com apenas uma biblioteca.