Imprima la consulta que se genera utilizando db_select ()

61

Quiero imprimir la consulta que se construye usando db_select () de manera programática. ¿Hay alguna función API proporcionada por Drupal Abstraction Layer?
Es similar al resultado de la consulta en Vistas, pero quiero imprimirlo desde mi módulo personalizado para fines de depuración.

Sithu
fuente

Respuestas:

67

SelectQueryimplementos SelectQuery::__toString(), que se llama en los contextos donde se requiere una cadena.

Considere el siguiente código.

global $theme_key;

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

print $query;

Su salida es la siguiente.

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

Para obtener la matriz de argumentos utilizados para la consulta, puede llamar SelectQuery::arguments().

El siguiente código imprime la consulta y sus argumentos utilizando las funciones disponibles desde el 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 pantalla

Sin embargo, el módulo Devel no es necesario, y podría drupal_set_message()mostrar el resultado. Por ejemplo, podría usar la siguiente función para obtener una cadena con los marcadores de posición reemplazados por sus valores reales.

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;
}

El código de ejemplo anterior que mostré se convertiría en el siguiente.

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;
}

Tenga en cuenta que SelectQuery::arguments()devuelve la matriz de argumentos consulta sólo cuando se le llama después SelectQuery::__toString(), SelectQuery::compile()o SelectQuery::execute(); de lo contrario, SelectQuery::arguments()vuelve NULL.

Puede usar una función similar a la siguiente para obtener la consulta de cadena, con los marcadores de posición reemplazados por los argumentos.

kiamlaluno
fuente
1
Creo que una función como _get_query_string()debería haber sido parte de la SelectQueryinterfaz.
dashohoxha
46

Puede usar dpq () para mostrar la consulta y dpr () para mostrar el 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
fuente
1
Tenga en cuenta que esto requiere que se instale el módulo Devel. Si usa Devel (me encanta), esta es la forma más fácil de hacerlo.
joe_flash
2
dpq () donde has estado toda mi vida!
Lomax
No parece funcionar en un try catchbloque cuando falla la consulta. Por lo tanto, no es útil en mi caso si no puedo depurar la consulta rota.
Kiee
19

Otra opción es:

global $theme_key;

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

print strtr((string) $query, $query->arguments());
vijaycs85
fuente
2
Corto y conciso de hecho.
dashohoxha
2
No se requieren módulos de hincha / terceros. Además, esto funciona en consultas que no se han ejecutado, por lo que puede imprimir una consulta que falla y da un error, dpqno parece permitir esto incluso en un intento / captura.
Kiee
1
Esta debería ser la respuesta correcta.
albertski
8

Las respuestas anteriores son buenas cuando tiene Devel instalado y configurado.

La mejor manera de imprimir la consulta sin Devel es la siguiente.

$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 una de las formas anteriores para imprimir la consulta.

KiranD
fuente
4

Tengo una buena solución que puede copiar / pegar su cadena de consulta directamente en la sección "SQL" en Phpmyadmin y depurar su consulta (a menudo uso este método cuando tengo problemas con la 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 esto sea útil para otros chicos.

Yusef Mohamadi
fuente