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

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

新規登録して質問してみよう
ただいま回答率
85.50%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

4回答

62158閲覧

ある値がデータベースに登録済かどうかをチェックする

earnest_gay

総合スコア615

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1グッド

8クリップ

投稿2016/05/16 08:08

編集2016/05/16 08:30

「ログインする際の重複アドレスがないかどうか」

を昨日からずっとやってるんですが、解決しないです。

ある値がデータベースに登録済かどうかをチェックするには、データ(アドレスのカラム)の行数
をカウントするSQL文を使用する
らしいんですが、、、

知りたいのは行数のカウントじゃなくて、登録されているアドレスそのものなのにどういうことなんだ?ってなって頭がぐるぐる回ってます...

「行数のカウントを取得するということは・・・・・」

「つまり・・・・・」

「したがって、・・・・・・」

その場だけの記述を覚えても理解しないと応用できないので、分かりやすく解説頂けると助かります。

sql文はPDOではなくsqliを使っています。
参考書の記述と解説がほとんどsqliでPDOではない為です。

宜しくお願いいたします。

≪追記≫

思った以上に回答してくださる方がいらっしゃいますので、質問を具体的にする為、サンプルのソースを追記します。

冒頭で、「ログインする際の重複アドレスがないかどうか」と記載しておりますが、誤りです。

「新規登録する際の重複アドレスがないかどうか」です。

宜しくお願いします。

// 重複アカウントのチェック if (empty($error)) { $sql = sprintf('SELECT COUNT(*) AS cnt FROM members WHERE email="%s"', mysqli_real_escape_string($db, $_POST['email']) ); $record = mysqli_query($db, $sql) or die(mysqli_error($db)); $table = mysqli_fetch_assoc($record); if ($table['cnt'] > 0) { $error['email'] = 'duplicate'; } } <input type="text" name="email" size="35" maxlength="255" value="<?php echo htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8'); ?>" /> <?php if ($error['email'] == 'blank'): ?> <p class="error">* メールアドレスを入力してください</p> <?php endif; ?> <?php if ($error['email'] == 'duplicate'): ?> <p class="error">* 指定されたメールアドレスはすでに登録されています</p> <?php endif; ?>
KiyoshiMotoki👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

useridに「abc」という登録が既にあるかどうか確認するのに
select count(*) from usertbl where userid = 'abc'
とすれば、存在すれば1以上、無ければ0が出力されるので、プログラム上でture/falseのように使えて便利ということだと思いますよ。

投稿2016/05/16 08:17

hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/05/16 08:46

回答ありがとうございます。 where userid = 'abc' この'abc'の部分が入力されるアドレス すなわち、$_REQUEST[email]なら辻褄は会うのですが、サンプルソースではこのようになっています。 ,,, // 重複アカウントのチェック if (empty($error)) { $sql = sprintf('SELECT COUNT(*) AS cnt FROM members WHERE email="%s"', mysqli_real_escape_string($db, $_POST['email']) ); $record = mysqli_query($db, $sql) or die(mysqli_error($db)); $table = mysqli_fetch_assoc($record); if ($table['cnt'] > 0) { $error['email'] = 'duplicate'; } } <input type="text" name="email" size="35" maxlength="255" value="<?php echo htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8'); ?>" /> <?php if ($error['email'] == 'blank'): ?> <p class="error">* メールアドレスを入力してください</p> <?php endif; ?> <?php if ($error['email'] == 'duplicate'): ?> <p class="error">* 指定されたメールアドレスはすでに登録されています</p> <?php endif; ?> ,,,
hirohiro

2016/05/16 08:52

>>$_REQUEST >>$_GET、 $_POST そして $_COOKIE の内容をまとめた連想配列です。 http://php.net/manual/ja/reserved.variables.request.php サンプルソースではformから送られてくる想定のようですね。 それでmembersテーブルのemail要素に「$_POST['email']」と同じ値が存在すればcntに1以上、無ければ0が出力されると思います。 それを「if ($table['cnt'] > 0) 」で判定していますね。
退会済みユーザー

退会済みユーザー

2016/05/16 08:56

sprintf関数とmysqli_real_escape_stringが入っているため混乱されているのかもしれませんが最終的に生成されるsql文は SELECT COUNT(*) AS cnt FROM members WHERE email="POSTされたメールアドレス" になりますよ
earnest_gay

2016/05/16 15:17

回答ありがとうございます。 SELECT COUNT(*) AS cnt FROM members WHERE email="POSTされたメールアドレス" これを知れただけでもかなり進歩です。 email="%s"',はなんなのでしょう? ,で区切られているのでなんなんだろうと思ってましたが単純に WHERE email=mysqli_real_escape_string($db, $_POST['email']) ではダメなのでしょうか?
退会済みユーザー

退会済みユーザー

2016/05/16 19:12

email="%s" に関してはsprintf関数を調べてみるのがいいと思います。 sprintfを使わない場合 $sql='(略)WHERE email="'. mysqli_real_escape_string($db, $_POST['email']). '"'; とする必要があります。 whereに指定するパラメータが今回は1つだけなのでこれでもいいのですが、パラメータが増えるほど可読性が下がるのでこうなっているのだと思います。 ただしmysqliならbind_paramを使うべきですので質問の内容とかなりずれてしまいますが http://php.net/manual/ja/mysqli.prepare.php や「mysqli 手続き側」で検索してみてmysqli自体の使い方をきちんと調べた方がよさそうですね
guest

