Ferramentas Pessoais
Você está aqui: Página Inicial Artigos Instalando o Python / Zope / Plone

Instalando o Python / Zope / Plone


   Os comandos dtml-sql são usados dentro de objetos SQL Method. O contexto de execução dos SQL
   Methods é especial: Dentro de um SQL Method, os argumentos declarados no campo Arguments do
   próprio método estão no topo do namespace. Eles são preenchidos automaticamente a partir de valores
   presentes no REQUEST. Por exemplo, se existe uma variável quantidade no REQUEST, seu valor será
   atribuido ao parâmetro declarado de nome idêntico, podendo ser acessado da seguinte maneira:
   <dtml-sqlvar name="quantidade" type="int">
   Outros comandos DTML também podem ser usadas em SQL Methods, porém eles raramente são
   necessários, uma vez que os comandos dtml-sqlgroup e dtml-sqltest, são bastante poderosos e evitam
   muitos dos transtornos que encontramos ao lidar com SQL em outras linguagens.


dtml-sqlgroup

   <dtml-sqlgroup parâmetros>testes</dtml-sqlgroup>
   Produz cláusulas condicionais complexas, formadas por múltiplos testes que podem ser opcionais ou
   obrigatórios. O uso deste comando combinado ao dtml-sqltest simplifica muito a geração de código SQL
   com cláusulas configuradas dinamicamente em função dos argumentos fornecidos ou omitidos pelo
   usuário. Geralmente, o bloco contido em um dtml-sqlgroup é composto exclusivamente por comandos
   dtml-sqltest.

Variantes

   <dtml-sqlgroup parâmetros>bloco1<dtml-and>bloco2</dtml-sqlgroup>
   <dtml-sqlgroup parâmetros>bloco1<dtml-or>bloco2</dtml-sqlgroup>
   <dtml-sqlgroup params1>bloco1<dtml-or>bloco2<dtml-and>bloco3</dtml-sqlgroup>

   Dentro de um dtml-sqlgroup, vários comandos dtml-and e dtml-or podem ser utilizados para conectar os
   blocos, renderizando opcionalmente os operadores lógicos AND e OR da linguagem SQL. Estes
   operadores só são renderizados caso os blocos adjacentes também sejam, evitando erros sintáticos no SQL.

Parâmetros

Parâmetro  Descrição
required  
se presente, este parâmetro define um grupo obrigatório, gerando uma exceção caso bloco renderizado fique vazio
where
se presente, este parâmetro provoca a renderização condicional da string WHERE; se o bloco renderizado ficar vazio e não for opcional, a palavra WHERE é omitida, evitando erro sintáico

Exemplos

   O exemplo abaixo produz uma lista de candidatos de um estado e/ou partido. Para funcionar, este código
   deve ser colocado em um SQL Method com dois argumentos declarados: uf e partido. O usuário pode
   fornecer ambos, apenas um, ou nenhum dos argumentos.
   select uf, partido, nome from candidatos

   <dtml-sqlgroup where>
   <dtml-sqltest name="uf" type="nb" optional>
   <dtml-and>
   <dtml-sqltest name="partido" type="nb" optional>
   </dtml-sqlgroup>
   order by uf, partido, nome


   Supondo os argumentos uf='AM' e partido='PT', o código resultante será:

   select uf, partido, nome from candidatos
   where
   (uf = 'AM'
     and partido = 'PT'
   )
   order by uf, partido, nome


   Se apenas o argumento uf='RS' for indicado, o SQL ficará assim (note a omissão dos parênteses e do
   operador and):

   select uf, partido, nome           from candidatos
   where
   uf = 'AM'
   order by uf, partido, nome


   Deixando em branco os dois argumentos, o resultado será uma listagem de todos os candidatos,
   indepentente de estado ou partido. O código SQL gerado será assim:

   select uf, partido, nome from candidatos
   order by uf, partido, nome


Uso do parâmetro required para evitar um desastre

   No código abaixo, o parâmetro required é usado para impedir a omissão da cláusula where. Isto é útil
   especialmente com o comando SQL DELETE, capaz de aniquilar uma tabela inteira de uma vez só. Neste
   exemplo, os dois argumentos são opcionais, mas o usuário será obrigado a fornecer um deles. Se ambos
   forem omitidos, uma execeção será levantada e o SQL não será executado. Assim, só é possível remover os
   candidatos de um partido, de um estado, ou de um partido e estado, e não todos de uma vez.
   delete from candidatos

   <dtml-sqlgroup where required>
   <dtml-sqltest name="uf" type="nb" optional>
   <dtml-and>
   <dtml-sqltest name="partido" type="nb" optional>
   </dtml-sqlgroup>


