Строка или двоичные данные будут проигнорированы. Что-то не так с объявлением «imagelocation»?

В настоящее время я разрабатываю студенческий портал с подходящей и простой системой входа в систему для проекта последнего года обучения в моем колледже. Это одна из командных кнопок (для сохранения фотографии на SQL-сервере). Я обнаружил ошибку. Это сообщение об ошибке:

System.Data.SqlClient.SqlException: 'String or binary data would be truncated. The statement has been terminated.'

Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click
    'String imagelocation = ""

    Dim images() As Byte = Nothing
    'Dim imagelocation As String
    'imagelocation = ""
    Dim Stream As New FileStream(imagelocation, FileMode.Open, FileAccess.Read)
    Dim brs As New BinaryReader(Stream)
    images = brs.ReadBytes(CInt(Stream.Length))

    Dim source As String = "Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True"
    Dim con As New SqlConnection(source)
    con.Open()

    Dim cmd As String = "Insert into Photo Values('" + TextBox2.Text + "', @images)"


    Dim qry As New SqlCommand(cmd, con)
    qry.Parameters.Add(New SqlParameter("@images", images))

    'qry.Parameters.Add(new SqlParameter("@images", pictureBox1));
    ***Dim i As Integer = qry.ExecuteNonQuery()

    If i >= 1 Then
        MessageBox.Show("Successfull!", "message", MessageBoxButtons.OK)
    Else
        MessageBox.Show("Fail!", "message", MessageBoxButtons.OK)
    End If
 End Sub
End Class

Это таблица SQL для меня, чтобы сохранить загруженную фотографию в базу данных. Любая помощь будет оценена по достоинству. Спасибо.

Строка или двоичные данные будут проигнорированы. Что-то не так с объявлением «imagelocation»?

ОБНОВИТЬ

Ранее имя столбца Photo было изменено на Img, имя таблицы должно было быть Photo.

Поэтому я попытался переключить код на другой метод:

    Dim source As String = "Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True"
    Dim con As New SqlConnection(source)
    Dim command As New SqlCommand("Insert into Photo (Img, Pname) Values (@Img, @Pname)", con)
    Dim ms As New MemoryStream
    pictureBox1.Image.Save(ms, pictureBox1.Image.RawFormat)

    command.Parameters.Add("@Img", SqlDbType.Image).Value = ms.ToArray()
    command.Parameters.Add("@Pname", SqlDbType.VarChar).Value = TextBox2.Text
    con.Open()

    If command.ExecuteNonQuery() = 1 Then
        MessageBox.Show("Successfully uploaded", "Message", MessageBoxButtons.OK)
    Else
        MessageBox.Show("Failed. Try again.", "Message", MessageBoxButtons.OK)
    End If

Думаю, это действительно сработало. Не уверен, будет ли какая-нибудь скрытая ошибка. Любой комментарий был бы полезен, ребята. Это результат таблицы Photo. Photo таблица вывода

Это слишком много кода для публикации. Вам нужно потратить некоторое время на решение проблемы самостоятельно и несколько сузить ее, а затем опубликовать ТОЛЬКО соответствующий код.

jmcilhinney 13.09.2018 09:45

Как сказал @jmcilhinney, вам нужно отладить свой код и пройти через него, чтобы определить, какой оператор вызывает исключение, и просто опубликовать код, относящийся к этому оператору. Кроме того, я бы рекомендовал почитать параметризованные операторы SQL, поскольку в настоящее время ваш код широко открыт для атак с использованием SQL-инъекций.

Diado 13.09.2018 09:49

Можете ли вы указать тип данных для каждого столбца в таблице Photo? Также вы, кажется, используете конкатенацию для строки запроса, вместо этого используйте параметры.

Tetsuya Yamamoto 13.09.2018 09:52

@TetsuyaYamamoto. Да, ссылка на изображение с названием «Таблица» является типом данных для таблицы Photo. Поскольку я никогда не узнал о параметрах, поэтому я его не использую.

not_Prince 13.09.2018 16:15

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

Mary 14.09.2018 09:15

@ Мэри, прости за беспокойство. Поскольку я разрабатываю его, я полагаю, что использовать имена по умолчанию для кнопок мне проще. Я упомянул легенду только для справки, так как по ошибке загрузил весь абзац кода, что не рекомендуется. Я не буду повторять эту ошибку снова. Спасибо :)

not_Prince 14.09.2018 09:47

Это второй раз за столько дней, когда появилась эта перегрузка конструктора для параметров. qry.Parameters.Add(New SqlParameter("@images", images)) Это эквивалент .AddWithValue, вызвавшего исключение. (см. ответ @Tetsuya Yamamoto) Используйте перегрузку метода .Add, для которой требуется тип и размер данных.

Mary 14.09.2018 09:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
415
2

Ответы 2

Эта ошибка возникает, когда вы указываете размер параметра, а затем предоставляете данные, превышающие его. Для начала, способ добавления параметра плохой:

qry.Parameters.Add(New SqlParameter("@images", images))

Вы не указываете там тип данных или размер, поэтому полагаетесь на то, что системный тип по умолчанию в порядке. Очевидно, что это не так, иначе вы не получили бы эту ошибку. ВСЕГДА указывайте тип данных и, если тип данных - переменный размер, также и размер, например

qry.Parameters.Add("@images", SqlDbType.VarBinary, 8000).Value = images

Указанное вами значение SqlDbType должно соответствовать типу данных столбца, для которого предназначены данные, а размер также должен соответствовать размеру в базе данных. Если вы используете varbinary(max) в базе данных, используйте -1 для размера параметра.

На самом деле проблема только с кодами для button8, остальное нормально. Я отправляю весь параграф кодов на всякий случай просто для справки. Фотография предназначена для загрузки в таблицу Photo. Как показано на прилагаемом снимке экрана, Table - это тип данных, который я использую для таблицы Photo.

not_Prince 13.09.2018 16:42

«в остальном все в порядке. Я отправляю весь параграф кодов на всякий случай только для справки». Не надо. Если нам нужно больше, мы можем попросить об этом, но вы должны публиковать только тот код, который имеет непосредственное отношение к проблеме.

jmcilhinney 13.09.2018 17:12

В документации четко указано, что тип данных image устарел, поэтому у вас нет веских причин использовать его в новой базе данных. Вы должны использовать varbinary. В любом случае, если вы используете image, вам все равно следует указывать это в качестве типа данных для параметра. Поскольку вы используете массив Byte, он почти наверняка будет использовать по умолчанию SqlDbType.VarBinary, а также использовать некоторый размер по умолчанию (вероятно, 4000 или 8000), и ваши данные должны превышать этот размер. Если вы сделаете то, что я уже сказал вам, и определитесь с типом и размером данных, тогда это сработает.

jmcilhinney 13.09.2018 17:15

Во-первых, вы должны знать, что использование типа данных IMAGE не рекомендуется. Более рекомендуется использование VARBINARY(MAX):

ALTER TABLE TableName ALTER COLUMN Photo VARBINARY(MAX)

Объяснение об устаревании типа данных изображения можно увидеть здесь.

For storing images you have to make use of the varbinary(MAX) datatype. The image datatype will be deprecated.

Затем исключение произошло из-за того, что вы добавляете данные в столбец изображения, размер которого меньше, чем размер переданного изображения из параметра (поскольку SqlDbType не указан, CLR автоматически определяет тип Byte(n); следовательно, может произойти усечение данных, чтобы соответствовать переданному массиву для типа данных IMAGE) . Используйте SqlDbType.VarBinary с размером -1:

qry.Parameters.Add("@images", SqlDbType.VarBinary, -1).Value = images

Обратите внимание, что вы можете установить максимальный размер VARBINARY с определенными числами в байтах (кроме -1), но вам нужно проверить images.Length, чтобы предотвратить усечение (просто отмените процесс загрузки, если размер изображения больше указанного).

If images.Length > 1048576 Then ' maximum limit e.g. 1 MiB
   ' cancel upload
Else
   ' continue and save to DB
End If

Наконец, настройте запрос, чтобы использовать параметры для всех значений:

Dim source As String = "Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True"
Using con As New SqlConnection(source)
   con.Open()

   Dim cmd As String = "Insert into Photo Values(@pname, @images)"

   Using qry As New SqlCommand(cmd, con)
      qry.Parameters.Add("@pname", SqlDbType.NVarchar, 50).Value = TextBox2.Text
      qry.Parameters.Add("@images", SqlDbType.VarBinary, -1).Value = images
      Dim i As Integer = qry.ExecuteNonQuery()

      ' other stuff

   End Using
End Using

Хорошо, поэтому я скорректировал конкретный запрос, который вы упомянули, и, используя тип данных varbinary для images, установил размер на -1. Однако есть ошибка System.Data.SqlClient.SqlException: 'Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.' с этим запросом: Dim i As Integer = qry.ExecuteNonQuery()

not_Prince 14.09.2018 10:04

@Tetsuya Yamamoto Из предоставленной вами ссылки «Varbinary (max) может хранить только изображения с максимальным размером 2 ГБ». Но в вашем комментарии говорится: «Максимальный предел, например, 1 МБ». Это какие-то другие критерии, которые дополнительно ограничивают ограничение в 2 ГБ?

Mary 14.09.2018 10:05

Другие вопросы по теме