sábado, 23 de maio de 2009

Cursor with parameters in PL/SQL

Ver este post em Portugûes

Here I'm gonna show another technique to work with cursors in PL/SQL. I had to do something at work where it was very useful: cursor that take arguments.

The biggest advantages of parametrized queries is that the server doesn't have to pass through the parse and plan phases ever again (after the first time, of course) and the compile-time checking for syntax errors (when we use string queries we only know any syntax errors in runtime).

That said let's go to examples:


cursor ProductCursor(pname in varchar2) is
select *
from product
where name like pname;


Nice, isn't it? It's like a procedure in terms of syntax. And opening the cursor is like this:


open ProductCursor('A%');


It'll open the cursor with all the products which name starts with 'A'.

We can create a rowtype based var from this cursor:


prod ProductCursor%rowtype;


Now I'm gonna join it all in a script:


declare
-- Cursor
cursor ProductCursor(pname in varchar2) is
select *
from product
where name like pname;

-- Simple loop
prod ProductCursor%rowtype;

-- bulk collect loop
type Tprods is table of ProductCursor%rowtype;
prods Tprods;
i integer;

begin
-- simple loop
open ProductCursor('A%');
loop
fetch ProductCursor into prod;
exit when ProductCursor%notfound;
DBMS_OUTPUT.put_line(prod.nome);
-- other commands
end loop;
close ProductCursor;

-- bulk collect loop
open ProductCursor('A%');
fetch ProductCursor bulk collect into prods;
for i in prods.first .. prods.last loop
DBMS_OUTPUT.put_line(prods(i).nome);
-- another commands using prods(i)
end loop;
close ProductCursor;
end;


Cool, isn't it? See you next time.

Artigo completo (View Full Post)

Cursor com parâmetros em PL/SQL

View this post in English

Aqui vou mostrar outra técnica para trabalhar com cursores em PL/SQL. Eu tive que fazer um trabalho recentemente onde isso foi muito útil: Cursores que aceitam argumentos.

As maiores vantagem de usar queries parametrizadas no banco de dados é que o servidor não precisa fazer o parse e traçar um plano de execução (ele só faz isso na primeira vez que a query é executada) e ela fica certa em tempo de compilação (ao contrário das queries em string que nós só sabemos se há um erro de sintaxe em tempo de execução).

Dito isso vamos a um exemplo:


cursor ProdutoCursor(pnome in varchar2) is
select *
from produto
where nome like pnome;


Legal, não? A sintaxe fica muito parecida com uma procedure. E o método de abrir o cursor também é legal:


open ProdutoCursor('A%');


Aqui vai abrir o cursor trazendo todos os produtos onde o nome começa com a letra 'A'.

Podemos ainda criar um rowtype a partir deste cursor:


prod ProdutoCursor%rowtype;


Agora vou criar um script para juntar tudo:


declare
-- Cursor
cursor ProdutoCursor(pnome in varchar2) is
select *
from produto
where nome like pnome;

-- Para loop simples
prod ProdutoCursor%rowtype;

-- Para loop com bulk collect
type Tprods is table of ProdutoCursor%rowtype;
prods Tprods;
i integer;

begin
-- Loop simples
open ProdutoCursor('A%');
loop
fetch ProdutoCursor into prod;
exit when ProdutoCursor%notfound;
-- comandos a serem executados com o registro prod
DBMS_OUTPUT.put_line(prod.nome);
end loop;
close ProdutoCursor;

-- Loop com bulk collect
open ProdutoCursor('A%');
fetch ProdutoCursor bulk collect into prods;
for i in prods.first .. prods.last loop
-- comandos a serem executaos com o registro prods(i)
DBMS_OUTPUT.put_line(prods(i).nome);
end loop;
close ProdutoCursor;
end;


Muito legal, né? Até a próxima.

Artigo completo (View Full Post)

Generics - A great addition to .Net

Ver este post em Portugûes

Hello. In this post I'll show something very nice about .Net: Generics.

First, I'll show a simple struct in order to explain the feature:


struct Person {
public string Name;
public string Address;
public string Zip;
}


We have here a classic example of a data struct. Here we define fields with their respective data types (we're talking here about a strongly typed language). That means we have to provide the data type of the attributes at compile time. But, what if we could let the (struct's) user define what type s/he wants to use in their struct? How so? e.g.: A struct, two fields and their data type is open to the user to specify and set the attribute, making it "appear" a weakly typed language, but with the advantage of type checking at compile time.

