PHPで、update&prepareステートメントを使って、

codeフィールドに連番を振りたいのですが出来ません。

--サンプルレコード
countr,name,code
usa,Sharon,
jp,Koji,
cn,wan,
cn,ree,
usa,Tom
cn,Yan,
jp,Kenji,
jp,Tae,

codeフィールドに国別に最初の3桁を国番号、
次の4桁がその国の個人番号で連番
例えば
--usa
countr,name,code
usa,SHaron,001001
usa,Tom,001002

--中国
countr,name,code
cn,wan,0860001
cn,ree,0860002
cn,Yan,0860003

--日本
countr,name,code
jp,Koji,0810001
jp,Kenji,0810002
jp,Tae,0810003

私に書いたサンプルコードは以下です。
http://1811way.com/work008/sample20140531.txt
抽出条件(例えばusa)での件数を出す所ですでにエラーになっています。

なお、自分で考えて書きましたが、
件数を出す->この件数だけ1回ごとにcodeを更新する
という方法にこだわっておりません。
何か別の方法でも教えていただければ大変助かります。
よろしくお願いします。
環境:PHP5.3、localhost(appache2.2),Windows7

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2014/05/31 11:35:01
  • 終了:2014/05/31 16:12:37

ベストアンサー

id:snow0214 No.3

snow0214回答回数470ベストアンサー獲得回数1162014/05/31 15:22:06

ポイント300pt
  1. テーブル名に [test01] と [test02] がありますが、[test02] に統一しました。
  2. フィールド名 [country] の綴りが違っていたので、DBの方を修正しました。
  3. PDOではマッチしたレコード数を返す適当な方法がありません。いったんfetchしてカウントしました。コメントアウトしている箇所がカウントする処理です。
  4. 国別コード表を配列に用意して、一気にupdateできるようにしました。

このコードを試してみてください。

<?php
//国別コード表
$CountryCode = array(
'usa'=>'001',
'cn'=>'086',
'jp'=>'081'
);

try {
    $dbh = new PDO('mysql:host=localhost;dbname=urank','****','****');

    //抽出条件(例えばusa)での件数を出す
/**
    $counter = 0;
    $sql = "SELECT count(*) FROM test02 where country = 'usa'";
    if ($res = $dbh->query($sql)) {
        if ($res->fetchColumn() > 0) {
            $sql = "SELECT * FROM test02 where country = 'usa'";
            foreach ($dbh->query($sql) as $row) $counter++;
        }
    }
    echo $counter;
**/

    //Updateする
    $counter['success'] = 0;
    $counter['failure'] = 0;
    foreach ($CountryCode as $country=>$code) {
        $sql1 = "SELECT * FROM test02 where country = '{$country}'";
        $i = 1;
        foreach ($dbh->query($sql1) as $row) {
            $sql2 = 'UPDATE test02 SET code = :code where country = :country and name = :name';
            $stmt = $dbh->prepare($sql2);
            $stmt->bindParam(':code', sprintf("%s%04d", $code, $i), PDO::PARAM_STR);
            $stmt->bindParam(':country', $country, PDO::PARAM_STR);
            $stmt->bindParam(':name', $row['name'], PDO::PARAM_STR);
            $res = $stmt->execute();
            if ($res)   $counter['success']++;
            else        $counter['failure']++;
            $i++;
        }
    }
    echo '更新成功 ' . $counter['success'] . '件/更新失敗' . $counter['failure'] . '';

} catch (PDOException $e) {
    var_dump($e->getMessage());
    exit;
}
?>
id:kohhi

いつも教えていただいてありがとうございます。
warningのようなメッセージは出ましたが、出来ました。
素晴らしいです。
教えていただいたリストをよく読みこんでみます。

なお、warningのようなメッセージは、
Strict Standards: Only variables should be passed by reference in C:\****.php on line 34
で、更新レコードの数だけ出ます。
phpのバージョンは5.3.8ですが、
僕のが古いのかもしれません。

更新は出来たので、この質問は締めさせていただきます。
上記メッセージの対処法、急ぎではありませんので、
コメントいただけると助かります。

ありがとうございました。

2014/05/31 16:11:32

その他の回答(2件)

id:pogpi No.1

POGPI回答回数377ベストアンサー獲得回数502014/05/31 12:38:20

ポイント40pt

「SELECT COUNT(*) AS cnt」として、PDOの例じゃないのであれですが、
$kekka = mysql_fetch_array($result,MYSQL_ASSOC)
$cnt = $kekka['cnt'];
で、件数は取れます。

他1件のコメントを見る
id:pogpi

ユーザーIDは国ごとの連番が良ければ、ユーザー国usercountry(countryid(foreign key),連番renban,userid(foreign key))を新たに作るとか。

2014/05/31 14:14:36
id:pogpi

