質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • PHP

    24510questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    7133questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • EC-CUBE

    317questions

    EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

  • Doctrine2

    20questions

    Doctrine 2.0はPHP(5.3.2+)のORMです。Doctrine1.2はActive Recordのパターンを使っているのに対し、Doctrine 2はData Mapperパターンを使います。Doctrineのプロジェクトはデータベースの抽象性とPHPで書かれたORMを扱うためのオープンソースのライブラリとツールの集合です。

LIMITを使用したDoctrine2のSQLの記述方法について

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,371

jef12

score 2

EC-CUBE3.0.10において、注文番号をカスタマイズしランダムにて設定しているためすでに存在している注文番号との重複チェックを行う必要があります。
まず、以下のようなSQLを作成しこれをQueryBuilderにて作成しました。

作成したSQL

SELECT COUNT(o.order_number) 
FROM dtb_order o 
WHERE o.order_number = 結合した注文番号

QueryBuilderにて作成

$qb = $em->getRepository('Eccube\Entity\Order')
    ->createQueryBuilder('o')
    ->select('COUNT(o.order_number)')
    ->where('o.order_number = :orderId')
    ->setParameter('orderId', $orderId);
$countOrderId = $qb
    ->getQuery()
    ->getSingleResult();

この際、メモリ不足のエラーが起きてしまったため以下のSQLに変えることにしました。

SELECT 1
FROM dtb_order o 
WHERE o.order_number = 結合した注文番号
LIMIT 1

この際の、QueryBuilderでの記述方法につきまして
ご存知の方がいらっしゃいましたらご教示お願いいたします。
ヒントでも構いません。

よろしくお願いいたします。

追記
・QueryBuilderで作成した新SQL

$qb = $em->getRepository('Eccube\Entity\Order')
    ->createQueryBuilder('o')
    ->select('COUNT(o.order_number)')
    ->where('o.order_number = :orderId')
    ->setParameter('orderId', $orderId)
    ->setMaxResults(1);
$countOrderId = $qb
    ->getQuery()
    ->getSingleResult();

2016/06/30 14:55 追記

$em = $this->app['orm.em'];
$num = 4;←ランダム取得は4桁とする
$array = range(0, 9);←09までを配列に格納する

// 注文日をシステム日付から取得する
$today = date("y/m/d");←システム日付をyymmddの形式で取得
$year = substr($today, 0, 2);←日付のyy部分を取得
$month = substr($today, 3, 2);←日付のmm部分を取得
$day = substr($today, -2);←日付のdd部分を取得

$flg = 0;←重複フラグを設定

while ($flg == 0) {←重複フラグが0の間ループを回す
    shuffle($array);←09の配列をシャッフルする
    $orderNum = substr(implode($array), 0, $num);←シャッフルした配列を左から4桁分取得する

    // 注文番号を10桁に結合する(月+日+年+ランダム4桁)
    $orderId = $month.$day.$year.$orderNum;←mmddyy+ランダム4桁で結合する

    // チェックデジットを取得する
    $cd = $this->editOrderNumber($orderId);
    $editOrderNum = $orderId.$cd;

    // TODO DBを確認し、同じ注文番号がないこと。
    $qb = $em->getRepository('Eccube\Entity\Order')
        ->createQueryBuilder('o')
        ->select('COUNT(o.order_number)')
        ->where('o.order_number = :orderId')
        ->setParameter('orderId', $editOrderNum)
        ->setMaxResults(1);
    $countOrderId = $qb
        ->getQuery()
        ->getResult();
    if ($countOrderId == 0) {←カスタマイズした注文番号が0件の場合はフラグを立てる。1件存在する場合は再度処理を行うためフラグ操作はしない。
        $flg = 1;
    }
}
return $editOrderNum;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

check解決した方法

0

やはり、まだ勉強し始めなので新たなことには挑戦せず
今回は以下のを使用し、カスタマイズ後の注文番号を今回使用しようとしている注文番号でselectし
中身が空の場合にフラグを立てるようにしたいと思います。
これで何とか受注はできているので