Let's take a look at an example:


struct Pair<TClass1, TClass2>
where TClass1 : class
where TClass2 : class {

public TClass1 obj1;
public TClass2 obj2;
}


Here comes the generics: We define a struct, asking the user to provide which clases will will represent the TClass1 and TClass2, which we are defining that have to inherit the class object and it automatically defines what data type that fields inside will accept

The nice part is when we start to use this structure. Let's see another code block:


class Customer {
public int ID;
public string Name;

public override string ToString() {
return string.Format("Customer ID = {0}, Name = {1}", ID, Name);
}
}

class Product {
public int ID;
public string Name;

public override string ToString() {
return string.Format("Product ID = {0}, Name = {1}", ID, Name);
}
}

struct Pair<TClass1, TClass2>
where TClass1 : class
where TClass2 : class {

public TClass1 obj1;
public TClass2 obj2;
}

class Program {
static void Main(string[] args) {

var c = new Customer { ID = 1, Name = "Felipe" };
var p = new Product { ID = 1, Name = "Caneta BIC" };

var pair = new Pair<Customer, Product>() { obj1 = c, obj2 = p };

Console.WriteLine(pair.obj1.ToString());
Console.WriteLine(pair.obj2.ToString());

}
}


The braces after the new instanct are a new notation of C# that allows us to create new instances of classes and set values to public fields in the same instruction.

In the progem we create instances of Customer and Product and define these types as the relevant types for the struct Pair. Note that, after we define the struct with these types we can only inform instances of these types for the specific fields. The compiler doens't let us inform any other value; and even the IntelliSense indicates correctly.

I hope you all liked this post and again, sorry for my english, as I am no native English speaker. Thank you very much and see you next time.

Artigo completo (View Full Post)

Generics - Uma Grande adição a .Net

View this post in English

Olá a todos. Neste post vou mostrar algo muito legal a respeito da .Net: Generics.

Primeiro vou preparar o terreno para explicar o recurso: Vamos ter como exemplo uma estrutura básica:



struct Pessoa {
public string Nome;
public string Endereco;
public string CEP;
}


Nós temos aqui um exemplo clássico de uma estrutura de dados. Nela nós definimos campos com os tipos definidos de dados (claro, numa linguagem fortemente tipada). Isso significa que nós temos que fornecer os tipos de dados na hora em que a criamos. Mas, E se pudéssemos criar uma estrutura de dados onde o usuário (da estrutura, claro) escolha os tipos de dados dos atributos? Como assim? A estrutura possui dois atributos e o usuário diz de que tipo de dados são estes atributos antes de definir seus valores, tendo "aparência" de linguagem de tipagem fraca, mas com a vantagem de checagem de tipos em tempo de compilação.

Nada melhor para explicar do que um exemplo prático:


struct Par<TClasse1, TClasse2>
where TClasse1 : class
where TClasse2 : class {

public TClasse1 obj1;
public TClasse2 obj2;
}


Aqui vem o uso dos genéricos: Definimos uma estrutura, pedido que o usuário forneça dois tipo, TClasse1 e TClasse2, que dizemos abaixo que elas devem ser descendentes de object (ou object) e isso vira uma classe para ser referenciada dentro da struct.

A parte legal vem na hora em que começamos a utilizar esta estrutura. Abaixo tem mais um bloco de código:


class Cliente {
public int ID;
public string Nome;

public override string ToString() {
return string.Format("Cliente ID = {0}, Nome = {1}", ID, Nome);
}
}

class Produto {
public int ID;
public string Nome;

public override string ToString() {
return string.Format("Produto ID = {0}, Nome = {1}", ID, Nome);
}
}

struct Par<TClasse1, TClasse2>
where TClasse1 : class
where TClasse2 : class {

public TClasse1 obj1;
public TClasse2 obj2;
}

class Program {
static void Main(string[] args) {

var c = new Cliente { ID = 1, Nome = "Felipe" };
var p = new Produto { ID = 1, Nome = "Caneta BIC" };

var par = new Par<Cliente, Produto>() { obj1 = c, obj2 = p };

Console.WriteLine(par.obj1.ToString());
Console.WriteLine(par.obj2.ToString());

}
}



