Imprima a consulta criada usando db_select ()

61

Eu quero imprimir a consulta que é criada usando db_select () de uma maneira programática. Existe alguma função de API fornecida pelo Drupal Abstraction Layer?
É semelhante à saída da consulta no Views, mas quero imprimi-la no meu módulo personalizado para fins de depuração.

Sithu
fonte

Respostas:

67

SelectQueryimplementa SelectQuery::__toString(), que é chamado nos contextos em que uma sequência é necessária.

Considere o seguinte código.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print $query;

Sua saída é a seguinte.

SELECT block.*
FROM 
{block} block
WHERE  (theme = :db_condition_placeholder_0) AND (status = :db_condition_placeholder_1)

Para obter a matriz de argumentos usados ​​para a consulta, você pode chamar SelectQuery::arguments().

O código a seguir imprime a consulta e seus argumentos usando as funções disponibilizadas no módulo Devel.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

dpm((string) $query);
dpm($query->arguments());

captura de tela

O módulo Devel não é necessário e você pode drupal_set_message()mostrar a saída. Por exemplo, você pode usar a seguinte função para obter uma string com os espaços reservados substituídos por seus valores reais.

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

O código de exemplo anterior que eu mostrei se tornaria o seguinte.

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

drupal_set_message(format_string('Query: %query', array('%query' => _get_query_string($query))));

function _get_query_string(SelectQueryInterface $query) {
  $string = (string) $query;
  $arguments = $query->arguments();

  if (!empty($arguments) && is_array($arguments)) {
    foreach ($arguments as $placeholder => &$value) {
      if (is_string($value)) {
        $value = "'$value'";
      }
    }

    $string = strtr($string, $arguments);
  }

  return $string;
}

Observe que SelectQuery::arguments()retorna a matriz de argumentos de consulta apenas quando é chamado depois SelectQuery::__toString(), SelectQuery::compile()ou SelectQuery::execute(); caso contrário, SelectQuery::arguments()retorna NULL.

Você pode usar uma função semelhante à seguinte para obter a consulta de string, com os espaços reservados substituídos pelos argumentos.

kiamlaluno
fonte
11
Eu acho que uma função como _get_query_string()deveria ter sido parte da SelectQueryinterface.
Dashohoxha 19/10/2015
46

Você pode usar dpq () para exibir a consulta e dpr () para exibir o resultado.

  $query = db_select('users','u');
  $query->fields('u');
  $query->condition('u.uid', 1042);
  $result = $query->execute()->fetchAll();

  dpq($query); // Display the query. 
  dpr($result); // Display the query result.
umesh
fonte
11
Observe que isso requer que o módulo Devel esteja instalado. Se você usa Devel (eu amo isso), esse é o caminho mais fácil.
Joe_flash 20/02
2
dpq () onde você esteve toda a minha vida!
Lomax
Não parece funcionar em um try catchbloco quando a consulta falha. Portanto, não é útil no meu caso se eu não puder depurar a consulta quebrada.
27416 Kiee
19

Outra opção é:

global $theme_key;

$query = db_select('block')
  ->condition('theme', $theme_key)
  ->condition('status', 1)
  ->fields('block');

print strtr((string) $query, $query->arguments());
vijaycs85
fonte
2
Curto e conciso, de fato.
Dashohoxha 19/10/2015
2
Não são necessários módulos inchados / de terceiros. Além disso, isso funciona em consultas que não foram executadas, para que você possa imprimir uma consulta que falhe e dê um erro, dpqnão parece permitir isso, mesmo em uma tentativa / captura.
27416 Kiee
11
Essa deve ser a resposta correta.
albertski 25/04
8

As respostas acima são boas quando você tem o Devel instalado e configurado.

A melhor maneira de imprimir a consulta sem Devel é a seguinte.

$query = db_select('block')
->condition('theme', $theme_key)
->condition('status', 1)
->fields('block');
//One way
echo $query->__toString();
// Second way
echo (string)$query;

Podemos usar uma das maneiras acima para imprimir a consulta.

KiranD
fonte
4

Eu tenho uma boa solução que você pode copiar / colar sua string de consulta diretamente na seção "SQL" no Phpmyadmin e depurar sua consulta (eu geralmente uso esse método quando luto com a consulta)

$querystring=$query->__toString();
$querystring=str_replace("{",'',$querystring);
$querystring=str_replace("}",'',$querystring);
foreach($query->getArguments() as $key=> $item){

    if(!$item) {
        $item = 'NULL';
    }
    $querystring=str_replace($key.')',$item.')',$querystring);
}
dpm($querystring);

Espero que isso seja útil para outros caras.

Yusef Mohamadi
fonte