$countOrderId = $em->getRepository('\Eccube\Entity\Order')->findBy(array('order_number'=>$editOrderNum));

if (empty($countOrderId)) {
    $flg = 1;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

メモリ不足のエラー とはどのような内容になりますか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 13:59

    Apacheのエラーログは以下の通りです。

    [Thu Jun 30 13:51:01.710082 2016] [:error] [pid 9568:tid 1856] [client ::1:61415] PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 552 bytes) in C:\xampp\htdocs\eccube-3.0.10\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOStatement.php on line 91, referer: http://localhost/eccube-3.0.10/html/index_dev.php/cart

    キャンセル

  • 2016/06/30 14:09

    物理メモリに余裕があるなら、
    一度試していただきたいことが。

    ソース側を修正するなら
    ini_set('memory_limit', '512M');//512Mでなくてもよいです。

    php.ini側を修正するなら
    memory_limit = 128M //128Mでなくてもよいです
    ※アパッチの再起動が必要です。

    キャンセル

  • 2016/06/30 14:22

    php.iniを修正し、128Mと256Mにもして試してみましたが
    同じエラーが出てしまいましたね…

    正確にはmemory sizeの部分が256Mでは上と同じで
    128Mの場合はAllowed memory size of 134217728 bytes exhausted

    当然のようではありますが…
    となりました

    ソース側の修正というのはどの部分になるのでしょうか?

    キャンセル

0

DQLLimit

これでいけませんかね?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 14:34

    私の作り方が悪いまたは間違っているのかもしれませんが
    質問の方に、上記参考サイトに載っていたやり方で作成してみたものを追記します。

    ご確認お願いいたします。

    キャンセル

0

Limitの取り方は上記コードで問題ないと思いますよ。

どういう結果セットを受け取りたいのか解りませんが

->getSingleResult()


では複数件の結果があった場合もしくは無かった場合エラーとなるので

->getResult()


で結果取得を行う方が良いかと思いますよ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 14:53

    結果としては、カスタマイズした注文番号で検索をかけて
    該当するものが存在した場合には再度カスタマイズし直しということにしています。

    前後の部分含め、説明に不足があったかと思うので再度追記させていただきます。

    キャンセル

0

「カスタマイズした注文番号」という言葉が独り歩きしているような気がします。
任意のルールでつくればよほどのことがない限りかぶることはないと思いますが
たとえば日時をミリ秒単位でシードにするとか・・
どのようなロジックでカスタマイズしているのか提示したほうがよいかも

また注文番号を探してなければ挿入とするよりは、
注文番号をユニーク属性にしてIGNOREでINSERTしたうえで、
影響があったかどうかカウントしたほうが効率的かも

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 15:18

    カスタマイズ後の注文番号がチェックデジットを付与して11桁という仕様のため
    ランダム文字含めて10桁となります。

    そこで、
    日付を2桁ずつの6桁と4桁のランダムで作ることになりました。
    10桁をシャッフルしてその中の配列を前から4桁でとるため基本的には被ることはないと思いますが万が一被ってしまった際に注文番号のため誤オペが発生することが考えられます。
    そのため、すでに存在していないかチェックを行う必要あり(日付が変わると注文番号の上位桁が変わるため大丈夫なのですが同一日付内ではランダム部分が被ってしまった際に注文番号が被ってしまうためチェックが必要)
    よほどのことがなければ、このやり方も被ることはないと思いますが…

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    24510questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    7133questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • EC-CUBE

    317questions

    EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

  • Doctrine2

    20questions

    Doctrine 2.0はPHP(5.3.2+)のORMです。Doctrine1.2はActive Recordのパターンを使っているのに対し、Doctrine 2はData Mapperパターンを使います。Doctrineのプロジェクトはデータベースの抽象性とPHPで書かれたORMを扱うためのオープンソースのライブラリとツールの集合です。