Tirando proveito dos recursos de Macro no ErWin

                                                           por Roberto Pena

O ErWin possui vários recursos que são, muitas vezes, desconhecidos de seus usuários. Um deles é a macro-linguagem para criação de stored procedures e scripts que podem ser executados, por exemplo, antes ou depois de qualquer alteração feita no modelo de dados. Você pode usar as macro-linguagens em um padrão para criação de triggers (ver Figura 1), stored procedures, scripts, quando estes recursos forem suportados pelo banco de dados. Conheceremos neste artigo um pouco mais sobre este recurso do ErWin.

 

F1.JPG

Figura 1. Trigger Template

Macros disponíveis

Na Figura 1, temos apenas umas das diversas telas que apresentam o botão da Toolbox onde as macros podem ser acessadas.

Clicando-se no botão Macro Toolbox, as macros-linguagem são apresentadas em ordem alfabética onde para cada macro são informadas (ver Figura 2):

·         Sintaxe: exibe a sintaxe de cada macro, incluindo chaves, variáveis definidas por usuários e a forma de colocação requerida.

·         Escopo: indica o comando ou código em que cada macro pode ser utilizada. Inclui as informações:

o        "%ForEach":  comandos em que a macro pode ser utilizada;

o        Em que situação a macro pode ser utilizada com o condicional "%if";

o        Os tipos padrões onde a macro pode ser inserida, como scritps padrões para controle de integridade das tabelas.

·         Valor de retorno: explica qual código SQL a macro retorna quando a ela é gerada.

·         Exemplos: são exemplos utilizando-se a macro e seu código expandido correspondente.

 

F2.JPG

Figura 2. Informações da Macro

 

Existem cinco tipos de macro-linguagem disponíveis (ver Figura 5) que fornecem informações do modelo de dados para serem utilizados. Utilizaremos o modelo de dados apresentado nesta figura para os exemplos citados nos comandos:

 

F5.JPG

Figura  5. Tela de Macro-Linguagem.

 

·         Entity Macro: são macros relacionados às informações das tabelas como nome, relação de atributos, índices, relacionamentos, entre outros. As informações retornadas são sempre referente a tabela associada a macro na stored procedure ou script. Segue alguns exemplos:

 

o        %Atts(): retorna uma lista com todos os atributos da tabela, podendo-se definir o separador, uma função e um prefixo:

§         Sintaxe

%Atts(<separator>,<function>,<prefix>)

§         Exemplo: para retornar comandos para verificação de alteração de todos os atributos de uma tabela utilizamos:

%Atts(" or ",update,%Entityname)

§         Expansão do exemplo associado à tabela MOVIE_COPY. A macro %Atts identifica o parâmetro "update" como uma função, colocando o nome de cada atributo da tabela dentro dos parenteses () da função, prefixando-os com o nome da tabela através da macro %EntityName e  separando cada função com o separador "or".

update(MOVIE_COPY.master_number) or

update(MOVIE_COPY.movie_copy_number) or

update (MOVIE_COPY.general_condition)

 

o        %EntityName(): retorna o nome lógico da tabela:

§         Sintaxe

%EntityName(<table>)

§         Exemplo: para retornar nome de uma tabela utilizamos:

%EntityName()

§         Expansão do exemplo associado à tabela MOVIE_RENTAL_RECOR. A macro %EntityName retorna o nome lógico da tabela associada, uma vez que o nome lógico e físico podem ser diferentes no modelo.

MOVIE_RENTAL_RECOR

 

o        %ForEachAtt() { <macro code> }: para cada atributo da tabela, retorna o comando apresentado em <macro code>:

§         Sintaxe

%ForEachAtt(<table>,<separator>) { <macro code> }

§         Exemplo: para retornar os nomes dos atributos de uma tabela utilizamos:

%ForEachAtt(, ", ") {%AttFieldName}

§         Expansão do exemplo associado à tabela MOVIE_COPY. A macro %ForEachAtt retorna os nomes dos atributos da tabela, através da macro %AttFieldName, separando cada atributo com o separador ",".

master_number,

movie_copy_number,

general_condition

 

