Sunday 31 May 2009

JSF 2.0 Criando componentes e usando listeners

Ola Pessoal,
hoje vou deixar o exemplo completo. Vou tentar colocar isso meio que formatado aqui, mas esse site nao e bom para isso e muito menos para a colocacao de codigos.
O arquivo web.xml ira ser o mesmo do post anterior.
Estrutura do projeto
project -+
+ src--+
| +-+ myjsf2.beans
| +-+ myjsf2.business
|
+ WebContent -+
| +-+ META-INF
| +-+ resources
| +-+ WEB-INF--+
| | + lib
| |-+ view files .xhtml

Agora vamos a classe MyLoginBean.java

package myjsf2.beans;
/*
* MyLoginBean is one bean using annotations and some new features from JSF 2.0
* There are no more the faces-config.xml, everything is made by annotations and
* pages are called via action from XHTML page.
* Tipos de anotacoes para o antigo back bean
* @ManagedBean - Registra a instancia da classe como um managed bean e coloca isso no escopo especificado
* @ManagedProperty - Seta a propriedade do managed bean. A anotacao precisa ser colocada antes da declaracao
* das variaveis membros da classe.
* @ApplicationScoped -
* @SessionScoped -
* @RequestScoped -
* @ViewScoped - Todas estas e como a tag que fala qual o escopo de cada...
* @NoneScoped - Sem escopo
* @CustomScoped - Armazena o managed bean em um custon escopo.
*
*/
import java.io.Serializable;
import java.util.ArrayList;
import javax.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.component.UISelectItems;
import myjsf2.business.CheckLogin;

@ManagedBean(name = "myLogin")
@SessionScoped
public class MyLoginBean implements Serializable {
private static final long serialVersionUID = 1L;
private String login;
private String password;
private ArrayList names = CheckLogin.allNames();
private String name;
private UISelectItems nameItem;

// ---- gets and sets from login
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}

// ---- gets and sets from password
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

// ---- gets and sets from name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


// ---- get all names from name
public ArrayList getNames() {
return names;
}
public void setNames(ArrayList names) {
this.names = names;
}


// ---- get and sets for UISelectItems
public UISelectItems getNameItem() {
return nameItem;
}
public void setNameItem(UISelectItems nameItem) {
this.nameItem = nameItem;
}


// ---- Cancel datas from inputTexts
public String cancel() {
login = "";
password = "";
name = "";
return "home";
}

// ---- Check if the login is valid or not
public String check() {
if (CheckLogin.checking(login, password)) {
return "final";
}
return "home";
}
}

Voces poderao perceber aqui que nao mudou muita coisa do JSF 1.2, mas voce poderia colocar o bean ou o objeto em vez do ArrayList que coloquei aqui. O ArrayList foi usado pois nao criei uma conexao a algum banco de dados, ussei um array em vez disso. E isso ja e uma boa diferenca. Temos tambem um componente UI que nessa e uma UISelectItems. Que sera usada para se 'pegar' o valor da view, que e um facelet e nao mais JSP, para portar diretamente para a variavel de instancia name, via gets e sets.
Agora vamos a classe que em um projeto poderia ser o DAO ou um EJB fazendo um lookup ou ainda mesmo uma chamada a um servico. Ela so esta aqui para que tenhamos alguns dados e algum check de login, na primeira parte, pois a segunda que sera o componente nao e testada. Eu fiz isso para que voce tenha uma boa ideia, com varias coisas juntas e depois seria so separar o que voce precisa.
A classe CheckLogin.java
package myjsf2.business;
import java.util.ArrayList;

public class CheckLogin {
public static boolean checking(String user, String password) {
if ((user.endsWith("admin")) && (password.equals("admin"))) {
return true;
}
return false;
}

public static ArrayList allNames() {
ArrayList names = new ArrayList();
names.add("Klaus");
names.add("admin");
names.add("Number1");
names.add("Number2");
names.add("Number3");
return names;
}
}

Como voces podem ver o primeiro metodo ira fazer um teste para direcionar para uma pagina se 'logado' e o segundo e um array que poderia ser um list, bean ou qualquer outro objeto.
A classe LoginActionListener.java
package myjsf2.business;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;

