SqlCommand e uma propriedade SQL

20 views
Skip to first unread message

Marcos George

unread,
Apr 3, 2009, 7:18:10 AM4/3/09
to Infra - Integrated Frameworks
O SqlCommand deveria ter uma propriedade chamada SQL (como um
TSQLQuery o tem tbm), esta seria usada de duas formas:

1º) para criação direta de sql sem a necessidade de um arquivo ou
outro mecanismo mais complicado:

IResumoContas = interface
property Total: Double read GetTotal;
end;

var
vSqlCommand: ISqlCommandQuery;
vResumo: IResumoContas;
begin
vSqlCommand.SQL.Text := 'select sum(valor) total from contas';
vResumo := vSqlCommand.GetResult as IResumoContas;
end;



2º) Para reter as queries criadas pelo session (no futuro usando o IQL
- Infra Query Language):
vSqlCommand := vSession.CreateQuery('TAccount');
// Aki o vSqlCommand já conteria o SQL gerado automaticamente
vResumo := vSqlCommand.GetResult as IAccount;

Por favor, expressem suas opiniões, para que possamos direcionar
nossos esforços.

Att
Marcos George

Fabricio Colombo

unread,
Apr 3, 2009, 7:46:22 AM4/3/09
to infra...@googlegroups.com

2009/4/3 Marcos George <mgnd...@msn.com>


O SqlCommand deveria ter uma propriedade chamada SQL (como um
TSQLQuery o tem tbm), esta seria usada de duas formas:

1º) para criação direta de sql sem a necessidade de um arquivo ou
outro mecanismo mais complicado:

IResumoContas = interface
 property Total: Double read GetTotal;
end;

var
 vSqlCommand: ISqlCommandQuery;
 vResumo: IResumoContas;
begin
 vSqlCommand.SQL.Text := 'select sum(valor) total from contas';
 vResumo := vSqlCommand.GetResult as IResumoContas;
end;

 
Na minha opnião essa propriedade sql deve existir sim.
Com relação ao exemplo a cima, acredito que temos um problema. Como o Infra vai saber que o select se refere a entidade IResumoContas?
No Hibernate dá pra fazer assim:
 
List result = session.createSQLQuery("select * from CATEGORY").addEntity(Category.class).list();
 
e assim
 
session.createSQLQuery("select {i.*}, {u.*} from ITEM i" +
                       " join USERS u on i.SELLER_ID = u.USER_ID" +
                       " where u.USERNAME = :uname")
                       .addEntity("i", Item.class)
                       .addJoin("u", "i.seller")
                       .setParameter("uname", "johndoe");
 
 
Dessa maneira ele tem como saber quais campos pertencem a quais objetos através das annotations. Poderia ter métodos similares no vSqlCommand.

Marcos Barreto

unread,
Apr 3, 2009, 12:21:54 PM4/3/09
to infra...@googlegroups.com
Este recurso de preencher uma propriedade SQL é valida no sentido de não utilizar um template em arquivo texto. O único chato disso tudo é que vamos ter uma string contendo nomes de campos e tabelas em vez de uma expressao OQL (Já que nao vamos fazer este tipo de coisa agora).

Não discordo de ter uma propriedade SQL no command mas acho que ela poderia ser uma string direta e não um TStrings (minha opinião).

O importante aqui seria pensar no seguinte, vale a pena esta abordagem ou deveriamos esperar pelo OQL e por a string em um arquivo texto (lembre-se que é muito fácil por exemplo criar um xml e um templatereaderxml com todas as instruções e buscar de lá).

Na minha opnião essa propriedade sql deve existir sim.
Com relação ao exemplo a cima, acredito que temos um problema. Como o Infra vai saber que o select se refere a entidade IResumoContas? No Hibernate dá pra fazer assim:
List result = session.createSQLQuery("select * from CATEGORY").addEntity(Category.class).list();
e assim
 
session.createSQLQuery("select {i.*}, {u.*} from ITEM i" +
                       " join USERS u on i.SELLER_ID = u.USER_ID" +
                       " where u.USERNAME = :uname")
                       .addEntity("i", Item.class)
                       .addJoin("u", "i.seller")
                       .setParameter("uname", "johndoe");