Grupos de condições aninhadas e festas com muito uísque

   O código a seguir poderia ser usado para criar listas de convidados para festas de políticos. Dados os
   argumentos uf, partido e votos este método seleciona todos os candidatos que são de um determinado
   estado e de um determinado partido, ou que tiveram mais do que um certo número de votos, independente
   do estado ou partido.

   select uf, partido, nome, votos from candidatos
   <dtml-sqlgroup where>
        <dtml-sqltest votos op="gt" type="int">
   <dtml-or>
        <dtml-sqlgroup>
             <dtml-sqltest uf type="nb">
        <dtml-and>
             <dtml-sqltest partido type="nb">
        </dtml-sqlgroup>
   </dtml-sqlgroup>


   Para formar uma mesa de pôquer, os argumentos poderiam ser uf='BA', partido='PV' e votos=40000.
   Tais argumentos resultariam no seguinte SQL:

   select uf, partido, nome, votos from candidatos
   where
   (votos > 400000
     or (uf = 'BA'
     and partido = 'PV'
   )
   )

                 

dtml-sqltest

   <dtml-sqltest parâmetros>
   Gera uma expressão de teste condicional em SQL, comparando um argumento declarado a uma coluna da
   tabela. O parâmetro name= é usado para especificar o argumento, e parâmetro column= define a coluna da
   tabela contra a qual o argumento deve ser comparado. Se o nome da coluna é idêntico ao nome do
   argumento, o parâmetro column= pode ser omitido.

Parâmetros

parâmetrodescrição
name=argnome do argumento a ser comparado (é obrigatório usar name= ou expr=; proibido usar ambos)
expr=expressãoexpressão a ser comparada (é obrigatório usar name= ou expr=; proibido usar ambos)
column=colunanome do coluna a ser comparada (o default é usar o mesmo nome definido no parâmetro name=); este parâmetro é obrigatório quando o parâmetro name= não é utilizado
type=tipoparâmetro obrigatório; valores válidos: nb, string, int, float; para strings, utilize tipo nb a menos que necessite testar campos vazios e não nulos (ex.: complemento = '')
optional
quando presente, este parâmetro evita evita a renderização do teste como um todo, em vez de levantar uma exceção se o argumento é nulo ou inexistente
multiple=bool
se verdadeiro, assume que o argumento é uma lista e gera um teste usando o operador SQL IN para verificar se o valor da coluna é igual a um dos valores do argumento (veja exemplo abaixo)
op=operador
operador a ser utilizado na comparação (default é eq); valores reconhecidos: eq (= igual), ne (<> diferente) gt (> maior), ge (>= maior ou igual), lt(< menor), le (<= menor ou igual); se um valor não reconhecido for utilizado, ele é renderizado sem modificação, permitindo o uso de operadores como LIKE,

                         % etc.


Exemplos

   Abaixo, alguns usos simples do comando dtml-sqltest. Outros exemplos podem ser encontrados no
   comando dtml-sqlgroup.

   select * from bares where <dtml-sqltest nome type="nb">

   Se o valor do argumento nome é "Moe's", o comando acima será renderizado assim:

   select * from bares where nome = 'Moe''s'

   Note que a aspa simples usada como apóstrofe foi duplicada na string renderizada, evitando um erro de
   sintaxe em SQL.
   Para pesquisar todos os bares diferentes do argumento:

   select * from bares where <dtml-sqltest nome type="nb" op="ne">

   Neste caso o resultado seria:

   select * from bares where nome <> 'Moe''s'

   Nos exemplos acima, utilizamos type="nb" obrigando o argumento nome a ser uma string não vazia.
   Supondo que o coluna nome pode conter strings vazias, podemos dar ao usuário a opção de buscar registros
   nestas condições usando type="string":

   select * from bares where <dtml-sqltest nome type="string">

   Agora, se o argumento nome é uma string vazia, o usuário não verá uma mensagem de erro, mas sim uma
   lista de bares sem nome, resultante deste comando SQL:

   select * from bares where nome = ''