@ManagedBean(name="loginActionListener")
@SessionScoped
public class LoginActionListener implements ActionListener {
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent source = event.getComponent();
ValueHolder usernamemy, passwordmy;
usernamemy = (ValueHolder) source.findComponent("usernameid");
passwordmy = (ValueHolder) source.findComponent("passwordid");
String message = "Login event happned userid : " + usernamemy.getValue() +
" password:" + passwordmy.getValue();
System.out.println(message);
context.getExternalContext().getRequestMap().put("loginActionMessage", message);
}
}

Essa classe ira pegar os dados do componente e disponibiliza-lo no contexto do JSF. Voce esta vendo uma classe nova aqui que e a ValueHolder, ela e que 'pega' o valor usando o id da tag e passa ele, nesse caso, para uma String, o que tambem poderia ser para um Integer ou qualquer outro tipo que voce queira, inlcusive primirivos. O resto sao comandos que ja existem e sao utilizados na versao 1.2 .
Agora voces devem estar se perguntando, para que ser a pasta resource dentro da WebContent, ela e onde voce ira guardar os recursos que serao usados no projeto, podem ser os arquivos CSS, JavaScript, componentes e ou imagens, no nosso caso aqui ira ser um componente.
Ele esta dentro de resources -> mycomponents
O componente loginPanel.xhtml

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite" >
< h:head >
< meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" / >
< title >This will not be present in rendered output< / title >
< / h:head>

< h:body >
< composite:interface >
< composite:valueHolder name="usernameid" / >
< composite:valueHolder name="passwordid" / >
< / composite:interface >

< composite:implementatio >
< br / >
< b >This is the composite component.< / b >
< br / >
< table >
< tr >
< td >Username: < h:inputText id="usernameid" / > < / td >
< / tr >
< tr >
< td >Password: < h:inputSecret id="passwordid" / >< / td >
< / tr >
< tr >
< td >< h:commandButton value="Login" id="loginEvent" actionListener="#{loginActionListener.processAction}" / >< / td >
< / tr >
< / table >
< / composite:implementation >

< / h:body >
< / html >

Este aquivo ira ser o componente que voce ira adicionar dentro da view principal que no nosso caso aqui e a home.xhtml e que voce poderea usar ele em varias outras views
Agora voce ira ver o arquivo home.xml
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:mc="http://java.sun.com/jsf/composite/mycomponents" >

< h:head >
< meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" / >
< title>J S F 2 . 0 - Tests< / title >
< style type="text/css" >
.grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9; }
< / style>
< / h:head>

< h:body >
< ui:debug hotkey="p" rendered="true" / >

< h:form id="home" >
< h:outputScript name="jsf.js" library="javax.faces" target="head" / >
< h:outputStylesheet name="stylesheet.css" / >

< b >
< h:outputText id="zerotext" value="JSF 2.0 Login" / >
< / b >
< br / >
< br / >


< h:outputText id="onetext" value="Login :" / >
< h:inputText id="oneinput" value="#{myLogin.login}" / >
< br / >

< h:outputText id="twotext" value="Password :" / >
< h:inputText id="twoinput" value="#{myLogin.password}" / >
< br / >
< br / >

< h:selectOneMenu id="oneselect" value="#{myLogin.login}" onchange="submit();" >
< f:selectItems id="oneselectItems" value="#{myLogin.names}" binding="#{myLogin.nameItem}" / >
< / h:selectOneMenu >

< br / >
< h:outputText id="threetext" value="#{myLogin.name}" / >
< br / >

< h:commandButton id="validate" value="Login" action="#{myLogin.check()}" / >
< h:commandButton id="cancel" value="Cancel" action="#{myLogin.cancel()}" / >

< br / >

< !-- From here is the part that contain the component example -- >
< div id="compositeComponent" class="grayBox" style="border: lpx solid #090;" >

< mc:loginPanel >
< f:actionListener for="loginEvent" type="myjsf2.business.LoginActionListener" / >
< / mc:loginPanel >

< / div >

< h:commandButton value="reload" / >
< h:outputText value="#{loginActionMessage}" / >

< !-- End of my component -- >