Fabricio demostrou bem que este é o tipo de recurso que é mais usado quando temos um analisador de expressoes HQL/OQL.
Para saber qual classe usar, o sqlcommand já possui a propriedade classtypeinfo e pela conversa que tive com MG ontem achamos que deveria ter tambem a propriedade Object (Um infraobject a ser persistido, ou que foi criado e passado no CreateCommandQuery para ser carregado).

Marcos George

unread,
Apr 3, 2009, 12:25:40 PM4/3/09
to infra...@googlegroups.com
Eu penso que SQL não deveria ser nem TStrings nem string, e sim, uma classe especializada, capaz de montar uma instrução usando os "Criterions" (nome bunito! :))

Att
Marcos George



 

Date: Fri, 3 Apr 2009 13:21:54 -0300
Subject: [Infra 685] Re: SqlCommand e uma propriedade SQL
From: mrba...@gmail.com
To: infra...@googlegroups.com

Marcos George

unread,
Apr 3, 2009, 12:41:23 PM4/3/09
to infra...@googlegroups.com
> Não discordo de ter uma propriedade SQL no command mas acho que ela poderia ser uma string direta e não um TStrings
>(minha opinião).

Ainda que SQL seja só pra armazenar a instrução, o TStrings leva vantagem sobre o string porque permite montar uma instrução complexa de forma mais organizada (visualmente).
 
SqlCommand.SQL.Clear;
SqlCommand.SQL.Add('select campoA, campoB');
SqlCommand.SQL.Add('from tabela');
SqlCommand.SQL.Add('where A = :A');
SqlCommand.SQL.Add('order by X');

né não?

Att
Marcos George



 

From: mgnd...@msn.com
To: infra...@googlegroups.com
Subject: [Infra 686] Re: SqlCommand e uma propriedade SQL
Date: Fri, 3 Apr 2009 19:25:40 +0300
</html

Marcos Barreto

unread,
Apr 3, 2009, 1:00:07 PM4/3/09
to infra...@googlegroups.com
Acho que vc está querendo transformar o SQLCommand em uma Query e não é esta a sua finalidade :D
Acho que vou trocar o nome de SQLCommand para outra coisa, assim vc nao vai querer ficar misturando nome de campo e de tabela em um codigo orientado a objeto.

Em um post anterior eu até meio que concordei com a ideia de ter um atributo SQL, mas agora estou vendo que isso vai levar muitos programadores a por SQL em seus código e isso ao meu ver um equivoco que não deveria ser cometido.

Criteria é criteria e deve ser tratada como uma classe a parte mesmo e passado para o SQLCommand ou para o GetResult/GetList, ainda nao estou certo. Só estou certo que este esquema ai de SQL.clear/Add nao cheira bem!

É isso que dá abrir as portas. A possibilidade de por a instrução diretamente no SQLCommand para evitar o cara escrever um template vai abrir a porteira para um monte de problemas que hoje em dia eu gostaria de evitar. Se nossa vida com Queries fosse bom nao estariamos aqui procurando programar de forma mais OO. E acho que a coisa pode ser feita de outra forma, mas fácil e légivel do que concatenação de strings. Temos de pensar na manutenção e por sql no codigo nao facilita isso.

Uma idéia que eu estava tendo seria ter um TemplateReader capaz de ler SQLs de uma lista singleton dentro da aplicação.

Ou seja, o cara nao quer escrever um arquivo, nem por as sqls em um xml, então ele criaria uma unit lá separada e usaria a lista singleton para poder adicionar suas instruções SQL via programação:

unit FinanceiroSQLs;
....
implementation

procedure RegisterFinanceiroSQLs;
begin
   with PersistenceService.TemplateReaderLocal do
   begin
      Add('InsereConta', 'Insert (....) values (...) from conta');
      Add('GetQuantidadeContas', 'Select Count(*) from conta');
      // outros add relacionados ao financeiro
   end;
end;

initialization
  RegisterFinanceiroSQLs;

E assim cada módulo poderia ir adicionar no TemplateReaderLocal suas sql, isso evitaria ficar escrevendo em arquivos separados e evitaria tambem termos um monte de sqls espalhadas por toda a aplicação.

Melhor ainda, nao mudo em nada a lógica do InfaOPF ele automaticamente buscaria a coisa no TemplateReaderLocal.

