fc2ブログ

top


総投稿数 本 
no_1338

Drupal で、SQL:Drupal で SQL文を構築した際の細かネタをメモしておく。in構文と、DISTINCT ・・・ 【今日の細ネタ】

 2010-05-04
 Drupalサイト構築
 やはり様々な理由で、ポテンシャルの高さを実感している。
 すばらしい。
 しかし、最近はほぼviewsを利用しなくなった。
 (ちょっと早すぎ?)
 理由は
 ・明らかに無駄なSQL文で動いていることが
  多く見受けられること
 ・(ほんの少しだけどやはり?)重さを感じること
 ・データベースに踏み込んで、Drupalのテーブル構造
  肌で感じたいこと
 ・・・様々だけれど。

 主に、
 ・(不明な場合は)viewsを作業用に作成し、
  そこで生成され表示されるSQL文と、
 ・phpMyAdmin利用したテーブル構造の再確認
 で、自力でSQL文を使うことが多い。
 今日も2つほど、「覚えておこ」という
 細ネタがあったので記録しておく。


2010年05月04日 のコマネタ
 □Drupalにおいて、pager_query使うときに注意
  その1:like '%strtext%' ではなく、in構文が確実(?)
  その2:集計関数を使う際の DISTINCT 再理解
 □jQueryって、簡易デバッグにも便利


  追記に  ▼


FC2ブログランキング にほんブログ村 IT技術ブログ Webサイト構築へ ブログ王ランキング 人気ブログランキング 人気ホームページランキングへ


more

************************************************
◎  Drupal で SQL文を構築した際の細かネタ の巻
                 :今日の細ネタ

************************************************


 

 ■Drupalにおいて、pager_query使うとき。
 ・pager_quer 自体は素晴らしくて多用している。
  (参照)Drupal pager_query:Pager続き。今度は、Drupalサイト。当然モジュールかAPIであるんだろうな ・・・ 【今日のDrupal】

 

  □症状
   ・これを利用するには、
function pager_query(
$query,
$limit = 10,
$element = 0,
$count_query = NULL)

    で、4つの引数
    ・検索本SQL
    ・頁の表示点数
    ・複数利用できるelement値
    ・カウント用のSQL
    を与えるわけだが・・・

   どうもおかしい。


   時折、クエリがうまくできなくて
   0 が返ってくるのだ。
   ・false ではない
   ・当該SQLを直接データベースに投げると
    きちんと答えを返してくる。


   ・この関数内を少し覗いてみる。
    □$args = func_get_args();
     ※関数の引数リストを配列として返す


     その後
    □$args = array_slice($args, 4);
     ※配列の一部を展開
      これはつまり、予定されてる4つ以降の引数を
      取得把握しようとしている?


 

    □
  // Alternative syntax for '...'
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}

     ※取得できそれが配列であれば、それ自体を
      引数扱いとする・・・と。

 

    □$count_query = NULL
     カウント用のSQLがなければ、
  // Construct a count query if none was given.
if (!isset($count_query)) {
$count_query = preg_replace(array('/SELECT.*?FROM /As', '/ORDER BY .*/'), array('SELECT COUNT(*) FROM ', ''), $query);
}
 自動的に与えられる。

 

    □そして最終的に
$pager_total_items[$element] = db_result(db_query($count_query, $args));
 ・・・として
     取得件数をまず得るのだが、
     ここで、返りが0 になってしまうケースがある。
     ※投げている、$count_query を直接データベースに
      あてると、正常に返ってくるのに・・・

 

    □どうも、この先、Drupal で
     ・includes/database.mysql.inc において、
function db_result($result) {
if ($result && mysql_num_rows($result) > 0) {
// The mysql_fetch_row function has an optional second parameter $row
// but that can't be used for compatibility with Oracle, DB2, etc.
$array = mysql_fetch_row($result);
return $array[0];
}
return FALSE;
}
  mysql_num_rows($result)がきちんと
  値を返してくれていないようなのだ。

    いろいろ探ったけどわからなかった。


  □回避
   検索を行う場合、 targetitem like = '%targetstr%' ではなくて
   > targetitem in ('targetstr') を利用することで
     正常に値を得ることができるようになった。


   ※一応正常に動いているようなので回避。
    しかし、知識疑問としての課題 残り。


