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

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

ただいまの
回答率

87.80%

ADO.NETでのINSERT文について

解決済

回答 1

投稿

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

score 21

Visual Sutaudio2017を使ってADO.NETによるデータベース(SQLServer)プログラミングでWindowsFormを作っています。  

CREATE TABLE [dbo].[IMAGE] (
    [ImageID]   INT             IDENTITY (1, 1) NOT NULL,
    [Photoname] NVARCHAR (50)   NULL,
    [GenreID]     INT             NULL,
    CONSTRAINT [NUM2] PRIMARY KEY CLUSTERED ([ImageID] ASC),
    CONSTRAINT [NUM3] FOREIGN KEY ([Genre]) REFERENCES [dbo].[GENRE] ([GenreID])
);

CREATE TABLE [dbo].[GENRE] (
    [GenreID] INT           IDENTITY (1, 1) NOT NULL,
    [Genre]   NVARCHAR (50) NULL,
    CONSTRAINT [NUM1] PRIMARY KEY CLUSTERED ([GenreID] ASC)
);


というテーブルを作り
[dbo].[IMAGE]

ImageID Photoname Genre
1 A.PNG 1
2 B.PNG 2

[dbo].[GENRE]

GenreID Genre
1 野球
2 サッカー

と格納しました。
新たにデータを格納したくて

 private void button2_Click(object sender, EventArgs e)
        {
             cn.ConnectionString=
                @"・・・";
              cn.Open();
              cmd.Connection = cn;
              cmd.CommandType = CommandType.Text;
            cmd.CommandText = "INSERT INTO [dbo].[GENRE] (Genre) VALUES (" +
                                 "N'" + textBox1.Text + "')" + //GenreをDBに格納
                                 "INSERT INTO [dbo].[IMAGE](Photoname,GenreID) VALUES" +
                                 "( N'" + textBox2.Text + "'," + "(SELECT GenreID FROM[dbo].[GENRE] " +
                                 "WHERE Genre Like N'%" + textBox1.Text + "%'))";
            rd = cmd.ExecuteReader();
            rd.Close(); 
            cn.Close();

            textBox1.Text = "";
            textBox2.Text = "";
            textBox3.Text = "";

        }
//textBox1にはGenreをtextBox2にはPhotonemeを入力します。


で格納し

private void button4_Click(object sender, EventArgs e)
        {
            cn.ConnectionString = cnstr;
            cn.Open();
            cmd.Connection = cn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT * FROM [dbo].[IMAGE] ";
            rd = cmd.ExecuteReader();

            while (rd.Read())
                listBox1.Items.Add(
                    String.Format("[ImageID]{0}[Photoname]{1}[GenreID]{2}",
                                  rd["ImageID"], rd["Photoname"], rd["GenreID"]));
            rd.Close();
            cn.Close();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            cn.ConnectionString = cnstr;
            cn.Open();
            cmd.Connection = cn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT * FROM [dbo].[Genre] ";
            rd = cmd.ExecuteReader();

            while (rd.Read())
                listBox1.Items.Add(
                    String.Format("[GenreID]{0}[Genre]{1}",
                                  rd["GenreID"], rd["Genre"]));
            rd.Close();
            cn.Close();
        }


でテーブルの中身を確認しました。
textBox1に卓球textBox2にC.PNGを入力しボタンを押すと格納できます。
しかしtextBox1に野球textBox2にC.PNGを入力し格納すると

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.


が表示されて格納できません。
なのでGenreが重複していても格納できる方法を教えてください。
ちなみに

"INSERT INTO [dbo].[IMAGE](Photoname,GenreID) VALUES" +
"( N'" + textBox2.Text + "'," + "(SELECT GenreID FROM[dbo].[GENRE] " +
"WHERE Genre Like N'%" + textBox1.Text + "%'))";


でtextBox1に卓球textBox2にC.PNGを入力しボタンを押して格納することとtextBox1に野球textBox2にC.PNGを入力しを入力しボタンを押して格納することはできました。

>>制作物
Windows Form
>>検索
どこが間違っているかわからないので検索していません。
>>開発環境
Visual Sutaudio2017,.NET Framework4.7,SQL Server Express2017,Windows10 

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

以前の質問でGenreIDを取得する際の問題点を指摘したかと思います。
また、「identity列の現在の値を取得する方法を検索してみてください。」とも書きました。
その検索結果がこちらです。
identity列の現在の値を取得する

ついでですが、エラーメッセージを訳すと
「サブクエリが複数の値を返しました。 これは、サブクエリが=、!=、<、<=、>、> =の後に続く場合、またはサブクエリが式として使用される場合は許可されません。 ステートメントは終了されました。」
となります。
ようはSELECTにて複数の結果が返ってきたということです。(この場合は’野球’が2レコード帰ってきたということですね)
それを、identity列の現在の値1つを返すように変更するということです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/19 20:09

    identity列の現在の値は
    ELECT IDENT_CURRENT('テーブル名')
    で取得出来ることは調べてわかりました。
    しかしidentity列の値をwhereを使って取得する方法がわからないので教えてください。(今回の質問に使えるかは分かりません)

    キャンセル

  • 2019/11/19 20:14

    identity列はデータをInsertするたびに自動で加算されます。
    その現在の値というのは、一番新しいデータの値となります。
    Insertした直後に現在の値を取得すれば、そのInsertしたデータの値となります。

    キャンセル

  • 2019/11/20 09:02

    "INSERT INTO [dbo].[GENRE] (Genre) VALUES (" +
    "N'" + textBox1.Text + "')" + //GenreをDBに格納
    "INSERT INTO [dbo].[IMAGE](Photoname,GenreID) VALUES" +
    "( N'" + textBox3.Text + "'," + "(SELECT IDENT_CURRENT('GENRE')))";
    にしたらうまくいきました。
    教えてくださりありがとうございます。

    キャンセル

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

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

関連した質問

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