Marcos George

unread,
Apr 3, 2009, 1:14:47 PM4/3/09
to infra...@googlegroups.com
> Acho que vc está querendo transformar o SQLCommand em uma Query e não é esta a sua finalidade :D
Acho que vou trocar o nome de SQLCommand para outra coisa, assim vc nao vai querer ficar misturando nome de campo e de tabela em um codigo orientado a objeto.
 
> Em um post anterior eu até meio que concordei com a ideia de ter um atributo SQL, mas agora estou vendo que isso vai levar muitos programadores a por SQL em seus código e isso ao meu ver um equivoco que não deveria ser cometido.

O fato de eu fazer uma query na forma tradicional não significa que eu não esteja trabalhando orientado ao objeto, bastando para isso mapear cada registro para um objeto e cada coluna para uma propriedade deste objeto. Isso o infra faz pra mim. Fazer queries da forma tradicional é muito útil, desde que eu possa converter o resultado para uma lista de objetos. Isso é fantástico. Me dá muito poder. O fato de eu ter de colocar o nome de campo e de tabela na SQL se dá simplesmente pelo fato de eu não ter um OQL no Infra. Quando essa limitação não existir, não haverá necessidade de eu colocar nomes de colunas e tabelas diretamente na SQL.
 
> Criteria é criteria e deve ser tratada como uma classe a parte mesmo e passado para o SQLCommand ou para o GetResult/GetList, ainda nao estou certo. Só estou certo que este esquema ai de SQL.clear/Add nao cheira bem!

Não entendi o que o Criteria tem a ver com o SQL.Clear/Add!
Quanto a classe Criteria ser uma classe a parte (leia-se independente) eu não estou certo de que seja a melhor abordagem, afinal, ela está diretamente ligada com o SqlCommand. Eu não deveria precisar instanciar uma classe TCriteria e passá-la para um GetResult ou GetList. E realmente não precisaria se Criteria fosse uma propriedade de SqlCommand. Agora, se vc puder explicar as razões que te levam a pensar diferente talvez eu mude de opinião.

Att
Marcos George



Imagem de exibição animada? Só com o novo Messenger. Baixe agora!

Solerman Kaplon

unread,
Apr 3, 2009, 2:10:03 PM4/3/09
to infra...@googlegroups.com
Marcos George escreveu:
Quanto a classe Criteria ser uma classe a parte (leia-se independente) eu não estou certo de que seja a melhor abordagem, afinal, ela está diretamente ligada com o SqlCommand. Eu não deveria precisar instanciar uma classe TCriteria e passá-la para um GetResult ou GetList. E realmente não precisaria se Criteria fosse uma propriedade de SqlCommand. Agora, se vc puder explicar as razões que te levam a pensar diferente talvez eu mude de opinião.

Criteria pode ser avaliado sem qualquer tipo de SQL, basta percurrer a árvore que compõe a mesma e avaliar cada um diretamente. E decididamente ela deve poder ser criada antes que qualquer coisa SQL exista. É comum ter por exemplo na aplicação cliente que não tem qualquer tipo de base de dados definir um criteria com filtros baseado na entrada do usuário e repassar este para o servidor para execução.

Solerman

Marcos George

unread,
Apr 3, 2009, 2:16:43 PM4/3/09
to infra...@googlegroups.com
> Criteria pode ser avaliado sem qualquer tipo de SQL, basta percurrer a árvore que compõe a mesma e avaliar cada um
> diretamente. E decididamente ela deve poder ser criada antes que qualquer coisa SQL exista. É comum ter por exemplo na
> aplicação cliente que não tem qualquer tipo de base de dados definir um criteria com filtros baseado na entrada do usuário e > repassar este para o servidor para execução.

Entendi o que vc quis dizer, mas realmente, o Criteria não estaria ligado ao SQL e sim ao SqlCommand que é o meio usado pelo Infra para fazer a carga dos objetos. O SQL (que entrou em questão em diversos tópicos) não deve ser pensado como um SQL comum, mas como um gancho para um futuro OQL.

Att
Marcos George
 


Quer deixar seu Messenger turbinado de emoticons? Clique aqui e baixe agora. É grátis!
Reply all
Reply to author
Forward
0 new messages