0

asp.net でランタイム SQL クエリ エラーが発生し続けます。私はc#を使用しています。エラーは常に、'(some word)' 付近の Incorrect Syntax で始まります。構文エラーがないかコードをチェックして再チェックしましたが、何も見つかりませんでした..以下のコードでは、エラーは「ユーザー」の近くの不正な構文です。助けてください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;

public partial class LogIn : System.Web.UI.Page
{
    SqlConnection con = new SqlConnection();
    SqlCommand cmd = new SqlCommand();

    protected void Page_Load(object sender, EventArgs e)
    {
        con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users        \Sony\Documents\Library\App_Data\Library.mdf;Integrated Security=True;User     Instance=True";
        cmd.Connection=con;
        con.Open();



    }
protected void  txt_user_TextChanged(object sender, EventArgs e)
{

}
protected void  txt_pass_TextChanged(object sender, EventArgs e)
{

}
protected void  btn_log_Click(object sender, EventArgs e)
{
    cmd.CommandText="select count(*) from user where Username='"+txt_user.Text+"' and     Password='"+txt_pass.Text+"'";
        int count =Convert.ToInt16(cmd.ExecuteScalar());
        if (count==1)
        {
            Response.Redirect("Home.aspx");
        }
        else
        {
            Label1.Text="Invalid Username or Password. Please try again..";
        }
}
4

4 に答える 4

4

エラーの理由は単語userです。SqlServer の予約済みキーワードです。
角括弧でカプセル化する必要があります

select count(*) from [user] ....

そうは言っても、コードの最大の問題に取り組みましょう。SQL インジェクション

cmd.CommandText="select count(*) from [user] where Username=@uname " + 
                "and Password=@upass";
cmd.Parameters.AddWithValue("@uname", txt_user.Text)
cmd.Parameters.AddWithValue("@upass", txt_pass.Text);
int count =Convert.ToInt16(cmd.ExecuteScalar());
......

このようなパラメーター化されたクエリを使用すると、データベースに格納されている情報を侵害 (または破壊) する可能性のある悪意のある入力 (参照されている質問を参照) からアプリケーションを保護できます。また、一重引用符や数値の小数点区切り記号を含む文字列、日付の書式設定の問題など、問題のある文字を含む入力の問題も回避できます。

上記のコードからわかるように、別の問題があります。接続をグローバル変数に保存しないでください。必要に応じて接続を開き、後で閉じると、パフォーマンスが低下することはありません。これは接続プーリングと呼ばれ、使用しないときに貴重なリソースをロックしたままにしておくことはありません。

すべてを要約すると、次のようになります。

protected void  btn_log_Click(object sender, EventArgs e)
{

   using(SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" +
                                 @"C:\Users\Sony\Documents\Library\App_Data\Library.mdf;" + 
                                 @"Integrated Security=True;User Instance=True")
    {
        con.Open();
        using(SqlCommand cmd = new SqlCommand("select count(*) from [user] where "+ 
                                   "Username=@uname and Password=@upass", con)
        {
            cmd.Parameters.AddWithValue("@uname", txt_user.Text)
            cmd.Parameters.AddWithValue("@upass", txt_pass.Text);
            int count =Convert.ToInt16(cmd.ExecuteScalar());
            ......
        }
    }
}
于 2013-03-17T18:41:39.513 に答える
1

問題は、「ユーザー」が SQL の予約語であることです。インジェクションの問題とは別に、クエリは次のようになります。

select ... from [user] where

于 2013-03-17T18:42:20.677 に答える
1

'User' は SQL サーバーの予約済みキーワードです。テーブル名が「user」の場合は、クエリ内のブラケットに配置する必要があります

select count(*) from [user] where ...
于 2013-03-17T18:42:39.753 に答える
0

私は、スティーブ、ローマン、アレックスが言ったことすべてに完全に同意します。

追加する必要がある場合は、この例で使用されているアドホック クエリの使用を最小限に抑えるようにしてください。むしろ、SQL コードの大部分を SQL 関数とストアド プロシージャに配置することをお勧めします。これにより、これらのクエリを最初に実行するときにコンパイルでき、その後データベースを実行できるため、パフォーマンスが大幅に向上する可能性があります。データを取得するためだけに焦点を当てます。アドホック クエリでは、クエリを毎回コンパイルする必要があり、より複雑なクエリの場合、実際には時間がかかる場合があります。

その後、次のようにストアド プロシージャを実行できます。

using(SqlCommand cmd = new SqlCommand("dbo.IsValidLogin", con)
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@username", txt_user.Text)
    cmd.Parameters.AddWithValue("@password", txt_pass.Text);
    var isValidLogin =Convert.ToBool(cmd.ExecuteScalar());
    ...
}

次のようにデータベースで宣言されたプロシージャがある場合:

CREATE PROC dbo.IsValidLogin
@username nvarchar(50),
@password nvarchar(50)
AS
BEGIN
  SELECT count(1) 
  FROM [user] 
  WHERE Username=@username
  AND Password=@password
END;

ここで Sql Fiddle の例を参照してください。

于 2013-03-17T20:28:06.480 に答える