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

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

ただいまの
回答率

91.35%

  • PHP

    15152questions

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

  • CakePHP

    1940questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • MySQL Workbench

    17questions

    MySQL Workbenchは、オープンソースのデータベースモデリングツールです。ビジュアルなデータベース設計・SQL開発・サーバー設定・ユーザー管理・バックアップといった様々な管理ツールを備えます。

Cakephp3で多次元配列に入っている価をDBにInsertとUpdateしたいです。

解決済

回答 3

投稿 2017/12/01 19:09

  • 評価
  • クリップ 0
  • VIEW 63

lovelydai

score 16

こんにちは!
ローカルにあるCSVファイルを読み込んで、サーバーに送信し、それをDBにインサートする機能を作ろうとしています。
ファイルの中身を読み取るのは成功し、Cakephp3にAjaxで投げて以下のような多次元配列csvContensを作りました。(ファイルの1行目はフィールド名が書いてあるので、2行目から読み取って配列インデックスは1からになりました。)

イメージ説明

この配列をForeach等でループを回し、DBのTable(Section)に入っているフィールド値と比較し、一致する情報があれば配列価でUpdateの更新し、一致する情報がなければInsertで追加することがしたいです。
DBのフィールドと値は以下のように入っています。

イメージ説明

しかし、この2つの連想配列をどういう風に扱い、比較し、DBに入れればいいか、がよく分かりません。
何かアドバイスか、ヒントになれるようなことあれば教えてください。
宜しくお願い致します。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • yambejp

    2017/12/01 20:57

    ソースはテキストで書き起こし、DBに登録するならどういった構造なのかも記載して下さい

    キャンセル

回答 3

+1

cakephp勉強中のものです!
以下のようなやり方ではどうでしょうか?
1 .

<?php
namespace App\Controller;

use Cake\ORM\TableRegistry;

class TestsController extends AppController
{
    public function index()
    {
        $csvContents=[
            [9999,2017,1,99,'テスト','テスト','ああ',true,null,null],
            [8888,2017,1,88,'トステ','トステ','いい',false,null,null],
        ];

        $tests=TableRegistry::get('Tests');
        foreach($csvContents as $c){
            if($tests->find('all')->where(['section_idx'=>$c[0]])->count()){
                $test = $tests->get($c[0]);
            }else{
                $test = $tests->newEntity();
            };
            $test->section_idx = $c[0];
            $test->year = $c[1];
            $test->customer_idx = $c[2];
            $test->section_code = $c[3];
            $test->section_name = $c[4];
            $test->section_short = $c[5];
            $test->memo = $c[6];
            $test->is_used = $c[7];
            $test->deleter = $c[8];
            $test->deleted = $c[9];
            $tests->save($test);
        }
    }
}

2 .
MySQLを使っているのであればREPLACE INTOを使う方法もあるみたいです。
updateではなく、delete→insertらしいですけど、
MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.8 REPLACE 構文

<?php
namespace App\Controller;

use Cake\Datasource\ConnectionManager;
use PDO;

class TestsController extends AppController
{
    public function index()
    {
        $csvContents=[
            [9999,2017,1,99,'テスト','テスト','ああ',true,null,null],
            [8888,2017,1,88,'トステ','トステ','いい',false,null,null],
        ];
        $conn = ConnectionManager::get('default');
        foreach($csvContents as $c) {
            $stmt = $conn->prepare("REPLACE INTO tests VALUES(?,?,?,?,?,?,?,?,?,?)");
            $stmt->execute($c);
        }
    }

}

投稿 2017/12/02 13:45

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

checkベストアンサー

0

まず「何の目的でそれがしたいのか」ということを書いた方がいいかと思います。
そうでないと「目的を達成する為の別の方法の提案」を他の方もできないからです。

質問の中身に戻りますが、やりたいことを端的に言うと
1.CSVを読み込む
2.読み取ったデータでDBを更新
それに加えて、下記でしょうか
3.CSVのカラムにはあって、DBのテーブルにはないカラムは自動的にDBにカラム追加する

もし上記の認識が間違っていたら申し訳ありませんが、
3.の方法はまず普通やらないです。
CSVの内容次第でDBの構造が変わるなんて言うのは怖すぎて運用できないです。
仮にそれをやるにしても追加するカラムのカラムの制約もCSVに書くのでしょうか?
とても現実的ではないですよね。
CSV自体が間違っていた場合など、意味のわからないゴミカラムは増えていきますし、
じゃあCSVに存在しないカラムは削除するのかとすると、何かの拍子に既存のカラムを削除してしまい、今までのデータが壊れるリスクと常に隣り合わせです。よってやめた方がいいです。