As chaves depois da nova instância das classes é uma facilidade do C# que nos permite criar uma nova instância de uma classe e atribuir valores aos membros públicos naquele momento.

Dentro do programa nós criamos instâncias das classes Cliente e Produto e definimos como atributos da nossa estrutura para usarmos depois. O detalhe é que, assim que nós definimos que as classes da estrutura são Cliente e Produto, o compilador não deixa nenhum outro valor; até o IntelliSense indica corretamente.

Espero que que vocês tenham gostado deste post e o assunto tenha despertado em vocês o interesse que despertou em mim. Muito obrigado e até a próxima.

Artigo completo (View Full Post)

Você já isntalou o IE8?

Como o título já diz: eu já. A microsoft colocou o Internet Explorer 8 como atualização crítica para o Windows XP e cá estamos nós usuários deste maravilhoso sistema operacional atualizando.

O navegador é muito bonitinho: A interface é boa, tem depurador de Javascript (já dava para fazer isso anteriormente, mas agora está incorporado no navegador), etc. Mas um problema assola alguns usuários (como minha digníssima que ainda usa muito o Internet Explorer): o teclado.

Alguns usuários têm notado que no IE 8 o teclado não responde legal. Na minhma máquina acontece isso Neste link [forum.clubedohardware.com.br] há uma discussão do problema e possíveis causas e soluções.

Alguns males vêm para bem: Agora minha patroa já está começando a usar o querido por todos Firefox para navegar, graças as minhas insistentes investidas. Ha ha. Aproveitei essa hora para trazê-la ao lado da luz.

Abraços e até a próxima!

Artigo completo (View Full Post)

sexta-feira, 15 de maio de 2009

JclStrings - StrPadRight, StrPadLeft

È uma biblioteca da JCL (Jedi), como o nome da “unit” indica, para trabalhar com strings. Esteja certo de que, tudo e qualquer coisa que você pensar fazer com strings eles implementaram nesta biblioteca.

Caso você, desafortunadamente, precise de alguma função para trabalhar com strings e não encontre na JclStrings, provavelmente é porque você está querendo fazer alguma variação do “BozoSort” (rsrsrs, neste caso procure o Bozo ou o Jaspion). Quem me apresentou a ela foi o Malta, desde então nunca mais me separei dela. A seguir, um exemplo de como concatenar caracteres a esquerda ou a direita de uma string de tamanho limitado. Ou seja, mantendo o tamanho (Length) da string inalterado.


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;

type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

uses jclStrings, Math;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
ZnDt, ZnNum: String;
ADay, AMonth, AYear: Word;
begin

DecodeDate(Date, AYear, AMonth, ADay);
ZnDt := Format('%s%s%s', [ StrPadLeft(IntToStr(ADay), 2, '0'),
StrPadLeft(IntToStr(AMonth), 2, '0'), IntToStr(AYear)]);
Self.Canvas.TextOut(12, 32, ZnDt);

Randomize;
ZnNum := IntToStr(RandomRange(0, 50000));
ZnNum := StrPadRight(ZnNum, 6, 'X');
Self.Canvas.TextOut(12, 52, ZnNum);

end;


Por falar me Bozo, lembrei de uma coisa (rsrsrs)..... Esse exemplo com datas, não foi uma boa idéia!?!?!?!??!?!
Na verdade ... esse exemplo com datas foi ótimo! Para demonstrarmos como não fazer ... uma coisa que provavelmente todo desenvolvedor, em algum momento, vai precisar fazer (rsrsrs).
Por favor, não façam assim (concatenar zeros a direita do dia e do mês).
Por isso, preste a tenção para substituir o código da linha 35 ...

ZnDt := Format('%s%s%s', [ StrPadLeft(IntToStr(ADay), 2, '0'),
StrPadLeft(IntToStr(AMonth), 2, '0'), IntToStr(AYear)]);

Por

ZnDt := Format('%.2d%.2d%.4d', [ADay, AMonth, AYear]);

Bem melhor agora!!!!!!!

Se você veio procurar "StrPadLeft" para trabalhar com datas, se deu bem! Use o "Format('%.2d%.2d%.4d, [ADay, AMonth, AYear])".
O Malta, mais uma vez, nos emprestou o conhecimento dele.
Grato!

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br