| | | How to: Exemplos de Data Providers com condições |
| (17/02/2009-12:30) |
Saiba como realizar Data providers com saída com condições. |
Na GeneXus X incorporamos o novo tipo de objeto Data Provider. A modo de pequena introdução para aqueles que ainda não o conhecem, os Data Providers são um objeto declarativo que substitui uma determinada classe de procedimento: aqueles que recebem uma entrada, realizam um processo e seu objetivo final é devolver um conjunto de dados em um formato estruturado, ou seja, o foco está na saída.
Deste modo, define-se o formato da saída do Data Provider e isso torna-se em um objeto mais declarativo que um procedimento pois coloca a ênfase no “que fazer” em lugar de “como fazer”
Os componentes básicos dos Data Providers são os Grupos, Elementos, Variáveis, Subgrupos e opções avançadas de controle para os Grupos (Default clause, Paginate clause, NoOutput clause, OutputIfDetail clause e Input clause).
Para maiores detalhes veja: Documentação
O objetivo deste How to é mostrar dois exemplos de uso interessantes.
O primeiro, a efeitos de mostrar que nas condições Where dos grupos não só posso adicionar condições onde o lado esquerdo da comparação seja um atributo, mas também podem ser variáveis.
Suponhamos que queremos obter uma lista de funcionários com seus dados, este seria o DP:
EmployeeCollection { EmployeeItem { Id = EmployeeId Name = EmployeeDsc Address = EmployeeAddress } } |
Agora, se tivermos a necessidade de condicionar a saída dependendo de se o usuário está autorizado a ver essa informação ou não, poderia adicionar a seguinte condição:
EmployeeCollection { EmployeeItem Where &UsrAut=”S” { Id = EmployeeId Name = EmployeeDsc Address = EmployeeAddress } } |
Neste caso, adiciona-se o filtro à sentença SQL gerada, a qual seria a seguinte:
SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress] FROM [Employee] WITH (NOLOCK) WHERE @AV1UsrAut = “S” ORDER BY [EmployeeId] |
Inclusive se quisesse devolver sempre os dados, mas mostrar o endereço apenas para aqueles usuários autorizados, poderia fazer o seguinte:
EmployeeCollection { EmployeeItem { EmployeeId EmployeeDsc EmployeeAddress [NoOutput] Where &UsrAut=”S” { EmployeeAddress = EmployeeAddress; EmployeeSalary = EmployeeSalary; } } } | Neste caso, gera-se a sentença select mas sem a condição de filtro, a qual se transforma em um IF no fonte do DP:
Select a ejecutar: SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress], [EmployeeSalary] FROM [Employee] WITH (NOLOCK) ORDER BY [EmployeeId]
Y además en el fuente del DP: if ( AV1UsrAut = “S”) { Gxm1employee.gxTpr_Employeeaddress = A363Employee ; Gxm1employee.gxTpr_Employeesalary = A364Employee ; } |
Nota: se em lugar de um grupo de atributos (Adress, Salary, etc) deseja-se filtrar apenas um valor é possível escrever diretamente: EmployeeAddress = EmployeeAddress if &UsrAut=”S”;
Vejamos outro exemplo interessante:
Suponhamos neste exemplo que temos uma aplicação que manipula Clientes e Prospects (os Clientes estão em uma tabela e os Prospects em outra). Deseja-se escrever um Data Provider que devolverá uma Collection que contenha os Clientes ou Prospects Ativos. O Data Providers receberá como parâmetro se deseja-se ver Clientes ou Prospects.
Uma forma de escrevê-lo é a seguinte:
Parm(&FiltrarPor) SDTCliProsCollection { SDTCliProsCollectionItem using DSClientesActivos() where &FiltrarPor = ‘CLIENTE’ { PartnerId = ClienteId PartnerName = ClienteName } SDTCliProsCollectionItem using DSProspectsActivos() where &FiltrarPor = ‘PROSPECT’ { PartnerId = ProspectId PartnerName = ProspectName } } |
DSClientesActivos define o filtro sobre Clientes e DSProspectsActivos faz o análogo mas na tabela de Prospects.
Notar que isto executará sempre os dois selects mas adicionará ao where o valor de &FiltrarPor recebido como parâmetro pelo Data Providers (portanto, um irá devolver dados e o outro não).
Isto gera:
SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK) WHERE (@AV4Filtrar = 'CLIENTE') AND ([ClienteStatus] = “Activo”) ORDER BY [ClienteId]
SELECT [ProspectTipo], [ProspectId], [ProspectNombre] FROM [Prospect] WITH (NOLOCK) WHERE (@AV4Filtrar = 'PROSPECT') AND ([ProspectStatus] = “Activo”) ORDER BY [ProspectId] |
Entretanto, podemos escrever o Data Provider como segue, para evitar que execute sempre os dois select, e execute apenas aquele que couber, conforme parâmetro &FiltrarPor (é no fonte gerado onde se decide qual select executar).
SDTCliProsCollection { SDTCliProsCollectionDummy [NoOutput] where &FiltrarPor = 'CLIENTE' { SDTCliProsCollectionItem using DSClientesActivos() { PartnerId = ClienteId PartnerName = ClienteNombre } } SDTCliProsCollectionDummy [NoOutput] where &FiltrarPor = 'PROSPECT' { SDTCliProsCollectionItem using DSProspectActivos() { PartnerId = ProspectId PartnerName = ProspectNombre } } }
Select a executar na hipótese de invocar o DP com &FiltrarPor = ‘CLIENTE’: SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK) WHERE [ClienteStatus] = “Activo” ORDER BY [ClienteId] E além disso no fonte do Data Providers: if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "CLIENTE".TrimEnd(' ') ) == 0 ) ) { AV10DSClie = AV2Cliente ; /* Using cursor P001R2 */ pr_default.execute(0, new Object[] {AV10DSClie}); while ( (pr_default.getStatus(0) != 101) ) { ………………………. (select con filtro por [ClienteStatus] = “Activo”) } pr_default.close(0); } if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "PROSPECT".TrimEnd(' ') ) == 0 ) ) { AV12DSPros = AV3Prospec ; /* Using cursor P001R3 */ pr_default.execute(1, new Object[] {AV12DSPros}); while ( (pr_default.getStatus(1) != 101) ) { ……………………….(select con filtro por [ProspectStatus] = “Activo”) } pr_default.close(1); } this.cleanup(); |
|
| | | | | | | | |
| |