Uso do parâmetro muliple

   O exemplo abaixo produz uma lista de candidatos de uma região. Para funcionar, este código deve ser
   colocado em um SQL Method com um argumento declarado de nome regiao. O valor esperado para este
   argumento é uma lista de siglas de estados separadas por espaços (por exemplo: "RS PR SC"). Uma
   expressão Python é usada para transformar o argumento em uma lista através do uso do método
   String.split().

   select uf, nome, partido from candidatos
   where <dtml-sqltest expr="regiao.split()" column="uf" type="nb" multiple>
   order by uf, nome


   Caso o argumento região receba o valor "RS PR SC", o SQL resultante é:

   select uf, nome, partido from candidatos
   where uf in ('RS', 'SC', 'PR')
   order by uf, nome

   Se apenas uma sigla é fornecida (por exemplo, regiao="MG"), o SQL gerado é:

   select uf, nome, partido from candidatos
   where uf = 'MG'
   order by uf, nome


dtml-sqlvar

   <dtml-sqlvar parâmetros>
   Insere o valor da variável ou expressão no código SQL. Normalmente o parâmetro name= corresponde a
   um argumento declarado no SQL Method. O parâmetro obrigatório type= define como o argumento deve
   ser renderizado (por exemplo, strings são renderizadas entre aspas simples, de acordo com a sintaxe da
   linguagem SQL, e aspas simples dentro de strings são duplicadas automaticamente). Este comando é útil
   principalmente para produzir valores para os comandos SQL INSERT e UPDATE.
   Os parâmetros optional e type=nb modificam bastante o comportamento deste comando. O tipo nb (non-
   blank) serve para renderizar strings em situações em que uma string vazia não faz sentido. Se o argumento
   é uma string vazia, a opção type=nb gera um erro. Porém, se o parâmetro optional for especificado, a
   palavra null (sem aspas) é renderizada no lugar do argumento (em muitos dialetos de SQL, null é a
   palavra reservada usada para designar um valor nulo). No caso de type=string, uma string vazia é sempre
   renderizada como '' (duas aspas simples). Na maioria dos casos é melhor usar type=nb do que type=string.
   Os exemplos abaixo demonstram todos os possíveis resultados da renderização de uma string vazia com
   diferentes parâmetros. Para entender estes exemplos, suponha que o código está em um SQL Method com
   um argumento declarado chamado cod. Os resultados mostram o que acontece quando o argumento cod
   recebe uma string vazia.
   <dtml-sqlvar name="cod" type="nb">                       #> Erro: string vazia inválida em cod
   <dtml-sqlvar name="cod" type="nb" optional> #> null (palava reservada de SQL)
   <dtml-sqlvar name="cod" type="string">                               #> '' (uma string vazia entre aspas
       simples)


Parâmetros

parâmetro
descrição
name=arg
nome do argumento a ser renderizado (é obrigatório usar name= ou expr=; proibido usar ambos)
expr=expressãoexpressão a ser renderizada (é obrigatório usar name= ou expr=; proibido usar ambos)
type=tipoparâmetro obrigatório; valores válidos: nb, string, int, float; para strings, utilize preferencialmente o tipo nb (veja explicação acima)
optional
quando presente, este parâmetro evita levantar uma exceção se o argumento é nulo ou inexistente

Exemplo

   O código abaixo poderia ser usado para cadastrar itens em um estoque. Supondo que os campos cod,
   descricao e cor são todos do tipo VARCHAR no banco de dados, este exemplo dá um tratamento diferente
   para seus respectivos argumentos. O argumento cod é obrigatório; se um valor nulo ou string vazia é
   fornecido, o comando dtml-sqlvar levanta uma exceção. O argumento descricao é uma string
   obrigatória, mas pode ser uma string vazia (''). Finalmente o argumento cor é uma string opcional; se um
   valor nulo ou vazio é fornecido, o comando dtml-sqlvar produzirá a palavra null.
  
   INSERT INTO ESTOQUE (
         cod, descricao, cor, preco, quantidade
   )
   VALUES (
         <dtml-sqlvar cod type="nb">,
         <dtml-sqlvar descricao type="string">,
         <dtml-sqlvar cor type="nb" optional>,
         <dtml-sqlvar preco type="float">,
         <dtml-sqlvar quantidade type="int">
   )


Desenvolvido por: Luciano Ramalho <ramalho@hiper.com.br>