Member 14108087 Ответов: 2

Извлечение фотографий из SQL db on VB.NET форма windows


Привет ребята я пытаюсь загрузить фотографии в базу данных sql а затем получить их в поле изображения в другой форме windows в vb.net . Но я получаю исключение, параметр не валиден, я перепробовал все методы, найденные в интернете, но ничего не работает. Вот код для загрузки. загрузка работает, потому что в базе данных у меня есть таблица, где у меня есть столбец с именем Photo with datatype Image, и я могу видеть, как он обновляется соответственно с байтом, подобным этому ниже. 0xFFD8FFE000104A4649460001010100600......

Вот код для загрузки работает нормально.
Try
 Fill()
            con = New SqlConnection(cs)
            con.Open()
            Dim ck As String = "insert into [Products]([Product Code],[Product Name],[Price],[Discount],[VAT],[Quantity],[photo]) VALUES ('" & txtID.Text & "','" & txtProductName.Text & "','" & txtSellingPrice.Text & "','" & txtDiscount.Text & "',
'" & txtVAT.Text & "','" & txtOpeningStock.Text & "',@d2)"
            cmd = New SqlCommand(ck) With {
                .Connection = con
            }
           
            ' Prepare command for repeated execution
            cmd.Prepare()
            ' Data to be inserted
            For Each row As DataGridViewRow In dgw.Rows
                If Not row.IsNewRow Then
                    Dim ms As New MemoryStream()
                    Dim img As Image = row.Cells(0).Value
                    Dim bmpImage As New Bitmap(img)
                    bmpImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
                    Dim outbytes(CInt(ms.Length - 1)) As Byte
                    ms.Seek(0, SeekOrigin.Begin)
                    ms.Read(outbytes, 0, CInt(ms.Length))

                    Dim q As New SqlParameter("@d2", SqlDbType.Image)
                    q.Value = outbytes
                    cmd.Parameters.Add(q)
                    cmd.ExecuteNonQuery()
                    ms.Close()
                    cmd.Parameters.Clear()
                End If
            Next

            con.Close()
            lblUser.Text = Login_Form.txtUserid.Text
            LogFunc(lblUser.Text, "added the new Product '" & txtProductName.Text & "' having Product code '" & txtProductCode.Text & "'")

            MessageBox.Show("Successfully saved", "Product Record", MessageBoxButtons.OK, MessageBoxIcon.Information)
            auto()
            con.Close()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

вот код для извлечения фотографии.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim cn As New SqlConnection()

        cn.ConnectionString = cs

        Try
            Dim sql As String = "Select [Photo] from login where [User Name] = @d1"

            Dim cmd As New SqlCommand(sql, cn)
            cn.Open()
            cmd.Parameters.AddWithValue("@d1", TextBox1.Text)

            Dim stream As New MemoryStream()
            Dim image As Byte() = DirectCast(cmd.ExecuteScalar(), Byte())
            stream.Write(image, 0, image.Length)
            cn.Close()
            Dim bitmap As New Bitmap(stream) ' <==The exception is being thrown here.

            PictureBox1.Image = bitmap

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try


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

Try
            Dim sql As String = "Select [Photo] from login where [User Name] = @d1"

            Dim cmd As New SqlCommand(sql, cn)
            cn.Open()
            cmd.Parameters.AddWithValue("@d1", TextBox1.Text)

            Dim stream As New MemoryStream()
            Dim image As Byte() = DirectCast(cmd.ExecuteScalar(), Byte())
            stream.Write(image, 0, image.Length)
            cn.Close()
            Dim bitmap As New Bitmap(stream) ' <==The exception is being thrown 

            PictureBox1.Image = bitmap

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

но это не работает

F-ES Sitecore

Это всего лишь идея но попробуйте установить положение потока равным 0

течение.Запись(изображение, 0, изображение.Длина)
течение.Позиция = 0

2 Ответов

Рейтинг:
14

OriginalGriff

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

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?


Member 14108087

Спасибо OriginalGriff, я знаю о параметрах sql, я исправлю это, но моя проблема заключалась в извлечении изображения из базы данных sql во что-то вроде коробки с картинками или около того. Есть идеи, где я могу ошибиться?

OriginalGriff

Сначала исправьте свои проблемы с SQL-инъекцией во всем приложении, а затем посмотрите на эту проблему (вполне возможно, что исправление проблемы с инъекцией также исправляет ее, и это гораздо важнее!)
Затем, если он все еще начинается с отладчика: разбейте строку
Тусклое изображение в виде байта() = DirectCast(cmd.ExecuteScalar(), байт())
течение.Запись(изображение, 0, изображение.Длина)
Таким образом, вы можете более легко получить доступ к каждой части:

Dim return = cmd.Executescalar так()
Тусклое изображение в виде байта() = DirectCast(return, Byte())
течение.Запись(изображение, 0, изображение.Длина)

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

Соберите информацию о том, что происходит, и она должна быть разрешима. Без него? Никаких шансов!

Рейтинг:
12

Wendelius

По крайней мере, несколько вещей могут быть причиной исключения:
- Растровое изображение очень большое
- Ручей пуст.

Я предлагаю поместить точку останова на линии, где вы получаете данные, и убедиться, что данные правильно доступны, а также проверить, что размер изображения является разумным.

Вы также можете попробовать, если поведение отличается при использовании изображения вместо растрового изображения.

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

Если вам интересно, взгляните на Правильное выполнение операций с базой данных[^]


Member 14108087

Спасибо Венделиусу, я попробовал меньшее изображение, которое имеет размер 340 * 654, но все та же проблема. Любое изображение, которое я пытался извлечь из базы данных, даже маленький значок, та же ошибка. Любая помощь заранее благодарю Вас

Wendelius

Если вы поместите точку останова на линию

Dim bitmap As New Bitmap(stream)

Правильна ли длина потока, другими словами, Правильно ли он содержит данные изображения?