0

SQLでWHEREに判定したい条件を書いて、とりあえず判定は無視してSELECTするとします。すると、

  • データがある時→ヒットしたデータが1行以上返ってくる
  • データがない時→1件もマッチしないので、結果は0行

ということになるので、「条件を満たすデータがあるか」はすなわち、「SELECTして1行以上取れるか」ということと同値になります。

行数さえわかればいいので、SELECT 1 FROM テーブル名 WHERE 条件 LIMIT 1のように実質のデータを取ってこずに結果セットの行数だけ別途で調べるのもありですし、COUNT(*)で行数を数えてしまうのも、状況によっては便利です。

なお、「重複したデータをDBに入れない」ためには、UNIQUEインデックスを使いましょう。アプリケーションレベルで対応するより楽で確実です(ほぼ同時に同じ値を書き込もうとするような場合にも防いでくれます)。

投稿2016/05/16 08:21

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/05/16 09:04

回答ありがとうございます。 UNIQUEインデックスの応用もどこかで見かけましたが、例外をcatchする方法が分からないのです...。
guest

0

「ログインする際の重複アドレスがないかどうか」

ですが重複アドレスの確認が必要になるのはログイン時ではなくユーザー登録時ではないでしょうか。

ログインの際に必要になる動作はメールアドレス(ユーザーID)からパスワード等のデータを取得するといった流れになるかと思います。

ユーザー登録時でしたら重複を調べる際にユーザーが入力したメールアドレスで検索を行うと思います。
つまりDBからメールアドレスを取得するまでもなく既に確認したいメールアドレスは判明しているわけです。

判明しているメールアドレスを再度DBから取得しても何も意味はありませんので、検索するメールアドレスを含むレコードの件数が0か1(または1以上)かがわかれば「そのメールアドレスは既に使用されています。」という判断が下せるということになります。

いずれの場合でもメールアドレスを元にデータを検索する以上、メールアドレスを取得する必要はないかと思います。

投稿2016/05/16 08:20

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/05/16 08:55

回答ありがとうございます。 ログインする際ではなく新規登録する際でした。 具体的なソースを追記しております。 宜しくお願いいたします。
earnest_gay

2016/05/16 08:57 編集

回答ありがとうございます。 ログインではなく新規登録時の話でした。すみません。 具体的なソースを追記しました。 宜しくお願いいたします。
guest

0

例えば下記のようなテーブルがあった場合。

test_table
email,name
a@test.com, a
b@test.com, b
c@test.com, c

仮にb@test.comが登録されているか確認したいということですよね?
という前提で話を進めると、test_table内にb@test.comが何件あるかで判断がつきますね。
上記テーブル例では登録されているので1件になります。
次に様に登録されていない場合、

test_table
email,name
a@test.com, a
c@test.com, c

0件になります。
ということで件数を数えれば登録済みかどうかの判断がつくということになります。

SQL

1select count(*) from test_table where email='b@test.com' 2

投稿2016/05/16 08:19

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/05/16 08:53

回答ありがとうございます。 select count(*) from test_table where email='b@test.com' この部分は辻褄として理解させていただきました。 実際はこのようなサンプルになっています。 sprintf('SELECT COUNT(*) AS cnt FROM members WHERE email="%s"', mysqli_real_escape_string($db, $_POST['email']) ); 次に分からないことは以下です。 ・sprintfは書式を整えるためのファンクションというのは分かるけど、そのファンクションが何故ここで使われるのか? ・上記ではsprintf(DBから情報を取り出す条件,POST送信内容)のような使い方をしているように見えるのですが、書式を整えるためのファンクションだったのではないのか? というところでぐるぐる回ってます...
ttyp03

2016/05/16 15:20

sprintfの部分に関してはhirohiroさんとのやり取りの中にも解説がありますが、ここでも書いておきます。 sprintfは仰るとおり、書式を整える関数です。 書式は sprintf( フォーマット, 値, ... ) で、書式が整えられた文字列が返却されます。 例えば、sprintf( "email=%s", "b@test.com" ); であれば、戻り値は "email=b@test.com" となります。 ご提示のコードでは、sprintfの引数は、'SELECT~' と mysql_real~ の2つです。 'SELECT ~ "%s"' の %s の部分が、mysql_real~ の値に置き換わります。 mysql_real~は何をしているかというと、詳細はマニュアルを参照してください。 https://secure.php.net/manual/ja/mysqli.real-escape-string.php 「接続の現在の文字セットを考慮して、SQL 文で使用する文字列の特殊文字をエスケープする」とあります。 データベースの接続情報にあわせて、文字列をうまいことやってくれる、程度に考えて良いでしょう。 結果、sprintfは、 SELECT COUNT(*) AS cnt FROM members WHERE email="b@test.com" というクエリ文字列を生成し返却します。 それを $sql で受け取り、mysqli_query関数で投げるという処理になっていますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問