------------------------------------------------


 

 ■SQL構文はそれ自体、奥深くて面白いのだが
  普段利用するときは基本的な構文のみで事足りる。
  しかし、知識は不安定であること、今日思い知った。

  □例
   ・ある 商品テーブルがあり、
    ・そこには、2レベルのカテゴリマスタの
     ・子カテゴリへのリンクが複数登録されているとする。


     ・つまり、商品Aが、
      カテゴリ(あ)> 子カテゴリ(イ) と
      カテゴリ(え)> 子カテゴリ(ハ) に
      属している・・・という場合


 

      ・リレーションは別のリレーショナルテーブル
       (子カテゴリリレーショナルテーブル)で
       保存されている
  商品Aid | 子カテゴリ(イ)id
  商品Aid | 子カテゴリ(ハ)id
  ・・・・・

 

     ・子カテゴリテーブルには
      (親)カテゴリへのリレーションが設定されている
  子カテゴリ(イ) | カテゴリ(あ)id
    子カテゴリ(ハ) | カテゴリ(え)id
  ・・・・・

 

   ・検索SQLで、親カテゴリ(あ)のカテゴリ名前で
    商品を全検索したい場合
SELECT *
FROM 商品テーブル
LEFT JOIN 子カテゴリリレーショナルテーブル
ON 子カテゴリリレーショナルテーブル.商品id =商品テーブル.商品id
LEFT JOIN 子カテゴリテーブル
ON 子カテゴリテーブル.子カテゴリid = 子カテゴリリレーショナルテーブル.子カテゴリid
LEFT JOIN カテゴリテーブル
ON カテゴリテーブル.カテゴリid = 子カテゴリテーブル.カテゴリid
WHERE (カテゴリテーブル.カテゴリ名前 in ('検索する文字列'))
ORDER BY カテゴリテーブル.カテゴリ名前 ASC
 で検索できるが
    このときに、重複を回避するために、distinct を利用し、
SELECT distinct
・・・・・
 とする。

 

    さらに集計関数を利用した場合、
SELECT COUNT(DISTINCT id) AS row_count
・・・・・
 とするんだなぁ。
   ※ DISTINCT * ではエラーになる。
   このあたり、色々試してやっと理解できた。恥ずかし。

------------------------------------------------


 

 ■jQuery ってほんとに便利だなぁ。
  もっとよく知ることにより、開発ももっと
  確実性も効率も向上するんだろうなぁ・・・

  □ケース
   先の投稿で、(いまさらながら)jQuery.dump.js という
   プラグインを知り、
   ・jQuery.dump.js:知、知らなかった。こんな便利なjQueryプラグインがあったのか。もっとい早く知っていれば。DOMの情報をdump出力してくれる ・・・ 【jQueryプラグイン】
    それはそれで喜んだのだけど。


   そのとき、ある<span> 要素のcalss名をとろうとしたのだけで
   うまくとれなかった。


 

   こんなときも、jQuery 利用すれば、
   ・確実に
   ・きれいに取得してくれる。
	var $target = $(this);
var classname = $target.attr('class');
 これだけだ。
    ※DOMはほんとに奥深く、対象がテキスト文字列であっても
     それを どうハンドリングするかによって
     取れたり取れなかったりする。
    それが、jQueryの簡単な構文で楽に取得できるのは有難い。

   これをうまく利用した、簡単なデバッグ用関数を作り、
   デバッグ時に利用しよう。


 ※取りとめもないメモ。乱文ご容赦。

commentsコメント
comment_post












管理者にだけ表示を許可する
commentトラックバック
トラックバックURL:
http://metaboy.blog23.fc2.com/tb.php/1338-b3224c1e
ようこそ
Add to Google 創るmetaboy:RSSフィード
My Yahoo!に追加
最新記事のRSS | 問い合わせ

仕事検索、アルバイト検索、依頼仕事の検索ポータル - 仕事検索.COM - www.jobkensaku.com ツクルン

創るmetaboy - WEB創る、サイト創る、何創る - 創ったmetaboy

 

リンク集

 

最近の記事

 

ブロとも申請フォーム
Sponserd by

さくらのレンタルサーバ さくらのレンタルサーバ
大容量・高機能レンタルサーバー heteml 大容量・高機能レンタルサーバー heteml
XREA (ValueDomain)
お名前.com お名前.com
名づけてねっと名づけてねっと
ムームードメインムームードメイン