1

私はばかで、C#でSQLデータベースに対して簡単なクエリを実行しようとしているようです。これはクエリです、私は実行しようとしています:

 _query = "SELECT PC.SN, User.Name + ' ' + User.Family as AssignedTo " +  
          "FROM PC LEFT JOIN Users ON PC.USERID = Users.ID " + 
          "WHERE PC.Type = '" + AssetTypeCB.SelectedItem.ToString() + "'";

問題は、「nvarcharでメソッドを呼び出せない」というエラーメッセージが表示されることです。何が問題になるのか分かりますか?

4

3 に答える 3

7

クエリが間違っているようです。、etalに変更User.Nameする必要があります。Users.Name正しいクエリは次のようになります。

 _query = "SELECT PC.SN, Users.Name + ' ' + Users.Family as AssignedTo " +
          "FROM PC LEFT JOIN Users ON PC.USERID = Users.ID " + 
          "WHERE PC.Type = '" + AssetTypeCB.SelectedItem.ToString() + "'";

また、コードにパラメーター化されたクエリを使用することを提案させてください。これはあなたがすべき理由を教えてくれます。

于 2013-01-24T11:05:42.700 に答える
0

クエリにパラメータを追加する方が良いと思います

using System;
using System.Data;
using System.Data.SqlClient;

class ParamDemo
{
    static void Main()
    {
        // conn and reader declared outside try
        // block for visibility in finally block
        SqlConnection conn   = null;
        SqlDataReader reader = null;

        string inputCity = "London";

        try
        {
            // instantiate and open connection
            conn =  new 
                SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
            conn.Open();

            // don't ever do this
            // SqlCommand cmd = new SqlCommand(
            // "select * from Customers where city = '" + inputCity + "'";

            // 1. declare command object with parameter
            SqlCommand cmd = new SqlCommand(
                "select * from Customers where city = @City", conn);

            // 2. define parameters used in command object
            SqlParameter param  = new SqlParameter();
            param.ParameterName = "@City";
            param.Value         = inputCity;

            // 3. add new parameter to command object
            cmd.Parameters.Add(param);

            // get data stream
            reader = cmd.ExecuteReader();

            // write each record
            while(reader.Read())
            {
                Console.WriteLine("{0}, {1}", 
                    reader["CompanyName"], 
                    reader["ContactName"]);
            }
        }
        finally
        {
            // close reader
            if (reader != null)
            {
                reader.Close();
            }

            // close connection
            if (conn != null)
            {
                conn.Close();
            }
        }
    }
}
于 2013-01-24T11:08:22.020 に答える
0

このクエリは、SQLインジェクション攻撃にさらされます。プリペアドステートメントに変換する必要がありますが、実際のエラーはテーブル名Usersの使用によるものです。SELECT ... Userがあります。Usersである必要があります。間違った列名エラーが発生しない理由は、Userが予約済みのキーワードであるため、テーブル名を[]で区切っていない限り、SQLServerはその特定のエラーを表示します。 。次のコードで修正できます。

string _query = "SELECT PC.SN, Users.Name + ' ' + Users.Family as AssignedTo FROM PC LEFT JOIN Users ON PC.USERID = Users.ID WHERE PC.Type = @Type";

SqlConnection conn = new SqlConnection("YOUR_CONNECTION_STRING");
SqlCommand cmd = new SqlCommand(_query, connection);
cmd.Parameters.AddWithValue("Type", AssetTypeCB.SelectedItem.Value);
DataTable dt = new DataTable();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
adp.Fill(dt);

テーブル名が実際にUserの場合、このコードはエラーを修正します

string _query = "SELECT PC.SN, [User].Name + ' ' + [User].Family as AssignedTo FROM PC LEFT JOIN [User] ON PC.USERID = [User].ID WHERE PC.Type = @Type";

SqlConnection conn = new SqlConnection("YOUR_CONNECTION_STRING");
SqlCommand cmd = new SqlCommand(_query, connection);
cmd.Parameters.AddWithValue("Type", AssetTypeCB.SelectedItem.ToString());
DataTable dt = new DataTable();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
adp.Fill(dt);

SQLインジェクション攻撃の詳細

smooeneが元のステートメントに次の値を入力したとします。

'; DELETE FROM Users; --

SQLステートメントを実行すると、SQLServerはそれを次のように解釈します。

SELECT PC.SN, User.Name + ' ' + User.Family as AssignedTo  
FROM PC LEFT JOIN Users ON PC.USERID = Users.ID 
WHERE PC.Type = ''; DELETE FROM Users; --'

このステートメントは完全に有効であり、ユーザーが持っている権限のレベルが与えられると、Usersテーブルからすべてのレコードが削除される可能性があります。プリペアドステートメントを使用すると、それが起こらないようにするのに役立ちます。

于 2013-01-24T11:21:19.360 に答える