2

誰かが特定の日付でmsデータベースを検索するためのSQLクエリで私にアドバイスできますか?

たとえば、2013年2月13日のすべてのトランザクションを検索したいと思います。私のデータベースには、購入日を格納する購入日という1つの列があります。

データベースでは、日付はこの形式で保存されます16/02/201302:47:36AM。

テキストボックスに希望の日付を入力して、その値をクエリに渡します。

 public DataSet OrderByDate(DateTime date)
        {
            //  string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Amrit\\Desktop\\Database.accdb ;Persist Security Info=False;";
            DataSet dataSet = new DataSet();
            OleDbConnection oleConn = new OleDbConnection(connString);

            try
            {
                oleConn.Open();
                string sql = "SELECT  Customer.[Title] + SPACE(2)  + Customer.[Customer's Name] as CustomerName, Customer.[Customer's Ebayname], Customer.[Email Address], Customer.[Phone Number], Customer.[Address 1] + SPACE(2)  +Customer.[Address 2] + SPACE(2)  + Customer.[City] + SPACE(2)  + Customer.[Post Code]+  SPACE(2)  + Customer.[Country] as Address, Customer.[Item Purchased], Customer.[Purchased Date], Customer.[Total Price] FROM Customer WHERE [Purchased Date]='" + date;
                OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, oleConn);
                dataAdapter.Fill(dataSet, "Customer");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                oleConn.Close();
            }
            if (dataSet.Tables.Count <= 0)
                return null;
            else
                return dataSet;
        }
4

6 に答える 6

4
  1. クエリには常に元の/適切なデータ型を使用するようにしてください。この場合 - 日時。
  2. パラメータを SQL に連結しないでください。特に文字列がユーザー入力の場合は特にそうです。

以下はうまくいくはずです:

    public DataSet OrderByDate(DateTime date)
    {
        string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Amrit\\Desktop\\Database.accdb ;Persist Security Info=False;";
        var dataSet = new DataSet();

        using(var oleConn = new OleDbConnection(connString))
        {
            try
            {
                oleConn.Open();
                var cmd = oleConn.CreateCommand();
                cmd.CommandText = "SELECT * FROM Customer WHERE [Purchased Date] BETWEEN :dateStart AND :dateEnd";
                cmd.Parameters.AddRange(new[]
                    {
                        new OleDbParameter("dateStart", date.Date),
                        new OleDbParameter("dateEnd", date.Date.AddDays(1).AddTicks(-1))
                    }
                    );

                var dataAdapter = new OleDbDataAdapter(cmd);
                dataAdapter.Fill(dataSet, "Customer");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        return dataSet.Tables.Count <= 0 ? null : dataSet;
    }

わかりやすくするために、列の長いリストを削除しました。私が理解している限り、Oracle は、SQL Server の '@' とは対照的に、パラメーター名の前にコロン (:) が付いたパラメーターを想定しています。上記がうまくいかない場合は、@ または単に ? を使用してみてください。パラメーター名の代わりに、名前なしでパラメーターを指定します。

「使用」部分は、例外がスローされた場合でも接続を正常に閉じる処理を行う必要があり、コードの最終セクションよりもきれいに見えます。

この部分について:

                    new OleDbParameter("dateStart", date.Date),
                    new OleDbParameter("dateEnd", date.Date.AddDays(1).AddTicks(-1))

date.Date は日付部分のみを返し (時刻は 00:00:00)、date.Date.AddDays(1) は次の日付 (時刻も 00:00:00) です (例: 2012-02-16 00:00)。 :00 と 2012-02-17 00:00:00 - 正確に 24 時間 - 1 日。必要に応じてティックを 1 つ減算することもできますが、考え方は同じです。このようにして、日付がその範囲内にあるすべてのレコードを選択します (したがって、BETWEEN を使用します)。Oracleの日時関数を使用して同じことを達成しようとすることもできますが、これはより短く/よりクリーンだと思います。

于 2013-02-16T15:11:55.890 に答える
1

クエリに itLIKE演算子を使用できます。

string sql = "SELECT  Customer.[Title] + SPACE(2)  + Customer.[Customer's Name] as CustomerName, Customer.[Customer's Ebayname], Customer.[Email Address], Customer.[Phone Number], Customer.[Address 1] + SPACE(2)  +Customer.[Address 2] + SPACE(2)  + Customer.[City] + SPACE(2)  + Customer.[Post Code]+  SPACE(2)  + Customer.[Country] as Address, Customer.[Item Purchased], Customer.[Purchased Date], Customer.[Total Price] FROM Customer WHERE [Purchased Date] LIKE '" + "'" + date "%'";

結果として、すべての文字列に13/02/2013次のような日付が含まれます。

  • 2013 年 2 月 13 日午前 2 時 47 分 36 秒。
  • 2013/02/13 14:24:02 午前

等..

そして、常にparameterized sqlクエリで使用してください。この種のコードは常にSQL Injection. お気に入り;

于 2013-02-16T14:23:22.963 に答える
1

where 句から時間コンポーネントを削除する場合は、次のようにします。

where YourDateField >= @StartDate
and YourDateField < @TheDayAfterTheEndDate

質問のデータを使用すると、@StartDate は 2013-02-13 になり、@TheDayAfterTheEndDate は 2013-02-14 になります。

于 2013-02-16T14:41:35.127 に答える
0

MSDNライブラリによると、DateTime.ToStringメソッド(文字列)を使用して、日時オブジェクトを明確な方法でフォーマットされた文字列に変換できます。

string datestring = date.ToString("yyyyMMdd"); 
string sql = 
  " SELECT ... "
+ " FROM Customer "
+ " WHERE [Purchased Date] >= '" + datestring + "'" 
  + " AND [Purchased Date] < DATEADD(day, 1, '" + datestring + "')" ;

そして、このような引用符で遊ぶよりも、パラメータをクエリ文字列に渡すためのより良い方法があると確信しています。たとえば、この質問を参照してください。SQL圧縮挿入ステートメントを適切にサニタイズ(またはパラメーター化)する方法

于 2013-02-16T15:52:24.500 に答える
0

理想的には、あらゆる種類の「時間」の問題を回避するためにDate、データベースを挿入/更新するときと読み取るときの両方で、常に日時のプロパティを使用します。実際、時間が重要でない列でこれを自動的に行うためのラッパー コードをいくつか書きました。

これにより、データベースでは、00:00:00挿入時と更新時の両方の時間が常に確保されます。

したがって、クエリ(他のSQLインジェクション/パラメータ化されたクエリの質問は避けてください)

"SELECT * FROM _table WHERE _date = '" + date.Date + "'";

すべてが等しく、すべての挿入も使用されていることがわかっているため.Date、時間について心配する必要はありません。

于 2013-02-16T14:45:42.817 に答える
0

like は使用しないでください。これには通常の WHERE 句を使用できます。

        DateTime start = DateTime.Now.Date; //this will get you 2/16/2013 12:00:00am
        DateTime end = start.AddDays(1); //this will get you 2/17/2013 12:00:00am

        //make sure to parameterize your query like this
        string sql = "SELECT * FROM Product WHERE PurchasedDate >= @start AND PurchasedDAte < @end";
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
        using (conn)
        {
            System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, conn);
            System.Data.SqlClient.SqlParameter pmStart = new System.Data.SqlClient.SqlParameter("start", start);
            System.Data.SqlClient.SqlParameter pmEnd = new System.Data.SqlClient.SqlParameter("end", end);
            command.Parameters.Add(pmStart);
            command.Parameters.Add(pmEnd);
        }
于 2013-02-16T14:46:00.390 に答える