0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ASP.NETでSQLエラーが発生したときのエラーメッセージの見方

0
Posted at

1.はじめに

新人プログラマーchocorです。
本題は6.から記載しています。
SQLのエラーが苦手でここ見れば分かりやすいと感じたものをメモとして残そうと思いこちらを書かせていただきます。
こうすればわかりやすいなどアドバイスがあれば教えて頂けると嬉しいです。

2.開発環境

VisualStudio 2026
ASP.NET Webアプリケーション (.NET Framework)

3.処理の流れ

Input.aspx
↓
Name / Contentを入力
↓
XMLからINSERT SQLを取得
↓
MyTableへ登録
↓
Output.aspx
↓
XMLからSELECT SQLを取得
↓
Id / Name / Contentを一覧表示

4.サンプルコード

Mytable
Idは自動採番にし、1ずつ増えます
image.png

SQL
<SqlQueries>
・一覧表示
  <Get>
    <![CDATA[
      SELECT  Id,
              Name,
              Content
        FROM  MyTable
      ORDER BY Id
    ]]>
  </Get>

・登録
  <Insert>
    <![CDATA[
      INSERT  INTO MyTable
           (
              Name,
              Content
           )
      VALUES
           (
              @Name,
              @Content
           )
    ]]>
    <Parameter>
      <Input Name="Name" Type="nvarchar" Size="15"/>
      <Input Name="Content" Type="nvarchar" Size="50"/>
    </Parameter>
  </Insert>
</SqlQueries>
Repository.cs
using System.Xml.Linq;
//XMLファイルに書かれているSQLを読み取って、呼び出し元に返すクラス
public class Repository
{
	private readonly XDocument _document;

	public Repository(string filePath)
	{
		_document = XDocument.Load(filePath);
	}

	public string GetSql()
	{
		return _document.Root.Element("Get").Value.Trim();
	}

	public string GetInsertSql()
	{
		return _document.Root.Element("Insert").Value.Trim();
	}
}
Input.aspx
<!DOCTYPE html>
<html>
	<head runat="server">
	    <title>入力画面</title>
	</head>
	<body>
	    <form id="form1" runat="server">
	        <div>
	            <h2>入力画面</h2>
	            <div>
	                <asp:Label ID="NameLabel" Text="Name" runat="server"/>
	                <asp:TextBox ID="NameTextBox" MaxLength="15" runat="server" />
	            </div>
	            <div>
	                <asp:Label ID="ContentLabel" Text="Content" runat="server"/>
	                <asp:TextBox ID="ContentTextBox" MaxLength="50" TextMode="MultiLine" runat="server"/>
	            </div>
	            <div>
	                <asp:Button ID="RegisterButton" Text="登録" OnClick="RegisterButton_Click" runat="server"/>
					<br/>
					<asp:HyperLink ID="InputLink" NavigateUrl="Output.aspx" Text="出力画面へ" runat="server"/>
	            </div>
	        </div>
	    </form>
	</body>
</html>
Input.aspx.cs
using System;
using System.Configuration;
using System.Data.SqlClient;