もし後から項目が追加されるというのであれば、
項目追加の度にDBのテーブルにカラムを追加すべきです。
あるいは、後からどんどん追加されていくような項目に関しては、カラムを1つ用意して、そこにjson形式で保管しておくという方法もあります。※DBに保管する際、jsonはただの文字列になり、記述形式も単純な文字列とは違う為、SQL文による検索や絞り込みでは使えなくなりますので、そういう点では注意

その他、読み取ったCSVに関してですがただの配列ではなく、CSVのヘッダーも読み取って連想配列にしてやらないとDBのどのカラムに対して更新をかける項目なのかがわからないですね。

投稿 2017/12/02 09:39

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/04 15:31

    ありがとうございます。配列をまるごと比較しようと思った時点でちょっとまって!と。
    CSVファイルを1行づつ読んで、フォーマットなどをチェックし、DBにあるか確認し、あれば更新、なければ登録というやり方の方がもっと簡単ですね。考え直すきっかけとなりました。

    キャンセル

0

こんな感じで書き直しました。
2つの配列を比較することは、うーん、あまりにもよくないですね。w

CSVファイルを1行づつよみ、DBにあるか確認してそれぞれ処理するようになりました。

foreach($csvContents as $key => $csvContent)
                {
                    $csv_section_idx = $csvContent[0];
                    $csv_section_year = $csvContent[1];
                    $csv_customer_idx = $csvContent[2];

                    echo "Loop is : " . $key. " " . " ";

                    if($customer_idx == $csv_customer_idx)
                    {
                        $section = $this->Section->find()->where(['customer_idx' => $customer_idx])
                                                        ->andWhere(['section_idx' => $csv_section_idx])                    
                                                        ->andWhere(['year' => $csv_section_year])
                                                        ->select(['section_idx','year','customer_idx','section_code','section_name','section_short','memo','is_used','deleter','deleted'])
                                                        ->toList();

                        if(empty($section))
                        {
                            echo "result : Insert with " . "csv_section_idx : " . $csv_section_idx . " csv_section_year : " . $csv_section_year . " ";

                        }
                        else
                        {
                            echo "result : update with " . "csv_section_idx : " . $csv_section_idx . " csv_section_year : " . $csv_section_year . " ";
                        }
                    }
                    else
                    {
                        echo "result : error , ";
                        // error
                    }



                }

投稿 2017/12/04 15:33

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

ただいまの回答率

91.35%

関連した質問

  • 解決済

    xcodeでの画面サイズ変更方法

    swiftでサンプルコードを写しているのですが、参考書を今まで放置してたのでxcodeのバージョンが違うので画面サイズ変更の方法がわからないです。 simulatorでの表示画面

  • 解決済

    Blender Game Engineでマテリアルを透過したい

    Blenderでゲーム開発をしようとしているものです。 Blender Renderで透過処理したマテリアルをBlender Gameに反映させたいと思っているのですが、透過でき

  • 解決済

    ACCESS クエリでの一部重複?の除外方法について

    前提・実現したいこと こんにちは、質問タイトルが適格でないかもしれませんが宜しくお願いいたします。 通販事業をしており、商品の仕入から販売までのデータベースをACCESSの

  • 解決済

    ChromeのDeveloper Toolに関して

    Chrome Developer Toolを用いてcakePHPでできているwebサイトのサーバー内での処理速度を調べたいのですが 「Network」タブや「Timeline」タ

  • 受付中

    この場合キャッシュが効くのか

    キャッシュが効いているのかわかりません headerにCache-Control=no-cacheを指定しているがETagやLast-Modifiedを指定しない場合、

  • 解決済

    GAS(google apps script)で一つのスプレッドシート内にある複数のスクリプトの挙動...

    GASに詳しい方、教えていただけますと助かります。 表題の件、一つのスプレッドシートに対してスクリプトが複数あってそれぞれに同じトリガーを設定している場合、そのトリガーが入っ

  • 受付中

    ER図について

    つぶやきアプリを作っているのですが、 ER図を作るとする例えばどんなものがありますか?? サンプル程度でいいので教えていただきたいです

  • 解決済

    pycharmのpython console部分の色の変更

    プログラムには関係ないんですが・・・ 長時間PCの画面を見てると目が疲れてしまうので、色を変えてみようと思って 色を変更してみたのですが、python consoleの部分の色

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

  • PHP

    15152questions

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

  • CakePHP

    1940questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • MySQL Workbench

    17questions

    MySQL Workbenchは、オープンソースのデータベースモデリングツールです。ビジュアルなデータベース設計・SQL開発・サーバー設定・ユーザー管理・バックアップといった様々な管理ツールを備えます。