# Question02 - 検索系SQL(パラメータあり) 本資料の練習問題は、複数のプログラミング言語(Java / PHP / C# / Python)で共通して利用できるよう記述されています。使用するデータベース接続の仕組み(JDBC、PDO、ADO.NET、DB-API 2.0準拠のドライバ など)やSQLへのパラメータの指定方法、自動採番された値の取得方法など、言語・環境固有の仕様に基づき、問題文の表現をご使用の環境の仕様に適宜読み替えて進めてください。 [共通の前提](../00.共通前提.md)を参照してください。 ## この問題のねらい - 実行のたびに異なる値(パラメータ)をSQLの実行結果に反映させる方法を理解する - SQLに値を直接埋め込むのではなく、プレースホルダ(バインド変数。Java: `PreparedStatement`/PHP: `PDOStatement`(`PDO::prepare()`)/C#: `SqlCommand`の`Parameters`/Python: DB-API 2.0の`cursor.execute()`へのパラメータ指定 など、各言語のデータベース接続の仕組みにおけるプレースホルダに相当するもの)を使って安全に値を渡せること 以下の設問はそれぞれ独立したプログラムとして実装してください。 ## ファイル名・フォルダ構成 - 設問ごとに1つのフォルダを作成し、そのフォルダの直下にプログラムのファイルを配置すること。 - フォルダ名は、設問番号に対応した連番(`question01`、`question02`、…)とすること(全言語共通・小文字)。 - ファイル名は、設問番号に対応した連番(`Question01`、`Question02`、…)を基本とし、言語の慣習に合わせて次のとおりとすること。 - 本問題(Question02-SelectWithParameter)の構成は次のとおり。 ``` Question02-SelectWithParameter/ ├── question01/    ← 設問1 │ └── Question01.<拡張子> ├── question02/    ← 設問2 │ └── Question02.<拡張子> └── question03/    ← 設問3 └── Question03.<拡張子> ``` - Java: `Question01.java`(公開クラス名もファイル名と同じ `Question01` とする) - C#: `Question01.cs` - PHP: `Question01.php` - Python: `question01.py`(モジュール名は小文字とする慣習のため、ファイル名のみ小文字) - 上記ツリー中の `Question01.<拡張子>` は、使用する言語に応じて上記のファイル名に読み替えること。 - プロジェクトファイルが必要な場合など、言語・開発環境の規則上やむを得ない場合は、その規則を優先してよい。その場合も、設問ごとのフォルダ分けと連番の命名は維持すること。 - 設問内で追加で作成するクラス・関数などは、その設問のフォルダ直下に配置すること。 - 他の設問で作成したクラス等を使用する設問では、各フォルダ単独で実行できるよう、そのフォルダ直下にも同じ内容を配置すること。 --- ## 設問1 標準入力から部署IDを受け取り、その部署IDに一致する部署のデータ(部署ID・部署名)をタブ区切りで出力するプログラムを実装してください。 ### 手順・要件 1. 次の処理を、有効な入力が得られるまで繰り返してください。 1. 「検索する部署IDを入力してください」と表示する 2. 標準入力から1行分のテキストを読み込む 3. 読み込んだ内容が整数として解釈できない場合、「数値を入力してください」と表示し、手順1に戻る 4. 整数として解釈できた場合、その値を部署IDとして繰り返し処理を終了する 2. 確定した部署IDを使って、部署テーブルから一致するデータを検索する。この際、SQLに値を直接埋め込むのではなく、プレースホルダ(バインド変数。Java: `PreparedStatement`/PHP: `PDOStatement`(`PDO::prepare()`)/C#: `SqlCommand`の`Parameters`/Python: DB-API 2.0の`cursor.execute()`へのパラメータ指定 など)を使用して値を渡すこと 3. 検索結果が存在する場合、その部署ID・部署名をタブ区切りで出力する 4. 検索結果が存在しない場合、「一致する部署は見つかりませんでした」と出力する ### 実行例 - 入力が `2` の場合 - 出力:`2 人事部` - 入力が `99`(存在しない部署ID)の場合 - 出力:`一致する部署は見つかりませんでした` - 入力が `abc`(数値でない)の場合 - 出力:`数値を入力してください`(その後、再度入力を促す) --- ## 設問2 標準入力から部署名の一部の文字列を受け取り、部署名にその文字列を含む部署のデータ(部署ID・部署名)を、部署IDの昇順で、1件につき1行、タブ区切りで出力するプログラムを実装してください(該当するデータは0件・1件・複数件のいずれの場合もあります)。 ### 手順・要件 1. 「検索する部署名の一部を入力してください」と表示する 2. 標準入力から1行分のテキストを読み込む 3. 読み込んだ文字列を部署名に含む部署のデータを、部署テーブルから検索する。この際、SQLに値を直接埋め込むのではなく、プレースホルダ(バインド変数。Java: `PreparedStatement`/PHP: `PDOStatement`(`PDO::prepare()`)/C#: `SqlCommand`の`Parameters`/Python: DB-API 2.0の`cursor.execute()`へのパラメータ指定 など)を使用し、部分一致検索に対応した形で値を渡すこと 4. 検索結果が1件以上存在する場合、該当するすべてのデータを部署IDの昇順でタブ区切りで出力する 5. 検索結果が存在しない場合、「一致する部署は見つかりませんでした」と出力する ### 実行例 - 入力が `部` の場合 - 出力: ``` 1 営業部 2 人事部 3 開発部 ``` - 入力が `営業` の場合 - 出力:`1 営業部` - 入力が `総務`(一致するものがない文字列)の場合 - 出力:`一致する部署は見つかりませんでした` --- ## 設問3 標準入力から部署IDの下限値を受け取り、その値**以上**の部署IDを持つ部署のデータ(部署ID・部署名)を、部署IDの昇順で、1件につき1行、タブ区切りで出力するプログラムを実装してください。 ### 手順・要件 1. 次の処理を、有効な入力が得られるまで繰り返してください。 1. 「検索する部署IDの下限値を入力してください」と表示する 2. 標準入力から1行分のテキストを読み込む 3. 読み込んだ内容が整数として解釈できない場合、「数値を入力してください」と表示し、手順1に戻る 4. 整数として解釈できた場合、その値を下限値として繰り返し処理を終了する 2. 確定した下限値を使って、部署テーブルから、部署IDがその値以上であるデータを検索する。この際、SQLに値を直接埋め込むのではなく、プレースホルダ(バインド変数。Java: `PreparedStatement`/PHP: `PDOStatement`(`PDO::prepare()`)/C#: `SqlCommand`の`Parameters`/Python: DB-API 2.0の`cursor.execute()`へのパラメータ指定 など)を使用し、比較演算子を伴う条件として値を渡すこと 3. 検索結果が1件以上存在する場合、該当するすべてのデータを部署IDの昇順でタブ区切りで出力する 4. 検索結果が存在しない場合、「一致する部署は見つかりませんでした」と出力する ### 実行例 - 入力が `2` の場合 - 出力: ``` 2 人事部 3 開発部 4 東京支店 5 大阪支店 ``` - 入力が `10`(該当するデータがない値)の場合 - 出力:`一致する部署は見つかりませんでした`