そうすれば、codeフィールドは必要なくなりませんか。

2014/05/31 14:16:06
id:gizmo5 No.2

gizmo5回答回数484ベストアンサー獲得回数1382014/05/31 13:19:38

ポイント40pt

PDO は execute で SQL を実行して、fetch でデータを取り出します。
件数を取り出すあたりを以下のようにしてみてください。

	//抽出条件(例えばusa)での件数を出す
	$sql = "SELECT count(*) FROM test02 where country = 'usa'"; 
	$result = $dbh->prepare($sql); 
	$result->execute();
//	echo (int)$result;
	$data = $result->fetch(PDO::FETCH_NUM);
	echo $data[0];

	//件数分だけUpdateする
	$i = 0;
	for($i;$i<=$data[0];$i++){		//  $data[0] が件数
		...

http://www.php.net/manual/ja/pdostatement.execute.php
http://www.php.net/manual/ja/pdostatement.fetch.php

id:kohhi

早速お返事いただきありがとうございました。
指示に従って変えてあります。
http://1811way.com/work008/sample20140531.txt

codeフィールドに国別に最初の3桁を国番号
ではなく、簡単にするために
$i
を入れるようにしました。

    • 以下更新部分のリスト

//件数分だけUpdateする
$i = 0;
for($i;$i<=$data[0];$i++){ // $data[0] が件数
$stmt = $dbh->prepare("UPDATE test02 SET code = $i where country = :country");
$country = 'usa';
$stmt->bindParam(':country', $country, PDO::PARAM_STR);
$res = $stmt->execute();
if ($res) {
echo "更新完了" .$i;
}
else {
echo "更新失敗";
}
}

    • 以上

すべてのレコードに「2」(country = 'usa'だった時の件数、$data[0]の値)
が入ってしまいます。
お手数掛けてすいません。
アドバイスいただけると助かります。

2014/05/31 15:47:07
id:snow0214 No.3

snow0214回答回数470ベストアンサー獲得回数1162014/05/31 15:22:06ここでベストアンサー

ポイント300pt
  1. テーブル名に [test01] と [test02] がありますが、[test02] に統一しました。
  2. フィールド名 [country] の綴りが違っていたので、DBの方を修正しました。
  3. PDOではマッチしたレコード数を返す適当な方法がありません。いったんfetchしてカウントしました。コメントアウトしている箇所がカウントする処理です。
  4. 国別コード表を配列に用意して、一気にupdateできるようにしました。

このコードを試してみてください。

<?php
//国別コード表
$CountryCode = array(
'usa'=>'001',
'cn'=>'086',
'jp'=>'081'
);

try {
    $dbh = new PDO('mysql:host=localhost;dbname=urank','****','****');

    //抽出条件(例えばusa)での件数を出す
/**
    $counter = 0;
    $sql = "SELECT count(*) FROM test02 where country = 'usa'";
    if ($res = $dbh->query($sql)) {
        if ($res->fetchColumn() > 0) {
            $sql = "SELECT * FROM test02 where country = 'usa'";
            foreach ($dbh->query($sql) as $row) $counter++;
        }
    }
    echo $counter;
**/

    //Updateする
    $counter['success'] = 0;
    $counter['failure'] = 0;
    foreach ($CountryCode as $country=>$code) {
        $sql1 = "SELECT * FROM test02 where country = '{$country}'";
        $i = 1;
        foreach ($dbh->query($sql1) as $row) {
            $sql2 = 'UPDATE test02 SET code = :code where country = :country and name = :name';
            $stmt = $dbh->prepare($sql2);
            $stmt->bindParam(':code', sprintf("%s%04d", $code, $i), PDO::PARAM_STR);
            $stmt->bindParam(':country', $country, PDO::PARAM_STR);
            $stmt->bindParam(':name', $row['name'], PDO::PARAM_STR);
            $res = $stmt->execute();
            if ($res)   $counter['success']++;
            else        $counter['failure']++;
            $i++;
        }
    }
    echo '更新成功 ' . $counter['success'] . '件/更新失敗' . $counter['failure'] . '';

} catch (PDOException $e) {
    var_dump($e->getMessage());
    exit;
}
?>
id:kohhi

いつも教えていただいてありがとうございます。
warningのようなメッセージは出ましたが、出来ました。
素晴らしいです。
教えていただいたリストをよく読みこんでみます。

なお、warningのようなメッセージは、
Strict Standards: Only variables should be passed by reference in C:\****.php on line 34
で、更新レコードの数だけ出ます。
phpのバージョンは5.3.8ですが、
僕のが古いのかもしれません。

更新は出来たので、この質問は締めさせていただきます。
上記メッセージの対処法、急ぎではありませんので、
コメントいただけると助かります。

ありがとうございました。

2014/05/31 16:11:32

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません