Emmablakes Ответов: 3

Как решить это сообщение об ошибке " строка или двоичные данные будут усечены."


я пытаюсь читать из текстового файла и использовать идентификатор внутри текстового файла, чтобы обновить статус идентификатора в таблице до ok или чего-то еще.

он успешно читает текстовый файл и в момент обновления выдает ошибку
String or binary data would be truncated.


идентификатор в текстовом файле выглядит следующим образом:
1606873,1412393,1588593,1481673,1351153,1422153,1790433,1587033,1582593,1474233,1398953,1704553,1631313,1576513,1757113,1360193,1648393,1455473,1517753,1773633,1428153,1691553,1795793,1805113,1572513,1397353,1447473,1533393,1374273,1530353,1368233,1667313,1431793,1396953,1720633,1648633,1483753,1573993,1499673,1768273,1541193,1556673,1555793


во всяком случае, гораздо больше.

Что я уже пробовал:

private void btnTest_Click(object sender, EventArgs e)
{
   ReadFromTextFile();
}
public void ReadFromTextFile()
{
   StreamReader str = new StreamReader(@"C:\midMonth30072016\AppLog_Test.txt");
   while ((line = str.ReadLine()) != null)
   {
      updatestatus(line);
   }
}

public void updatestatus(string da)
{
   try
   {
      if (con.State != ConnectionState.Open)
      {
         con.Open();
      }
      SqlCommand cmd = new SqlCommand();
      string query = "update tblMidMonthold set Status='processed' where ID in ( @data )";
      SqlCommand sqlCmd = new SqlCommand(query, con);
      sqlCmd.Parameters.AddWithValue("@data", line);
      SqlDataReader dr = sqlCmd.ExecuteReader(); // it throws the arror at tis point.                                                       
   }
   catch (Exception)
   {
      throw;
   }
}

0x01AA

Что это SQL-типа код точно? Скорее всего, меньше ваших актальных данных из текстового файла.

3 Ответов

Рейтинг:
24

0x01AA

Невозможно добавить список целых чисел для оператора SQL " IN " в качестве одного параметра.

Один из обходных путей заключается в том, что вы создаете sql динамически, что-то вроде этого:

private void button1_Click(object sender, EventArgs e)
{
    // Your sql
    string sql = "update tblMidMonthold set Status='processed' where ID in ( @data )";

    // your textfile data
    string line = "1606873,1412393,1588593,1481673,1351153,1422153";

    // Split text file data into list
    string[] numbers = line.Split(',');
    StringBuilder paramIntList= new StringBuilder();
    int dummyTryParse;
    // Check wheter all items are really numbers
    foreach (string number in numbers)
    {
        // Among TryParse also some other Validation on can add. I.e. empty
        // number items, max number of numbers(?) and maybe more.
        if (int.TryParse(number, out dummyTryParse))
        {
            if (paramIntList.Length > 0)
            {
                paramIntList.Append(",");
            }
            paramIntList.Append(number);
        }
        else
        {
            // Exeception or whatever you prefer in this error situation.
            throw new Exception("Try Parse faild. Value= "+ number);
        }
    }
    sql = sql.Replace("@data", paramIntList.ToString());
}

Надеюсь, это поможет.

[Редактировать] Stringbuilder не нужен
private void button1_Click(object sender, EventArgs e)
{
    // Your sql
    string sql = "update tblMidMonthold set Status='processed' where ID in ( @data )";

    // your textfile data
    string line = "1606873,1412393,1588593,1481673,1351153,1422153";

    // Split text file data into list
    string[] numbers = line.Split(',');

    int dummyTryParse;
    // Check wheter all items are really numbers

    // Check Input string
    foreach (string number in numbers)
    {
        // Among TryParse also some other Validation on can add. I.e. empty
        // number items, max numer of numbers(?) and maybe more.
        if (!int.TryParse(number, out dummyTryParse))
        {
            // Exeception or whatever you prefer in this error situation.
            throw new Exception("Try Parse faild. Value= "+ number);
        }
    }

    // Inputdata is ok (no axception in check part)
    sql = sql.Replace("@data", line);
}


Emmablakes

Спасибо, брат...спасибо... это прекрасно решило мою проблему. ты самый лучший братан.

0x01AA

Добро пожаловать братан :)

Maciej Los

5ед!

0x01AA

Большое вам спасибо, Мацей.

Richard Deeming

Было бы лучше добавить несколько параметров в команду, а не вводить данные непосредственно в запрос.

В данный конкретный случай, вы избегаете SQL-инъекции, потому что каждое значение анализируется как целое число. Но если ОП попытается повторно использовать этот код со строками, не осознавая опасности...

В качестве альтернативы используйте Щеголеватый[^], который обрабатывает подобные случаи автоматически.

0x01AA

Вы правы, парсинг был идеей избежать SQL-инъекции. Но, конечно, добавление параметров умножения-это определенно лучший способ, я полностью пропустил этот вариант: (Большое вам спасибо за эту подсказку.

Рейтинг:
1

Maciej Los

Я бы посоветовал прочитать эту замечательную статью: Использование разделенных запятыми строк параметров значений в предложениях SQL IN[^]


Рейтинг:
0

Karthik_Mahalingam

Эта ошибка произошла из-за Datatype от Status Колонка.

Цитата:
Строковые или двоичные данные будут усечены.

когда вы попытаетесь присвоить данные столбцу, который не способен содержать эти данные, то возникнет ошибка.

длина столбца состояния может быть меньше 10 (nvarchar(5) )

Чинить:

Увеличьте длину nvarchar/varchar тип столбца состояния и проверка. это должно сработать.
Напр.: nvarchar(50)


0x01AA

Я думаю, что проблема заключается в добавлении значений списка для SQL в качестве параметра.

Karthik_Mahalingam

привет 0x01AA
я попытался воспроизвести ошибку, изменив размер nvarchar, он выдал ту же ошибку, что и ожидалось