db_select ()를 사용하여 빌드 된 쿼리를 인쇄하십시오.


61

프로그래밍 방식으로 db_select () 를 사용하여 작성된 쿼리를 인쇄하고 싶습니다 . Drupal Abstraction Layer에서 제공하는 API 기능이 있습니까?
뷰의 쿼리 출력과 비슷하지만 디버깅 목적으로 사용자 정의 모듈에서 인쇄하고 싶습니다.

답변:


67

SelectQuery구현 SelectQuery::__toString()은 문자열이 필요한 컨텍스트에서 호출됩니다.

다음 코드를 고려하십시오.

global $theme_key;

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

print $query;

출력은 다음과 같습니다.

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

쿼리에 사용되는 인수 배열을 얻으려면을 호출하면 SelectQuery::arguments()됩니다.

다음 코드는 Devel 모듈에서 사용 가능한 함수를 사용하여 쿼리 및 해당 인수를 인쇄합니다.

global $theme_key;

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

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

스크린 샷

그러나 Devel 모듈은 필요하지 않으며 drupal_set_message()출력을 표시 할 수 있습니다. 예를 들어 다음 함수를 사용하여 자리 표시자가 실제 값으로 대체 된 문자열을 얻을 수 있습니다.

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

내가 보여준 이전 예제 코드는 다음과 같습니다.

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

, 또는 ; SelectQuery::arguments()다음 SelectQuery::__toString()에 호출 될 때만 쿼리 인수 배열 을 반환합니다 . 그렇지 않으면를 반환합니다 .SelectQuery::compile()SelectQuery::execute()SelectQuery::arguments()NULL

다음과 유사한 함수를 사용하여 자리 표시자가 인수로 대체 된 문자열 쿼리를 얻을 수 있습니다.


1
나는 같은 기능 _get_query_string()SelectQuery인터페이스의 일부 라고 생각합니다 .
dashohoxha

46

dpq () 를 사용 하여 쿼리를 표시하고 dpr () 을 사용하여 결과를 표시 할 수 있습니다.

  $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.

1
이를 위해서는 Devel 모듈이 설치되어 있어야합니다. Devel (사랑합니다)을 사용한다면 가장 쉬운 방법입니다.
joe_flash

2
dpq () 당신은 내 평생 어디에 있었습니까!
Lomax

try catch쿼리가 실패하면 블록 에서 작동하지 않는 것 같습니다 . 깨진 쿼리를 디버깅 할 수없는 경우 제 경우에는 도움이되지 않습니다.
키이

19

다른 옵션은 다음과 같습니다.

global $theme_key;

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

print strtr((string) $query, $query->arguments());

2
짧고 간결합니다.
dashohoxha

2
팽창 / 타사 모듈이 필요하지 않습니다. 또한 이것은 실행되지 않은 쿼리에서 작동하므로 실패하고 오류를 발생시키는 쿼리를 인쇄 할 수 dpq있으며 시도 / 캐치에서도이를 허용하지 않는 것 같습니다.
키이

1
이것이 정답이어야합니다.
albertski

8

위의 답변은 Devel을 설치하고 구성했을 때 좋습니다.

Devel없이 쿼리를 인쇄하는 가장 좋은 방법은 다음과 같습니다.

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

위의 방법 중 하나를 사용하여 쿼리를 인쇄 할 수 있습니다.


4

Phpmyadmin의 "SQL"섹션에서 직접 쿼리 문자열을 복사 / 붙여 넣을 수 있고 쿼리를 디버깅 할 수있는 좋은 솔루션이 있습니다.

$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);

나는 이것이 다른 사람들에게 유용하기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.