< / h:form >

< / h:body >
< / html >

Voce pode notar que ate o comentario < !-- From here is the part that contain the component example -- >, a view e a mesma do exemplo anterior com somente um SelectOneMenu a mais.
Que foi colocado aqui para que voce veja o funcionamento dos componentes JSF 2.0 usando facelets.
Os arquivos index.xhtml e fina.xhtml sao exatamente os mesmos do ultimo exemplo postado.
Como voces podem ver nao ha muito o que explicar, pois e muito simples o uso dos listeners, criacao de componentes e inclusao deles em outra pagina, uma coisa que nao era facil
com a versao anterior. Tambem deve ter percebido a ausencia do faces-config.xml, agora e tudo feito via anotacoes e o direcionamento para paginas esta dentro da view.
Espero que com isso voces tenham uma boa ideia do que vem vindo por ae com o Java2 SE 7 e o EE 6.
O que posso adiantar tambem para voces e que o uso de microcontainer do EJB3.1 e muito poderoso e pratico, com ele tambem nao existe mais a necessiade de se criar interfaces
locais e remotas, e tudo feito via anotacoes. O validator usado e o do Hibernate que por sinal e muito poderoso e facil de usar. Ainda no EE temos o web beans que fara a tarefa
de trabalhar com EJB muito mais facil e devera tambem ser o core da proxima versao do Seam. Que hoje e um dos frameworks mais utlizados, tendo ja suplantado os sistemas com Struts.
Bom com isso encerro a visao do JSF 2.0 . Eu tinha falado que iria postar um exemplo usando AJAX, mas como a padronizacao ainda nao esta 100% e podendo mudar muito ainda, fora que
RichFaces e IceFaces ainda nao sao 100% compativeis com facelets e o novo JSF engine. Achei melhor deixar isso para depois
Qualquer duvida que voces tiverem podem me escrever, o email esta no post anterior.
Se voce tiver alguma duvida a mais tem um blog da sun que possue varios exemplos de JSF 2.0 que por sinal e muito bom e o Jim Driscoll's Blog .
Boa sorte.

Monday 25 May 2009

Um exemplo com JSF 2.0

Ola mais uma vez pessoal....
Aqui vai um exemplo em JSF 2.0, devido a impossibilidade de eu colocar o codigo para voces fazerem download, vou ter que colocar classe a classe aqui.
Antes de mais nada, para voces criarem com o plugin que passei para voces no post anterior, o plugin nao tem a opcao para criar .xhtml, portanto vc cria uma pagina .html e depois renomeia ela para .xhtml, isso deve facilitar as coisas.
Este exemplo nao usa nada de AJAX ainda, e so JSF 2.0 puro, somente para voces terem uma ideia geral... de como ele se porta. Claro que ha muito mais coisas para se mostar, mas essa e a primeira visao para voces.
Primeiro o Bean : MyLoginBean.java
package myjsf2.beans;

/*
* MyLoginBean is one bean using annotations and some new features from JSF 2.0
* There are no more the faces-config.xml, everything is made by annotations and
* pages are called via action from XHTML page.
* Tipos de anotacoes para o antigo back bean
* @ManagedBean - Registra a instancia da classe como um managed bean e coloca isso no escopo especificado
* @ManagedProperty - Seta a propriedade do managed bean. A anotacao precisa ser colocada antes da declaracao
* das variaveis membros da classe.
* @ApplicationScoped -
* @SessionScoped -
* @RequestScoped -
* @ViewScoped - Todas estas e como a tag que fala qual o escopo de cada...
* @NoneScoped - Sem escopo
* @CustomScoped - Armazena o managed bean em um custon escopo.
*
*/
import java.io.Serializable;
import javax.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import myjsf2.business.CheckLogin;

@ManagedBean(name = "myLogin")
@SessionScoped
public class MyLoginBean implements Serializable {
private static final long serialVersionUID = 1L;
private String login;
private String password;

// ---- gets and sets from login
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}

// ---- gets and sets from password
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

public String cancel() {
login = "";
password = "";
return "home";
}

public String check() {
if (CheckLogin.checking(login, password)) {
return "final";
}
return "home";
}
}