namespace test
{
	public partial class Input : System.Web.UI.Page
	{
  //ボタンを押したら
protected void RegisterButton_Click(object sender, EventArgs e)
{
	// XMLからINSERT用SQLを取得
	Repository repository = new Repository(Server.MapPath("~/Sql/test.xml"));
	string sql = repository.GetInsertSql();
	string connectionString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
	using (SqlConnection connection = new SqlConnection(connectionString))

	// 入力値をSQLに設定
	using (SqlCommand command = new SqlCommand(sql, connection))
	{
		command.Parameters.AddWithValue("@Name", NameTextBox.Text);
		command.Parameters.AddWithValue("@Content", ContentTextBox.Text);

		// DBへ接続してSQLを実行
		connection.Open();
		command.ExecuteNonQuery();
	}
	//表示画面へ
	Response.Redirect("Output.aspx");
	}
}
Output.aspx
<!DOCTYPE html>
<html>
	<head runat="server">
	    <title>出力画面</title>
	</head>
	<body>
	    <form id="form1" runat="server">
	        <div>
	            <h2>出力画面</h2>
	            <asp:GridView ID="MyTableGridView" AutoGenerateColumns="False" runat="server">
	                <Columns>
	                    <asp:BoundField DataField="Id" HeaderText="Id"/>
	                    <asp:BoundField DataField="Name" HeaderText="Name"/>
	                    <asp:BoundField DataField="Content" HeaderText="Content"/>
	                </Columns>
	            </asp:GridView>
	            <br/>
	            <asp:HyperLink ID="InputLink" NavigateUrl="Input.aspx" Text="入力画面へ" runat="server"/>
	        </div>
	    </form>
	</body>
</html>
Output.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace test
{
	public partial class Output : System.Web.UI.Page
	{
		//ページを初めて表示したときだけデータ取得処理を行う
		protected void Page_Load(object sender, EventArgs e)
		{
			if (!IsPostBack)
			{
				LoadtestTable();
			}
		}
        
		private void LoadtestTable()
		{
			// XMLから<Get>用SQLを取得
			Repository repository = new Repository(Server.MapPath("~/Sql/test.xml"));
			string sql = repository.GetSql();
			string connectionString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;

			using (SqlConnection connection = new SqlConnection(connectionString))
			using (SqlCommand command = new SqlCommand(sql, connection))
			using (SqlDataAdapter adapter = new SqlDataAdapter(command))
			{
				// DBからデータを取得
				DataTable dataTable = new DataTable();
				adapter.Fill(dataTable);

				// 取得したデータを画面に表示
				MyTableGridView.DataSource = dataTable;
				MyTableGridView.DataBind();
			}
		}
	}
}

5.デモプレイ

image.png

image.png

入力画面に入力すると出力画面で表示される簡単なものを作りました!

6.エラーメッセージの見方

目次

1.テーブル名が間違っている (Message=Invalid object name~~)
2.列名が間違っている (Message=Invalid column name~~)
3.SELECT句のカンマがない( Message=名前 '~~' のフィールドまたはプロパティが選択されたデータ ソースに見つかりませんでした。
4.SQL(Message=Incorrect syntax near '**')
5.SQLパラメータの指定漏れ(Message=Must declare the scalar variable "*")

(1)テーブル名が間違っている

SQL
・一覧表示
  <Get>
    <![CDATA[
      SELECT  Id,
              Name,
              Content
        FROM  MyTable → MyTabel
      ORDER BY Id
    ]]>
  </Get>

テーブル名の正解がMyTableなのに間違えてMyTabelと書いていたとします。

結果

エラーメッセージ
System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Invalid object name 'MyTabel'.
  Source=.Net SqlClient Data Provider
  スタック トレース:
<例外のスタック トレースを評価できません>

メッセージでは、Invalid object name 'MyTabel'と表示がされています。
Invalid object nameのobjectは指定したテーブルやビューなどのオブジェクトが見つからないということです。
'MyTabel'と出ているのでこの部分が間違っていると分かります。

(2)列名が間違っている

SQL
・一覧表示
  <Get>
    <![CDATA[
      SELECT  Id,
              Name,
              Content → Contant
        FROM  MyTable
      ORDER BY Id
    ]]>
  </Get>

ContentがContantと間違えて書いていたとします。

結果

エラーメッセージ
System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Invalid column name 'Contant'.
  Source=.Net SqlClient Data Provider
  スタック トレース:
<例外のスタック トレースを評価できません>

Invalid column nameとエラーが出ていますがcolumn は「列」という意味なので、Contantという列が存在しないということです。

(3)SELECT句のカンマがない

SQL
・一覧表示
  <Get>
    <![CDATA[
      SELECT  Id,
              Name →,×
              Content
        FROM  MyTable
      ORDER BY Id
    ]]>
  </Get>

Nameの後ろのカンマが抜けていたとします。

結果

エラーメッセージ
System.Web.HttpException
  HResult=0x80004005
  Message=名前 'Name' のフィールドまたはプロパティが選択されたデータ ソースに見つかりませんでした。
  Source=test
  スタック トレース:
   場所 test.Output.LoadtestTable() (C:\**\**\**\**\**\**\Output.aspx.cs):行 37
   場所 test.Output.Page_Load(Object sender, EventArgs e) (C:\**\**\**\**\**\**\Output.aspx.cs):行 15

メッセージでは名前 'Name' のフィールドまたはプロパティが選択されたデータ ソースに見つかりませんでした。
と表示がされています。
つまり、取得したデータにNameという列が存在しない、SQLの記述に誤りがある、またはSQLで取得している列名とGridViewなどで使用している名前が一致していない可能性があります。
今回はカンマの記述ミスが原因でしたが、列名の不一致など、ほかの原因も考慮しながら確認する必要があります。

(4)SQL構文エラー

SQL
・一覧表示
  <Get>
    <![CDATA[
      SELECT  Id,
              Name,
              Content
  FRAM←FROM  MyTable
      ORDER BY Id
    ]]>
  </Get>

FROMがFRAMと間違っていたとします。

結果

エラーメッセージ
System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Incorrect syntax near 'MyTable'.
  Source=.Net SqlClient Data Provider
  スタック トレース:
<例外のスタック トレースを評価できません>

エラーには、Incorrect syntax near ...のようなメッセージが出ます。
Incorrect syntaxは、SQLの構文が正しくありませんという意味です。
MyTableはその付近がエラーですという意味です。
つまりMyTable付近のSQLの構文が正しくありませんという意味です。
付近なので前後もあり得るためIncorrect syntax near '〇〇' が出た場合は、〇〇 だけを見るのではなく、その前後のSQL構文も確認するようにします。

(5)SQLパラメータの指定漏れ

今回、C#,SQLで"@ Name","@ Content"を設定しています。

Input.cs
command.Parameters.AddWithValue("@Name", NameTextBox.Text);
command.Parameters.AddWithValue("@Content", ContentTextBox.Text);
test.xml
  <Insert>
    <![CDATA[
      INSERT  INTO MyTable
           (
              Name,
              Content
           )
      VALUES
           (
              @Name,
              @Content
           )
    ]]>
    <Parameter>
      <Input Name="Name" Type="nvarchar" Size="15"/>
      <Input Name="Content" Type="nvarchar" Size="50"/>
    </Parameter>
  </Insert>

ですが、C#側が設定をせず@ Nameのみだと..

Input.cs
command.Parameters.AddWithValue("@Name", NameTextBox.Text);

結果

エラーメッセージ
System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Must declare the scalar variable "@Content".
  Source=.Net SqlClient Data Provider
  スタック トレース:
<例外のスタック トレースを評価できません>

Must declare the scalar variableはスカラー変数を宣言する必要がありますという意味です。
つまり、
SQLで@ Contentを使っているが、そのパラメータが認識できていないということです。
Must declare the scalar variable が表示された場合は、エラーメッセージの@〇〇を確認し、SQLで使用しているパラメータがC#側でも設定されているか確認するようにします。

7.まとめ

 SQLはC#と違い書いてる途中でエラーが出なくて動かしてみないとエラーがわからないものなので苦手意識がありましたがエラーメッセージにヒントがちりばめられていてすこし苦手意識がなくなってきました。
 今後も、必要なものいいなと思ったものを追加していこうと思います。
 長くなってしまいましたがメモとして見ていただければ幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?