<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.pdo.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'pdo.prepared-statements.php',
    1 => 'Declara&ccedil;&otilde;es preparadas e procedimentos armazenados',
    2 => 'Declara&ccedil;&otilde;es preparadas e procedimentos armazenados',
  ),
  'up' => 
  array (
    0 => 'book.pdo.php',
    1 => 'PDO',
  ),
  'prev' => 
  array (
    0 => 'pdo.transactions.php',
    1 => 'Transa&ccedil;&otilde;es e confirma&ccedil;&atilde;o autom&aacute;tica (auto-commit)',
  ),
  'next' => 
  array (
    0 => 'pdo.error-handling.php',
    1 => 'Erros e manipula&ccedil;&atilde;o de erros',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'reference/pdo/prepared-statements.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="pdo.prepared-statements" class="chapter">
 <h1 class="title">Declarações preparadas e procedimentos armazenados</h1>

 <p class="para">
  Muitos dos bancos de dados mais maduros suportam o conceito de declarações
  preparadas. O que são elas? Elas podem ser consideradas como uma espécie de
  modelo compilado para o SQL que uma aplicação deseja executar, que pode ser personalizado
  usando parâmetros variáveis. As declarações preparadas oferecem dois benefícios principais:
 </p>
 <ul class="itemizedlist">
  <li class="listitem">
   <span class="simpara">
    A consulta só precisa ser analisada (ou preparada) uma vez, mas pode ser
    executada várias vezes com os mesmos ou diferentes parâmetros. Quando a
    consulta é preparada, o banco de dados irá analisar, compilar e otimizar seu
    plano para executar a consulta. Para consultas complexas, esse processo pode levar
    tempo suficiente para diminuir perceptivelmente o desempenho de uma aplicação se houver
    necessidade de repetir a mesma consulta muitas vezes com diferentes parâmetros. Ao
    usar uma declaração preparada, a aplicação evita repetir o
    ciclo de análise/compilação/otimização. Isso significa que declarações preparadas usam menos
    recursos e, portanto, são mais rápidas.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    Os parâmetros das declarações preparadas não precisam ser citados; o
    driver lida automaticamente com isso. Se uma aplicação usar exclusivamente
    declarações preparadas, o desenvolvedor pode ter certeza de que nenhuma injeção de SQL
    ocorrerá (no entanto, se outras partes da consulta estiverem sendo construídas com
    entrada não escapada, a injeção de SQL ainda é possível).
   </span>
  </li>
 </ul>
 <p class="para">
  As declarações preparadas são tão úteis que são a única funcionalidade que o PDO
  emula para drivers que não as suportam. Isso garante que uma
  aplicação poderá usar o mesmo paradigma de acesso a dados, independentemente das
  capacidades do banco de dados.
 </p>
 <p class="para">
  <div class="example" id="example-1">
   <p><strong>Exemplo #1 Inserções repetidas usando declarações preparadas</strong></p>
   <div class="example-contents"><p>
    Este exemplo executa uma consulta INSERT substituindo um <code class="literal">name</code>
    e um <code class="literal">value</code> pelos marcadores de posição nomeados.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #DD0000">':name'</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #DD0000">':value'</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// insere uma linha<br /></span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #DD0000">'one'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// insere outra linha com valores diferentes<br /></span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #DD0000">'two'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <div class="example" id="example-2">
   <p><strong>Exemplo #2 Inserções repetidas usando declarações preparadas</strong></p>
   <div class="example-contents"><p>
    Este exemplo executa uma consulta INSERT substituindo um <code class="literal">name</code>
    e um <code class="literal">value</code> pelos marcadores de posição posicionais <code class="literal">?</code>.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO REGISTRY (name, value) VALUES (?, ?)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #0000BB">2</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// insere uma linha<br /></span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #DD0000">'one'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// insere outra linha com valores diferentes<br /></span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #DD0000">'two'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <div class="example" id="example-3">
   <p><strong>Exemplo #3 Buscando dados usando declarações preparadas</strong></p>
   <div class="example-contents"><p>
    Este exemplo busca dados com base em um valor de chave fornecido por um formulário.
    A entrada do usuário é automaticamente citada, portanto, não há risco de um ataque de
    injeção de SQL.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT * FROM REGISTRY where name = ?"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">([</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">]]);<br />foreach (</span><span style="color: #0000BB">$stmt </span><span style="color: #007700">as </span><span style="color: #0000BB">$row</span><span style="color: #007700">) {<br />  </span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$row</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <div class="example" id="example-4">
   <p><strong>Exemplo #4 Chamando um procedimento armazenado com um parâmetro de saída</strong></p>
   <div class="example-contents"><p>
    Se o driver do banco de dados suportar, uma aplicação também pode vincular parâmetros de
    saída além de entrada. Os parâmetros de saída são normalmente usados para recuperar
    valores de procedimentos armazenados. Os parâmetros de saída são um pouco mais complexos
    de usar do que os parâmetros de entrada, pois um desenvolvedor deve saber o quão grande um determinado
    parâmetro pode ser quando o vincula. Se o valor for maior do
    que o tamanho sugerido, um erro será gerado.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"CALL sp_returns_string(?)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">$return_value</span><span style="color: #007700">, </span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">PARAM_STR</span><span style="color: #007700">, </span><span style="color: #0000BB">4000</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// chamar o procedimento armazenado<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br />print </span><span style="color: #DD0000">"procedure returned </span><span style="color: #0000BB">$return_value</span><span style="color: #DD0000">\n"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <div class="example" id="example-5">
   <p><strong>Exemplo #5 Chamando um procedimento armazenado com um parâmetro de entrada/saída</strong></p>
   <div class="example-contents"><p>
    Os desenvolvedores também podem especificar parâmetros que contêm valores tanto de entrada quanto de saída;
    a sintaxe é semelhante aos parâmetros de saída. No próximo exemplo, a
    string &#039;hello&#039; é passada para o procedimento armazenado e, quando ele retorna,
    hello é substituído pelo valor de retorno do procedimento.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"CALL sp_takes_string_returns_string(?)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #DD0000">'hello'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindParam</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">PARAM_STR</span><span style="color: #007700">|</span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">PARAM_INPUT_OUTPUT</span><span style="color: #007700">, </span><span style="color: #0000BB">4000</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// chamar o procedimento armazenado<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br />print </span><span style="color: #DD0000">"procedure returned </span><span style="color: #0000BB">$value</span><span style="color: #DD0000">\n"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <div class="example" id="example-6">
   <p><strong>Exemplo #6 Uso inválido de marcador de posição</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT * FROM REGISTRY where name LIKE '%?%'"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">([</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">]]);<br /><br /></span><span style="color: #FF8000">// o marcador de posição deve ser usado no lugar do valor inteiro<br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT * FROM REGISTRY where name LIKE ?"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">([</span><span style="color: #DD0000">"%</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #0000BB">name</span><span style="color: #007700">]</span><span style="color: #DD0000">%"</span><span style="color: #007700">]);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
</div>
<?php manual_footer($setup); ?>