o        %UpdatePK(): retorna os comandos necessários para verificação de alteração dos atributos da chave primária da tabela:

§         Sintaxe

%UpdatePK(<separator>)

§         Exemplo: para retornar comandos para verificação de alteração nos atributos que são primary key de uma tabela, utilizamos:

%UpdatePK(" or")

§         Expansão do exemplo, associado à tabela MOVIE_COPY:  A macro %UpdatePK utiliza a função update() para cada atributo pertencente a primary key da tabela, separando cada função com o separador " or".

update(master_number) or

update(movie_copy_number)

 

o        %Tablename: retorna o nome físico da tabela:

§         Sintaxe

%Tablename

§         Exemplo: para retornar o nome físico da tabela, utilizamos

%Tablename

§         Expansão do exemplo associado à tabela MOVIE_COPY. A macro %Tablename retorna o nome físico da tabela, uma vez que o nome lógico e físico podem ser diferentes no modelo.

MOVIE_COPY

o        %ParamDecl(): retorna o nome e tipo de todos os atributos da tabela, podendo-se alterar seus prefixos:

§         Sintaxe

%ParamDecl(<old prefix>,<new prefix>,<separator>)

§         Exemplo: para retornar declarações de variáveis prefixados com @ins, com base em atributos de uma tabela.

%ParamDecl(,@ins_,", ")

§         Expansão do exemplo associado à tabela MOVIE_COPY. A macro %ParamDecl retorna os nomes e tipos dos atributos da tabela prefixando seus nomes com o prefixo "@ins, separando cada atributo com o sperador ", ". Caso o padrão de nomenclatura dos atributos utilizasse um prefixo em seus nomes, o mesmo poderia ser retirado dos mesmos através do parâmetro <old prefix>.

@ins_master_number int,

@ins_movie_copy_number int,

@ins_general_condition varchar(10)

 

·         Relantionship Macro: são macros relacionadas às informações dos atributos dos relacionamentos entre as tabelas como nome do relacionamento, tabela pai, tabela filho, atributos migrados de relacionamentos, entre outros. Segue alguns exemplos:

 

o        %ChildFK(): retorna todos os atributos migrados para a tabela filho:

§         Sintaxe

%ChildFK(<separator>,<function>,<prefix>)

§         Exemplo: para retornar comandos para verificação de alteração nos atributos que são foreign key na tabela, separando os comandos com "or", utilizamos.

%ChildFK(" or ",update,%Child)

§         Expansão do exemplo associado à tabela MOVIE_RENTAL_RECOR. A macro % ChildFK identifica o parâmetro "update" como uma função, colocando o nome de cada atributo que são foreign key na tabela, dentro dos parenteses () da função, prefixando-os com o nome da tabela "filho" do relacionamento através da macro %Child e  separando cada função com o separador "or".

update(MOVIE_RENTAL_RECOR.master_number) or

update(MOVIE_RENTAL_RECOR.movie_copy_number)

 

o        %ForEachFKAtt() { <macro code> }: para cada atributo da foreign key, retorna o comando apresentado em <macro code>:

§         Sintaxe

%ForEachFKAtt(<separator>) { <macro code> }

§         Exemplo: para retornar nome dos atributos que são foreign key na tabela, utilizamos:

%ForEachFKAtt(", ") {%AttFieldName}

§         Expansão do exemplo associado à tabela MOVIE_RENTAL_RECOR. A macro %ForEachFKAtt retorna os nomes dos atributos que são foreign key na tabela, através da macro %AttFieldName, separando cada atributo com o separador.

master_number,

movie_copy_number

 

·         Atribute Macro: são macros relacionadas às informações dos atributos das tabelas como nome, tipo de dado, valor default, domain, entre outros.

o        %AttDatatype: retorna o tipo do atributo.

o        %AttDefault(): retorna o default associado ao atributo.

o        %AttDomain: retorna o domain utilizado na definição do atributo.

o        %AttIsFK: retorna se o atributo é foreign key.

o        %AttIsPK: retorna se o atributo é primary key.

o        %AttNullOption: retorna se o atributo é null ou not null.

 

·         Constraint Macro: são macros relacionadas às informações de regra, domain, default do modelo utilizado na definição dos atributos das tabelas. Segue alguns exemplos:

o        %DomainDatatype(<domains name>): retorna o tipo de dado de um domain.

o        %DomainDefault(<domains name>): retorna o valor default de um domain.

o        %ForEachDefault() {<macro code>}: para cada default existente no modelo, expande <macro code>.

o        %ValidationRule(<validation name>): retorna os valores válidos de uma regra.

·         Miscellanious Macro: são macros de variáveis e funções que auxiliam na obtenção e manipulação de informações do modelo como nome do SGBD, nome do database, condições, transformação. Segue alguns exemplos:

 

o        %if(<Condição>) {<Macro 1>} %else {<Macro 2>}: executa <Macro 1> caso <Condição> seja verdadeira, caso contrário retorna <Macro 2>;

§         Sintaxe

%If (<predicate>) {<macro code>} %Else {<macro code>}

§         Exemplo: para retornar o nome do atributo, concatenado com a literal " -> PK" para cada atributo da tabela se a mesma for primary key, utilizamos:

%ForEachAtt() { %If(%AttIsPK) { %AttName -> PK} %Else {%AttName}

§         Expansão do exemplo associado à tabela MOVIE_COPY. Para os atributos retornados pela macro %ForEachAtt, a macro %If verifica através da macro %AttIsPK, o qual retorna um booleano identificando se o atributo pertence a chave primária da tabela, se o atributo é uma PK da tabela. Caso positivo, retorna o nome do atributo através da macro %AttName concatenado com a literal "-> PK". Caso contrário retorna somente o nome doa tributo através da macro %AttName.

master_number -> PK

movie_copy_number -> PK

general_conditional

 

o        %==(<Macro1>,<Macro2>): retorna verdadeiro se a expansão de <Macro1> for igual a expansão de <Macro2>;

§         Sintaxe

%==(<macro code>,<macro code>)

§         Exemplo: para retornar o nome do atributo, concatenado com a literal " -> Null" para cada atributo da tabela se o atributo for Null, utilizamos:

%ForEachAtt () { %if (%==( %AttNullOption,Null)) {%AttName -> Null}

§         Expansão do exemplo associado à tabela MOVIE_COPY. Para os atributos retornados pela macro %ForEachAtt, a macro %If verifica através da macro %== se o retorna da macro %AttNullOption, a qual retorna se o atributo aceita valores nulos ou não (Null or Not Null), o tipo de nulidade do atributo. Caso o retorna seja "Null", retorna o nome do atributo através da macro %AttName concatenado com a literal " -> Null". Caso contrário, não retorna nada.

general_condition -> Null

 

o        %DBMS: retorna o nome do banco de dados configurado para o diagrama;

 

o        %Upper(<Macro>): transforma expansão de <Macro> em maiúsculo:

§         Sintaxe

%Upper(<macro code>)

§         Exemplo: para retornar o nome dos atributos da tabela em maiúsculo.

%ForEachAtt () { %Upper(%AttName)}

§         Expansão do exemplo associado à tabela MOVIE_COPY. Para os atributos retornados pela macro %ForEachAtt, retorna os nomes dos atributos através da macro %AttName, convertidos em letras maiúsculas, através da macro %Upper( )

MASTER_NUMBER

MOVIE_COPY_NUMBER

GENERAL_CONDITION

Utilizando a Macro-Linguagem

Uma utilização prática da Macro-Linguagem é a implementação de stored procedures básicas para as tabelas do modelo de dados. Sabendo-se a estrutura básica da criação destas stored procedures, podemos criar templates que associadas às tabelas do modelo de dados, geram o script para sua criação. Para criar um template de stored procedure para tabelas basta selecionar no menu a opção Database à Stored Procedures à Table Level ou com o botão direito do mouse, na definição da tabela no diagrama, a opção Stored Procedure.

Você cria um novo template clicando no botão New e digitando o nome do template. A tela apresentada na Figura 6 é mostrada contendo as pastas:

·         General: onde se pode definir stored procedure para tabelas ou para o modelo;

·         Code: onde se deve codificar seus comandos utilizando as macros necessárias. Este procedimento é manual, utilizando-se das macros apropriadas para gerar o resultado necessário no final;

·         Expanded: onde poderá ser visto seus comandos expandidos de acordo com a tabela vinculada;

·         Comment: onde se pode incluir comentários a respeito do template gerado;

·         UDP: são variáveis do Erwin que podem ser criadas e utilizadas nos próprios templates.

 

Na Figura 2, temos um template para criação de uma stored procedure de inserção, onde foram utilizados as seguintes Macros, já explicados anteriormente:

%if(<Condição>) {<Macro 1>} %else {<Macro 2>}

%==(<Variável>,<Macro>)

%DBMS

%Tablename

%ParamDecl(,<prefixo>)

%Atts()

 

F6.JPG

Figura 6. Tela e Script do Template de Inserção.

 

Uma vez criado o template ele pode ser associado a todas as tabelas do modelo de dados. O objetivo disso é gerar o script para criação das stored procedures de inserção das tabelas. Para associar o template à tabela basta selecionar no menu a opção Database à Stored Procedures à Table Level ou com o botão direito do mouse, na definição da tabela no digrama, a opção Stored Procedure. Na tela de Stored Procedure poderão ser vistas todas stored procedures associadas à tabela (Figura 8).

Para associar uma stored procedure à tabela, clique no Browser, o qual exibirá a tela de Stored Procedure Browser (Figura 9) onde estarão listadas todas as stored procedures existentes no modelo de dados. Executando um duplo clique na tabela na coluna Unattached Table, a mesma será transferida para a coluna Attached Table. Neste momento, a tabela estará associada a stored procedure selecionada.

Para maior comodidade, pode-se especificar para que a stored procedure seja associada automaticamente a qualquer tabela que seja criada no modelo de mados. Para isto basta marcar a opção Attach To New Table.

Associada à tabela CLIENTES (Listagem 1), a Listagem 2 mostra a expansão do template da macro, gerando o script de criação da stored procedure de inserção desta tabela com base no template criado. Este expansão será exibida na janela SP Expansion, mostrada na Figura 9. Esta expansão é gerada também durante a criação do script do banco através do menu Tools -> Forward Engineer/Schema Generator, conforme Figura 7, quando as opções de script estão selecionadas.

 

Estrutura tabela CLIENTES

 

CREATE TABLE CLIENTES (

       CLI_NRMAT int,

       CLI_DCNOM char(30),

       DTCAD datetime,

       CLI_END varchar(100),

       CLI_NRCPF char(11),

       CLI_NRRG char(10))

Listagem 1. Estrutura da tabela CLIENTES

 


CREATE PROCEDURE SP_INS_CLIENTES

   @INS_CLI_NRMAT int,

   @INS_CLI_DCNOM char(30),

   @INS_CLI_DTCAD datetime,

   @INS_CLI_END varchar(100),

   @INS_CLI_NRCPF char(11),

   @INS_CLI_NRRG char(10)

AS

INSERT INTO CLIENTES (

   CLI_NRMAT,

   CLI_DCNOM,

   CLI_DTCAD,

   CLI_END,

   CLI_NRCPF,

   CLI_NRRG)

VALUES

   @INS_CLI_NRMAT,

   @INS_CLI_DCNOM,

   @INS_CLI_DTCAD,

   @INS_CLI_END,

   @INS_CLI_NRCPF,

   @INS_CLI_NRRG)

GO

Listagem 1. Script com expansão do template de inserção.

 

F7.JPG

Figura 7. Schema Generation

 

F8.JPG
Figura 8. Tela de Stored Procedures associadas à tabela.

 

F9.JPG
Figura 9. Tela com todas Stored Procedures do Modelo de Dados.

Conclusão

Conhecendo as macros existentes, é possível criar templates e scripts que podem facilitar a implementação de alguns recursos necessários para o modelo de dados. Os procedimentos acima são os mesmos para template de scripts e podem ser criados juntamente com as stored procedures em nível global e de tabela. Estes recursos podem muitas vezes economizar tempo de programação e facilitar a administração da manutenção do modelo de dados evitando retrabalho.

Exemplos das macros podem ser encontrados no help do ErWin com explicações que facilitam seu entendimento e utilização.