0

I have been trying to upload images to my database, but I get this error:

Implicit conversion from data type varchar to varbinary(max) is not allowed. Use the CONVERT function to run this query

Here is my code:

con.Open();

cmd = new SqlCommand("SELECT * FROM ImagePosts", con);
ad = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
ad.Fill(ds);

int id = ds.Tables[0].Rows.Count + 1;

byte[] buffer = File.ReadAllBytes(file);

SqlCommand cmd2 = new SqlCommand("INSERT INTO Images (Id, Title, Image) VALUES('" + id + "', '" + textBox1.Text + "', '" + "@image" + "')", con);

var binary1 = cmd2.Parameters.Add("@image", SqlDbType.VarBinary, -1);
binary1.Value = buffer;

cmd2.ExecuteNonQuery();
con.Close();
this.Close();

Edit: my bad, I forgot to remove the parenthesis around @image.

5
  • Leaving aside the actual error here, I don't think it is wise to store files in a database. Why don't you use the filesystem instead, and store the filepaths in the database? stackoverflow.com/a/13421029/1666620 Commented Apr 6, 2020 at 15:22
  • remove the single quotes around the @image parameter. and use the parameter approach for the textBox1.Text too. Commented Apr 6, 2020 at 15:29
  • @user1666620 two reasons pro: transactional integrity, one-file-contains-all backup. two reasons contra external storage and path reference: external paths can move, and server may not always have access to them unless (5 not obvious conditions are met), and would require a separate logic to safely write and retrieve them. Commented Apr 6, 2020 at 15:38
  • SQL Injection alert - you should not concatenate together your SQL statements - use parametrized queries instead to avoid SQL injection - check out Little Bobby Tables Commented Apr 6, 2020 at 16:37
  • And don't just parameterize SOME of the column values - do that for ALL of the them! Commented Apr 6, 2020 at 17:18

2 Answers 2

2

The issue is that you are inserting '@image' when it should just be @image. If you put '', that is saying you want to insert the value "@image" into the field. Drop the '' and it should work. However, I would also recommend doing the same thing for the Textbox.Text or else you can get Sql Injected:

           con.Open();
        cmd = new SqlCommand("SELECT * FROM ImagePosts", con);
        ad = new SqlDataAdapter(cmd);
        DataSet ds = new DataSet();
        ad.Fill(ds);
        int id = ds.Tables[0].Rows.Count + 1;


        byte[] buffer = File.ReadAllBytes(file);
        SqlCommand cmd2 = new SqlCommand("INSERT INTO Images (Id, Title, Image) VALUES('" + id + "', @Title, @image)", con);
        cmd2.Parameters.Add("@Title", textBox1.Text);
        var binary1 = cmd2.Parameters.Add("@image", SqlDbType.VarBinary, -1);
        binary1.Value = buffer;
        cmd2.ExecuteNonQuery();
        con.Close();
        this.Close();

You could even do it with the ID one, too.

Sign up to request clarification or add additional context in comments.

Comments

0

You don't need to wrap varbinary data in single quotes in sql server. Try this

SqlCommand cmd2 = new SqlCommand("INSERT INTO Images (Id, Title, Image) VALUES('" + id + "', '" + textBox1.Text + "',  @image)", con);

3 Comments

(why? it would mean the string '@image', which is implicitely a varchar, instead of the @image parameter's value, which at the same time explains the error message OP gets)
I don't understand what you're asking....but varbinary data is not encapsulated by single quotes in sql server
I felt that your expression "don't need to" is too weak and does not explain much: it's not optional - it's the cause for the error they're seeing. this is a suggestion to add the explanation to your answer. And while OP is at fixing their statement, they should remove the injection vulnerability that textBox1.Text is, too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.