System.Data.SqlClient.SqlException: 'Неверный синтаксис около' 9 ' - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть два DateTimePickers (dateStart и dateStop) в winform. Я установил dateStart и формат dateSop следующим образом:

    dateStart.Format = DateTimePickerFormat.Custom;
    dateStart.CustomFormat = "yyyy:MM:dd HH:mm:ss";
    dateStop.Format = DateTimePickerFormat.Custom;
    dateStop.CustomFormat = "yyyy:MM:dd HH:mm:ss";

Я хочу посчитать количество строк в таблице моей базы данных между dateStart и dateStop. Моя строка выбора:

string stmt = "SELECT COUNT(*) FROM [dbo].[tbl_TagLogging] WHERE DateTime BETWEEN  " + Convert.ToString(dateStart.Value) + " AND " + Convert.ToString(dateStop.Value);

И это результат: enter image description here

Это то, как связывают параметры DateStart и DateStop моей базы данных с DateTimePickers.

 cmd.Parameters.Add("@DataStart", SqlDbType.DateTime).Value = dateStart.Value;// new DateTime(dateStart.Value);
 cmd.Parameters.Add("@DataStop", SqlDbType.DateTime).Value = dateStop.Value;// new DateTime(2020, 02, 05, 13, 12, 25, 703);//2020, 02, 05, 13, 12, 25, 703   //2020, 02, 05, 13, 06, 50, 700

Подсчет строк работает отлично без предложения WHERE.

count = (int)cmdCount.ExecuteScalar();//this is how I count the rows

Я получаю здесь 'System.Data.SqlClient.SqlException: Incorect синтаксис около 9'.

Я не понимаю, почему, если формат dateStart имеет формат «гггг: ММ: дд ЧЧ: мм: сс», dateStart.value возвращается в другом формате. В моем пользовательском интерфейсе dateStart отображается в правильном формате (тот, что из приведенного выше кода). Но я мог сделать что-то не так в моей строке stmt. Есть мысли о том, что не так?

РЕДАКТИРОВАТЬ 1 (весь мой код):

 private void button_Click(object sender, EventArgs e)
    {
        dateStart.Format = DateTimePickerFormat.Custom;
        dateStart.CustomFormat = "yyyy:MM:dd HH:mm:ss";
        dateStop.Format = DateTimePickerFormat.Custom;
        dateStop.CustomFormat = "yyyy:MM:dd HH:mm:ss";
        string stmt = "SELECT COUNT(*) FROM [dbo].[tbl_TagLogging] WHERE DateTime BETWEEN  @DataStart AND @DataStop";         // WHERE DateTime BETWEEN  " + Convert.ToString(dateStart.Value) + " AND " + Convert.ToString(dateStop.Value)
       // string stmt = "SELECT COUNT(*) FROM [dbo].[tbl_TagLogging] WHERE DateTime BETWEEN  '" + Convert.ToString(dateStart.Value) + "' AND '" + Convert.ToString(dateStop.Value) + "'";
        int count = 0;

        using (SqlConnection connection = new SqlConnection(@"Data Source=DESKTOP-JQSJAF8\SQLEXPRESS;Initial Catalog=TRTF_TagLogging;Integrated Security=True; MultipleActiveResultSets = true")) 
        {
            using (SqlCommand cmd = new SqlCommand("PS_TagLogging", connection))// used for stored proc
            {
                using (SqlCommand cmdCount = new SqlCommand(stmt, connection))//used to count number of rows of my table
                {
                    //yyyy:MM:dd hh:mm:ss
                    connection.Open();
                    cmd.CommandType = CommandType.StoredProcedure;                        
                    cmd.Parameters.Add("@DataStart", SqlDbType.DateTime).Value = dateStart.Value;
                    cmd.Parameters.Add("@DataStop", SqlDbType.DateTime).Value = dateStop.Value;
                    var values = new List<double>();
                    var valData = new List<DateTime>();
                    SqlDataReader reader = cmd.ExecuteReader();
                    while (reader.Read())
                    {
                        // values.Add(reader.GetInt64(0));//reads the values of first column (ID) from DB
                        values.Add(reader.GetFloat(1));//reads the values of second column (Tag1) from DB 
                        valData.Add(reader.GetDateTime(2));//reads the values of third column (DateTime) from DB 
                    }

                    arrDate = valData.ToArray();
                    arrVal = values.ToArray();

                    count = (int)cmdCount.ExecuteScalar();
                    plot1.XAxes[0].ScaleDisplay.TextFormatting.Style = Iocomp.Types.TextFormatDoubleStyle.DateTime;
                    plot1.XAxes[0].ScaleRange.Span = 1.0 / 120.0 ; //30sec Span;



                    for (int i=0; i<count; i++)
                    {
                        plot1.Channels.Trace[0].AddXY(arrDate[i], arrVal[i]);
                    }


                    connection.Close();
                }
            }
        }
        MessageBox.Show("Nr. lines: " + count);
         Random().NextDouble() * 100);
    }

Ответы [ 2 ]

4 голосов
/ 17 февраля 2020

Как уже упоминалось в комментариях и подтверждено вашей другой командой, вы должны использовать параметры. И вот как это должно выглядеть в вашем случае:

string stmt = "SELECT COUNT(*) FROM [dbo].[tbl_TagLogging] WHERE DateTime BETWEEN @DataStart AND @DataEnd";
using (var cmd = new SqlCommand(stmt))
{
    cmd.Parameters.Add("@DataStart", SqlDbType.DateTime).Value = dateStart.Value;
    cmd.Parameters.Add("@DataStop", SqlDbType.DateTime).Value = dateStop.Value;
    var reader = cmd.ExecuteReader();

    // Process the data from the reader.
}

Но, возможно, вам следует подумать о том, чтобы полностью отбросить эти вещи и использовать Entity Framework (Core) и смоделировать ваш DBContext и просто работать с LINQ- to- SQL для извлечения данных из вашей базы данных.

Обновление

После того, как вы обновили свой вопрос и опубликовали всю функцию, проблема довольно проста. Вы просто пропустили добавление параметров ко второму запросу и добавили его только к первому. Поэтому обновите, пожалуйста, примерно так:

cmdCount.Parameters.Add("@DataStart", SqlDbType.DateTime).Value = dateStart.Value;
cmdCount.Parameters.Add("@DataStop", SqlDbType.DateTime).Value = dateStop.Value;
count = (int)cmdCount.ExecuteScalar();

Тем не менее, я надеюсь, что это не совсем ваша функция, потому что в этом случае запрос счетчика с помощью этого второго запроса совершенно бесполезен. Это значение используется для перебора массива, извлеченного из первого запроса. Поэтому я предполагаю, что переменные arrDate.Length и arrVal.Length уже содержат значение, которое вам нужно. Поэтому вам следует проверить, совпадают ли эти значения (свойство длины массива и результат подсчета вашего запроса), а если нет, то почему они различаются, и найти причину root для этой проблемы. Если они совпадают, просто используйте свое локальное существующее значение и не спрашивайте SQL serverb о том, что вы уже знаете.

1 голос
/ 17 февраля 2020

Все, что говорили люди, в порядке, но я думаю, что пропущены цитаты. Попробуйте:

string stmt = "SELECT COUNT(*) FROM [dbo].[tbl_TagLogging] WHERE DateTime BETWEEN  '" + Convert.ToString(dateStart.Value) + "' AND '" + Convert.ToString(dateStop.Value) + "'";
...