Agora a segunda classe que e bem boba, somente para voces terem uma ideia da simplicidade do JSF 2.0, que poderia ser uma DAO ou que fizesse coisa similar.
Classe : CheckLogin.java
package myjsf2.business;

public class CheckLogin {
public static boolean checking(String user, String password) {
if ((user.endsWith("admin")) && (password.equals("admin"))) {
return true;
}
return false;
}
}


O arquivo : web.xml
< ?xml version="1.0" encoding="UTF-8"? >
< xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<>myjsf2
<>
<>index.html< / welcome-file >
<>index.htm< / welcome-file >
<>index.jsp< / welcome-file >
<>default.html< / welcome-file >
<>default.htm< / welcome-file >
<>default.jsp< / welcome-file >
< / welcome-file-list >
<>
<>Faces Servlet< / servlet-name >
<>javax.faces.webapp.FacesServlet< / servlet-class >
<>1< / load-on-startup >
< / servlet >
<>
<>Faces Servlet< / servlet-name >
<>/faces/*< / url-pattern >
< / servlet-mapping >
<>

<>Faces Servlet< / servlet-name >
<>*.jsf< / url-pattern >
< / servlet-mapping >
< / web-app >

Agora as tres paginas, que se chamam index.html que e a principal a de welcome, que e chamada automaticamente, depois a home.xhtml que possui o login em si e a final.xhtml que lhe dira se foi efetuado com sucesso ou nao, eu coloquei todas as escritas em ingles, pois como vou demonstrar esse codigo para um pessoal que usa JSF 1.2, ficara mais facil para mim do que ter que ficar mudando tudo novamente.
View : index.xhtml
<>
<>
< equiv="Content-Type" content="text/html; charset=UTF-8">
<>GlassFish PROMOTED v3< / title >
< / head >
<>
<>Directing to JSF 2.0 page...< / h1 >
< equiv="Refresh" content="0;url=home.jsf">
< / body >
< / html >

View : home.xhtml
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< xmlns="http://www.w3.org/1999/xhtml" h="http://java.sun.com/jsf/html">

<>
< equiv="Content-Type" content="text/html; charset=iso-8859-1">
<>Insert title here< / title >
< / h:head >

<>
< id="home" prependid="false">
< name="jsf.js" library="javax.faces" target="head">
< name="stylesheet.css">
< id="zerotext" value="JSF 2.0 Login">
<>
< id="onetext" value="Login :">
< id="oneinput" value="#{myLogin.login}">
<>
< id="twotext" value="Password :">
< id="twoinput" value="#{myLogin.password}">
<>
< id="validate" value="Login" action="#{myLogin.check()}">
< id="cancel" value="Cancel" action="#{myLogin.cancel()}">
< / h:form >
< / h:body >
< / html >

View : final.xhtml
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<>
< equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<>Succesful validate.< / title >
< / head >
<>
<>Succesful validate.< / h1 >
< / body >
< / html >

Com isso voce tem um mini projeto em JSF 2.0 para vc comecar a fucar, o que realmente indico e baixar o source dele do link MOJARRA 2.0
La voce pode baixar as ultimas atualizacoes para ver como esta ficando. O que acho bem valido, visto que as novas versoes devem sair ate o fim do ano.... SE 7 e EE 6!!!
Como voces podem ver tambem, nao existe mais .xml a nao ser o web descriptor (web.xml) mais nada.
Quanto ao codigo me desculpem mas esse blogger nao e muito bom para se colocar codigos entao nas views eu tive que incluir espacos em cada tag no comeco e no final para poder postar, portanto se vc quizer dar um copy/paste nao pode esquecer de tirar estes espacos.
Bom e isso ae se nao conseguirem fazer funcionar podem mandar post ou um email para klaus_villaca@gmail.com
Abracos e ate semana que vem qdo vou postar um com AJAX integrado...

Friday 22 May 2009

JSF 2.0 preparando o ambiente...

Ola pessoal,
Pelo que puder ler e estou testando agora, o JSF 2.0 ira ser muito bom mesmo, devera ser uns 70% melhor do que o 1.2, aqui vou passar algumas dicas para voce fazer os downloads certos e preparar o ambiente para desenvolver usando o JSF 2.
Tem muitas coisas que mudaram, e para melhor.
O primeiro passo e baixar o Eclipse com o plugin para o GalsFish, voce pode encontrar ele em : https://glassfishplugins.dev.java.net/ depois desca a pagina e va onde esta entitulado "GlassFish Support in Eclipse IDE (Eclipse 3.4 - Ganymede)", la voce ira encontrar um botao com o simbolo do GlassFish e escrito "Download NOW", e so clicar e fazer o download, se voce prestar a atencao voce ira ver que o download pode ser feito com ou sem o JDK 1.6, o ideal e voce faer direto o completo, e quase 100Mg maior mas e bom pq tudo ja esta integrado. Que na verdade isso e um bundle com Eclipse 3.4, JDK 1.6 e GlassFish app server v2 e v3 incluido.
Apos isso rode o arquivo e voce pode aceitar todas as opcoes pre-definidas... o famoso "Next" .
Quanto tudo estiver instalado e voce ja tiver ajustado suas configuracoes no Windows-> Preferences, voce pode comecar com : File -> New -> New Dynamic Web Project que ira trazer o Wizard para criar um novo projeto web.
Voce pode colocar o nome do projeto, escolha um ae, eu usei Myjsf2test
Depois em Target Runtime voce clica no botao do lado direito que esta escrito New , e depois na nova janela que esta escrito New Server Runtime Environment, voce ira escolher a opcao que tiver escrito GlassFish v3 PROMOTED e clicar no box que esta escrito Create a new local server e clicar no botao Next, ira abrir uma nova janela sobre aquela, onde estara escrito New Server Runtime Environment tambem, nessa janela voce ira ver a JRE que voce esta usando e um campo escrito Application Server Directory, clique no botao do lado direito escrito Browse , e escolha o diretorio onde ira ser intalado o GlassFish v3 PROMOTED BUILD. Voce escolhe um e clique em Install Server que esta logo abaixo. Assim que voce clicar no botao Install Server o plugin ira comecar a fazer o download da versao PROMOTED do GlassFish para o diretorio escolhido. Terminando o download o botao Next ira estar habilitado novamente e e so clicar nele, e depois Finish e Finish. E pronto seu ambiente ja esta configurado para usar o JSF 2.0.
Para comecar e so deletar o index.jsp e comecar a colocar o .XHTMLs.
Agora so algumas coisas que comecando a testar pude perceber, primeiro nao existe mais o faces-config.xml , ira ser tudo feito atravez de anotacoes, o que e muito bacana e rapido, depois voce ira notar que nao se usam mais .jsp our .jsf, ira ser tudo .xhtml usando facelets com jsf tags.
A criacao de componentes tambem esta bem mais simplificada e trabalhar com AJAX tambem e o controle, ou as chamadas das proximas paginas sao feitas agora diretamente da action dentro da tag do .xhtml, que irei mostrar mais adiante. Os proximos posts irao conter um exemplo bem simples de um aplicacao com JSF 2.0, simples e depois uma com AJAX.
So para voce que gosta de estar no cut the edge... Essa versao do GlassFish v3 Prelude, tem um update automatico, que o ideal e voce entrar na IDE, e levantar o servidor. Depois va no diretorio que voce intalou ele e procure por \glassfishv3-prelude ( o meu esta em C:\klaus\GlassFish-Tools-Bundle-For-Eclipse-1.0\glassfishv3-prelude) dentro deste diretorio tem uma pasta bin e dentro dela tem o arquivo updatetool.bat, rode ele e coloque 'y' quando perguntado se quer intalar o update tool. Ele ira baixar os arquivos da internet para instalar o update tool em sua maquina. Apos isso feito e so rodar ele, pois la ira conter um aquivo chamado "updatetool.exe"
Assim que ele rodar, voce pode instalar as atualizacoes que existem e va em "Available add ons"
Escolha glassfish-ejb, eu escolhi todos para nao ter duvidas, assim que acabar o download voce tera que fazer o bounce do app-server (desligar e ligar novamente). E pronto... voce tambem ja tem o EJB 3.1 com o light container e tudo mais, e so comecar a testar, mas primeiro aqui vou postar sobre o JSF 2 com e sem AJAX, e depois do EJB 3.1, que e muito interessante mesmo.
Sei que ainda estou devendo sobre o SEAM, mas e que como tive em outros projetos eu dei uma parada de ver ele, mas estou voltando, portanto aguardem que ira vir muito mais coisas por ae como tambem WS com ESB e mais...

Wednesday 20 May 2009

Cuidados usando Oracle ou PL/SQL, clients

Agora vou falar dos problemas que tive usando alguns Oracle clients, mas de longe o mais problematico foi o TOAD. Comecando pelo client fornecido pela propria Oracle, nao vale a pena usar, se tiver so ele desista, abra o DOS e use o sqlplus, e uma ferramenta que trava muito e com muito poucos recursos. Pior quando ela trava se voce nao salvou o conteudo, esqueca... acho que nem deveria vir no pacote uma ferramenta dessa.
TOAD, muito bom para selects simples, updates mas nada muito mais complicado, inclusive quando voce seta para enable o output, para fazer um debug, ele demora um tempo , que nao me perguntem o pq para comecar a mostrar as saidas para o console. Isso quando ele mostra, pois na maior parte do tempo ele nao mostrava nada e nao aparece nenhuma mensagem de erro nem nada. Mas o que mais sofri e com a demora deste client em atualizar os dados com o Oracle em si. Ele deve ter algum cache que quando voce lida com grandes qtdes. de dados perde o sincronismo. Pois cheguei a ter um script perfeito acusando erro nele, pq este deveria ter carregado uma versao antiga no cache e nao estava atualizando com a nova que inclusive estava salva ja, e quando fui rodar o mesmo script no sqlplus rodou perfeitamente. Agora o mais engracado e que apos rodar os scripts no sqlplus, e atualizar duas tabelas, eu ia para o TOAD e rodava um select e advinha !!! Nada de ver os dados atualizados, mas se vc rodasse o mesmo select pelo sqlplus esta tudo ok. Agora se vc saisse do TOAD e depois esperasse uns segundos para limpar todos os caches dele e carregasse ele de novo, ele rodava bem somente por muito pouco tempo. As travadas que ele da do nada eram um caso a parte, tinha horas que eu achava que ele estava trabalhando para trazer os registros e estava travado, falta alguma coisa que mostre o que ele ta fazendo ou o que ele ta lendo de fato. E uma ferramenta que nao recomendo. Se voce leu esse post e nao gostou pq e fa do TOAD, me desculpe, mas usando scripts grandes mais complexos e varios carregados ao mesmo tempo, ele vai travar.
A melhor opcao e ou usar o Squirrel que e um client feito em java e muito mais maduro em certas partes do que as duas ultimas solucoes, ou abrir o notepad e usar ele mesmo com o sqlplus que e garantia de nao haver problemas, a nao ser que vc codifique errado. Porem e a mais lenta opcao de todas.
A maquina que usei era um Intel Duo de 3Ghz com 3Gb ram, uma GForce 7 (nao lembro exata a versao dela) 512mb, e um HD fujitisu de 7.200rpm de 300Gb e dois monitores de 19". Como voces podem ver nao era qualquer maquina.
Portanto se voce tiver que realmente usar um client para criar e editar longos scripts em PL/SQL e nao quizer nenhuma dessas duas opcoes que passei aqui, procure outras pois ha varias no mercado e ate de graca. Mas estou revoltado com a perca de tempo que tive usando o TOAD, pela quantidade de problemas que enfrentei sem causa aparente. Agora se voce usa para coisas simples e nada com grande concorrencia de acesso a sua base de dados ele e uma boa pedida.
Deixei esse desabafo aqui, pois em servico que eu deveria ter perdido 1,5 dia para realizar, com essa ultima ferramenta que ainda por cima e paga, eu perdi 3,5 dias. Por conta de travadas inexplicaveis, cache que nao atualiza e acusa de erro em codigo que esta 100% certo, o que me rendia horas relendo e repensando se o codigo estava mesmo errado, ate que tive uma luz que ele poderia estar com problemas. Mas o problema e do software mesmo, pois eu o removi e reinstalei umas cinco vezes.
Bom e isso ae, espero que com isso eu tenha lhe poupado um monte de dores de cabeca. Mas veja bem estou falando para trabalho em ambientes de pre-producao/producao ou de grandes scripts. Coisas simples ele e muito bom.

Tuesday 19 May 2009

Usando PL/SQL para ler uma tabela e atualizar outra

Ola pessoal, a algum tempo que ja nao posto nada aqui, mas e por varios motivos, o principal e minha mudanca para a Australia.
Mas vamos la, semana passada eu passei por uma migracao de dados pegando um arquivo .xls do Excel e transformando ele para .csv, que e um arquivo delimitado por virgulas, para entao usando o SQL Loader do Oracle importar esses campos para uma tabela Oracle e entao ler esta, comparando os dados com outra e atualizando esta e se os dados nao batessem, ou seja nao existissem nessa tabela, salvar em uma outra tabela. Claro que nesse site nao e possivel colocar todas as indentacoes.
Aqui esta um exemplo, que e muito util, e usando Oracle Cursor, pois procurei muito isso na net e so consegui achar em livros especificos.

O codigo :

set serveroutput on
declare
v_voipFlag varchar2(20);
v_xtype number(1);
v_serviceType varchar2(100);
v_serviceTypeId number(22);
v_de varchar2(20);
v_para varchar2(20);
v_data_de_aceitacao date;
v_cliente_Id number(22);
v_area_Id number(22);
v_achado number(10);
v_conta number(10);
cursor updateapp is
select migra_tabela.VOIP_FLAG, migra_tabela.service_type, migra_tabela.de_NUM, migra_tabela.TO_NUM,
migra_tabela.acceptance_date, migra_tabela.numb_client_id, migra_tabela.area_type_id
de migra_tabela
order by migra_tabela.de_NUM;
begin
dbms_output.enable;
open updateapp;
loop
fetch updateapp into v_voipFlag, v_serviceType ,v_de, v_para, v_data_de_aceitacao, v_cliente_Id, v_area_Id;

v_achado := 0;
v_voipFlag := upper(trim(v_voipFlag));

if (v_voipFlag <> 'NAO') or
(v_voipFlag <> 'SIM') then v_xtype := 9;
end if;

if (v_voipFlag = 'NAO') then v_xtype := 0;
end if;
if (v_voipFlag = 'SIM') then v_xtype := 1;
end if;

-- Look for one value
select count(low_number) into v_achado de aplicacao
where (v_de = aplicacao.LOW_NUMBER
and v_para = aplicacao.HIGH_NUMBER
and v_data_de_aceitacao = to_char(aplicacao.ACCEPTANCE_DATE,'DD-Mon-YY')
and aplicacao.APPLICATION_STATE_ID = 6);

-- Look for one value
dbms_output.put_line('v_achado' || v_achado);

if (v_achado < de_num =" v_de" to_num =" v_para" numb_client_id =" v_cliente_Id" area_type_id =" v_area_Idand" acceptance_date =" v_data_de_aceitacao);" voip_flag =" v_xtype" v_de =" aplicacao.LOW_NUMBER" v_para =" aplicacao.HIGH_NUMBER" v_data_de_aceitacao =" to_char(aplicacao.ACCEPTANCE_DATE,'DD-Mon-YY')"> 9);
commit;
exit when updateapp%NOTFOUND;
end loop;
close updateapp;
end;


O codigo e um pouco grande, mas ele percorre toda a tabela de migra_tabela comparando com da aplicacao, se achar na aplicacao ele atualiza, se nao achar ele procura na tabela nao_bate, se achar algum registro que satisfaca as condicoes ele atualiza senao ele cria um novo.
E simple porem muito poderoso.
Eu usei um muito parecido para uma migracao de dados em producao, e rodaram com perfeicao, claro que eram outros dados e outras condicoes, mas o esqueleto esta ai, e so copiar dar uma estudada no codigo e maos a obra.
So mais uma coisa... prestem bem atencao pois como nesse blog nao foi possivel colocar o sinal correto. Para se atribuir um valor voce usa := (dois pontos e igual sem espacos no meio).