For a few week I've been working on this application. One of the users wishes was to save and display images. So I've created this opportunity for the user to insert screenshots. However, when I first send the images to the database and retrieve them again, they can't be decoded into images anymore. (Error: Parameter is not valid.) So I checked whether is was the code or something else. I found out, that after converting the image into byte[], I could revert and display that without any trouble. So the problem lays somewhere between writing to the database and getting it back again. I had a look in the database, and noticed that every image started with 0x, even if there was no image to upload. I read something about some databases might add a header, so I guess that's what creates the problem. But now I need to know how to get rid of that header. And if I get rid of that reader, can I still just use the GetValue() function, or do I really need to use GetBytes()? The reason I didn't go for GetBytes in the first place, is that I need to assign a length in start, but that changes from image to image.
Can anyone tell me how to delete that header if that comes with it? I checked the values of the first few bytes, I hoped if I dropped the first two, they represent the 0x and the problem would be solved, but that's not how it works apparently. After that, I tried to upload a picture to the db and retrieve it again, I noticed the length went from 566 to 1335. The empty picture however, despite that the db says it has 0x in it, has a byte[] with a length of 0.
The object bsk will be send to a part of the code, which writes that to the database:
String command = "INSERT INTO " + db.getTabelbsk() + " VALUES ('" + bsk.getEmailapplicant() + "','" + bsk.getCreation().ToString("MM-dd-yyyy") + "','" + bsk.getCrmQuoteNumber()
+ "','" + bsk.getProjectStage() + "','" + bsk.getRefArticleId() + "','" + bsk.getClassification() + "','" + bsk.getDescription() + "','" +
bsk.getTrackingnumber() + "','" + bsk.getLastModified().ToString("MM-dd-yyyy") + "','" + bsk.getStatus() + "','" + bit + "','" + bsk.getScr() + "','" +
bsk.getBskMail() + "','" + bsk.getEnd12Mail() + "','" + bsk.getEnd3elecMail() + "','" + bsk.getEnd3swMail() + "','" + bsk.getPrmMail() + "','" +
bsk.getRejectMail() + "','" + bsk.getRejectReason() + "','" + bsk.getCommercialDescription() + "','" + bsk.getTechnicalDescription() + "','" +
bsk.getValue() + "','" + bsk.getEndhours() + "', '" + bsk.getLockedBy() + "', '";
command = addImages(command, bsk.getSrcSs()) + "', '" + addImages(command, bsk.getTechnicalDescriptionSs()) + "');";
sqlcommand(con, command);
private String addImages(String command, byte[] ba)
{ //Adds every byte to the command String
foreach (byte b in ba)
{
command += b;
}
return command;
}
public SqlDataReader sqlcommand(SqlConnection con, String s)
{ //Executes the command
try
{
con.Close();
}
catch { }
SqlCommand cmd = new SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = s;
cmd.Connection = con;
try
{
con.Open();
}
catch
{
}
SqlDataReader reader = cmd.ExecuteReader();
return reader;
}
This part is used to retrieve data from the database:
public Bsk returnBsk(Database db, Bsk bsk, SqlConnection con)
{ //This will retrieve the data from the database
String table = db.getTabelbsk();
int trackingnumber = bsk.getTrackingnumber();
String command = "SELECT * FROM " + table + " WHERE trackingNumber = " + trackingnumber;
SqlDataReader reader = sqlcommand(con, command);
reader.Read(); //Filling the object with data
bsk.setEmailapplicant(reader.GetString(0));
bsk.setCreation(reader.GetDateTime(1));
bsk.setCrmQuoteNumber(reader.GetString(2));
bsk.setProjectStage(reader.GetString(3));
bsk.setRefArticleId(reader.GetString(4));
bsk.setClassification(reader.GetString(5));
bsk.setDescription(reader.GetString(6));
bsk.setLastModified(reader.GetDateTime(8));
bsk.setStatus((Bsk.Status)Enum.Parse(typeof(Bsk.Status), reader.GetString(9)));
if (reader.GetBoolean(10) == false)
{
bsk.setComplexity((Bsk.Complexity.Simple));
}
else if (reader.GetBoolean(10) == true)
{
bsk.setComplexity((Bsk.Complexity.Complex));
}
bsk.setScr(reader.GetString(11));
bsk.setBskMail(reader.GetString(12));
bsk.setEnd12Mail(reader.GetString(13));
bsk.setEnd3elecMail(reader.GetString(14));
bsk.setEnd3swMail(reader.GetString(15));
bsk.setPrmMail(reader.GetString(16));
bsk.setRejectMail(reader.GetString(17));
bsk.setRejectReason(reader.GetString(18));
bsk.setCommercialDescription(reader.GetString(19));
bsk.setTechnicalDescription(reader.GetString(20));
bsk.setValue(reader.GetInt32(21));
bsk.setEndhours(reader.GetInt32(22));
bsk.setLockedBy(reader.GetString(23));
if (!Convert.IsDBNull(reader.GetValue(24)))
{
bsk.setSrcSs((byte[])reader.GetValue(24));
}
if (!Convert.IsDBNull(reader.GetValue(25)))
{
bsk.setTechnicalDescriptionSs((byte[])reader.GetValue(25));
}
reader.Close();
con.Close();
return bsk;
}
Image to byte[]:
Image imageSrc = pb_Src.Image;
byte[] arrSrc;
ImageConverter converterSrc = new ImageConverter();
arrSrc = (byte[])converterSrc.ConvertTo(imageSrc, typeof(byte[]));
bsk.setSrcSs(arrSrc);
byte[] to image:
byte[] arrSrc = bsk.getSrcSs();
MemoryStream ms = new MemoryStream(arrSrc);
pb_Src.Image = Image.FromStream(ms); <-- Error message appears here
PS:
I'm aware that How to display image from database in c# is related. However, this question never got answered.
Related
This question already has answers here:
how to get the last record number after inserting record to database in access
(6 answers)
Closed 1 year ago.
Am working with Access as Database in C# (Visual Studio 15). I want to save form entries (add record) into the Access Database and would want the corresponding ID of the record to show in MsgBox upon a successful saving. I have tried the following:
private void Form21_Load(object sender, EventArgs e)
{
try
{
connection.Open();
checkConnection.Text = "Server Connection, Successful";
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error, Server not connected " + ex);
}
}
private void Button6_Click(object sender, EventArgs e)
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "insert into Students_File ([YourNames],[Nationality],[StateOfOrigin],[PlaceOfBirth],[DoB],[HomeAddress],[LastSchools1],[LastClass1],[LastSchools2],[LastClass2],[LastSchools3],[LastClass3],[AdmClass],[CurrentClass],[Guidian],[GuardianContact],[UserName],[PassWord],[Gender],[RegistrationDate]) values('" + YourNames.Text + "','" + Nationality.Text + "','" + StateOfOrigin.Text + "','" + PlaceOfBirth.Text + "','" + DoB.Text + "','" + HomeAddress.Text + "','" + LastSchools1.Text + "','" + LastClass1.Text + "','" + LastSchools2.Text + "','" + LastClass2.Text + "','" + LastSchools3.Text + "','" + LastClass3.Text + "','" + AdmClass.Text + "','" + CurrentClass.Text + "','" + Guidian.Text + "','" + GuardianContact.Text + "','" + UserName.Text + "','" + PassWord.Text + "','" + Gender.Text + "','" + RegistrationDate.Text + "')";
command.ExecuteNonQuery();
//MessageBox.Show("Congrats! Your registration, is successful. You may now click close button, then proceed to login");
command.CommandText = "Select * from Students_File where UserName='" + UserName.Text + "' and PassWord='" + PassWord.Text + "'";
OleDbDataReader reader = command.ExecuteReader();
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("Congrats! Your registration, is successful. You may now click close button, then proceed to login");
this.Close();
}
else if (count > 1)
{
MessageBox.Show("Sorry, the chosen username or password is currently existing or picked by another user. Consequently, your registration was not successful. Do please, decide another but a unique one. Thank you");
}
connection.Close();
}
You can do it this way:
using (OleDbCommand Command = new OleDbCommand("", conn))
{
Command.CommandText = "Your big ugly mess - need to change this to parmaters!)";
Command.Connection.Open();
Command.ExecuteNonQuery();
Command.CommandText = "Select ##Identity";
var intLastID = Command.ExecuteScalar;
MsgBox("Last id into database = " + intLastID);
}
As noted, you do want to change that insert command - it too long, too difficult to maintain, and subject to mistakes in code and even sql injection.
But, for now, you can use the above approach to get/pick up the last ID insert.
In solution to my inquiry, i have the following code (From Kevin):
string query = "Insert Into Categories (CategoryName) Values (?)";
string query2 = "Select ##Identity";
int ID;
string connect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Northwind.mdb";
using (OleDbConnection conn = new OleDbConnection(connect))
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("#CategoryName", OleDbType.Integer);
conn.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = query2;
ID = (int)cmd.ExecuteScalar();
}
}
Now, my challenge is how do i get the ID to appear in messagebox after a successful record creation. Please consider my earliest code in this post in connection with this.
Here is my aspx.cs Code behind Class I am Setting properties and set correctly
Here is my getter/setter properties I get properties in SQL insert see below query
Here is my VoucherSubmit method that post the form into SQL Server 2012 database:
public class InsertData
{
public void VoucherSubmit()
{
myconection mycon = new myconection();
VoucherForm vr = new VoucherForm();
string Query1 = "insert into Voucher(VrType,VrDate,CreatedBy,CreationDate,SubmittedBy,SubmittedDate,ApprovedBy,ApprovedDate,Method,BillNo,ChequeNo,DemandNo,Branch,AccountDebit,AccountCredit,Debit,Credit,Description)values('" + vr.getvouchertype() + "','" + vr._date + "','" + vr._createdby + "','" + vr.getvoucher_creationdate() + "','" + vr._submittedby + "','" + vr._submitteddate + "','" + vr._approvedby + "','" + vr._approveddate + "','" + vr._method + "','" + vr._billno + "','" + vr._chequeno + "','" + vr._demandno + "','" + vr._branch + "','" + vr._accountdebit + "','" + vr._accountcredit + "','" + vr._debit + "','" + vr._credit + "','" + vr._description + "')";
SqlCommand cmd = new SqlCommand(Query1, mycon.GetConnection());
cmd.ExecuteNonQuery();
mycon.GetConnection().Close();
}
}
You are not passing initialized VoucherForm, but creating new one in your VoucherSubmit method.
public void btn_save_Click(object sender, EventArgs e)
{
// All the stuff you have there just change single line
insert.VoucherSubmit(vf);
}
public void VoucherSubmit(VoucherForm vf)
{
myconection mycon = new myconection();
// remove VoucherForm vf = new VoucherForm();
string Query1 = "insert into Voucher(VrType,VrDate,CreatedBy,CreationDate,SubmittedBy,SubmittedDate,ApprovedBy,ApprovedDate,Method,BillNo,ChequeNo,DemandNo,Branch,AccountDebit,AccountCredit,Debit,Credit,Description)values(#VrType,#VrDate,#CreatedBy,#CreationDate,#SubmittedBy,#SubmittedDate,#ApprovedBy,#ApprovedDate,#Method,#BillNo,#ChequeNo,#DemandNo,#Branch,#AccountDebit,#AccountCredit,#Debit,#Credit,#Description)";
SqlCommand cmd = new SqlCommand(Query1, mycon.GetConnection());
cmd.InsertCommand.Parameters.Add("#VrTyp").Value = vr.getvouchertype();
cmd.InsertCommand.Parameters.Add("#VrDate").Value = vr._date;
cmd.InsertCommand.Parameters.Add("#CreatedBy").Value = vr._createdby;
cmd.InsertCommand.Parameters.Add("#CreationDate").Value = vr.getvoucher_creationdate();
cmd.InsertCommand.Parameters.Add("#SubmittedBy").Value = vr._submittedby;
cmd.InsertCommand.Parameters.Add("#SubmittedDate").Value = vr._submitteddate;
cmd.InsertCommand.Parameters.Add("#ApprovedBy").Value = vr._approvedby;
cmd.InsertCommand.Parameters.Add("#ApprovedDate").Value = vr._approveddate;
cmd.InsertCommand.Parameters.Add("#Method").Value = vr._method;
cmd.InsertCommand.Parameters.Add("#BillNo").Value = vr._billno;
cmd.InsertCommand.Parameters.Add("#ChequeNo").Value = vr._chequeno;
cmd.InsertCommand.Parameters.Add("#DemandNo").Value = vr._demandno;
cmd.InsertCommand.Parameters.Add("#Branch").Value = vr._branch;
cmd.InsertCommand.Parameters.Add("#AccountDebit").Value = vr._accountdebit;
cmd.InsertCommand.Parameters.Add("#AccountCredit").Value = vr._accountcredit;
cmd.InsertCommand.Parameters.Add("#Debit").Value = vr._debit;
cmd.InsertCommand.Parameters.Add("#Credit").Value = vr._credit;
cmd.InsertCommand.Parameters.Add("#Description").Value = vr._description;
cmd.ExecuteNonQuery();
mycon.GetConnection().Close();
}
UPDATE:
Dan Guzman in the comment suggested to use overload with specified sql data type to avoid performance issues.
the main point of the article I referenced is that the SqlDbType
should be explicitly specified along with the max length in the case
of varchar columns. For example,
cmd.Parameters.Add("#VrDate",
SqlDbType.DateTime).Value = DateTime.ParseExact(vr._date,
"yyyy-MM-dd", null);
This will ensure the desired data types are
passed and avoid excessive cached plans in SQL Server.
Thanks for update!
Related links:
Can we stop using AddWithValue() already?
I´m using C# Windows forms application and i got 5 items in a checklistbox.
Now I have to save these items into a MS Access database table.
Does anyone knows how i should do it?
(Sprachen = checkedlistbox)
private void button1_Click_1(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "INSERT INTO Employee (Vorname, Nachname, Wohnort, Geburtstag, Abteilung, Nummer, MKZ, Führerschein, Sprachen) values('" + Vorname.Text + "','" + Nachname.Text + "','" + Wohnort.Text + "','" + Geburtstag.Text + "','" + Abteilung.Text + "','" + Mitarbeiter.Text + "','" + MKZ.Text + "'," + Führerschein.Checked.ToString() + "," + Sprachen.SelectedItems + ")";
command.ExecuteNonQuery();
MessageBox.Show("Daten gespeichert!");
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
everytime i tried it with toString(), it gives me an error:
For at least one required parameter no value was specified.
I can only count how many items i´ve checked in the checklistbox.
Anyone got an solution?
Sprachen.SelectedItems returns list of selected items. If you are trying to insert the items which are checked in checkedlistbox then you have to loop for checklistbox.CheckedItems.
Instead of "Sprachen.SelectedItems" pass checklistbox.CheckedItems[0].ToString() as value and check the code. Note: 0 is hard coded.. later you can loop it
String type value must be passed within single quote. Check out last two fields.
I have a sql table which has an image cloumn I'm trying to insert the image after converting it into byte.... the my insert query looks like this
INSERT INTO Member (F_NAME, L_NAME, D_O_B, UAE_ID_NO, MOBILE_NO, EMAIL_ID, REFERER, REF_CONTACT, ADDRESS, PICTURE) VALUES ('" + fname + "','" + lname + "','" + dob.ToShortDateString() + "','" + uaeid + "','" + mobile + "','" + emailid + "','" + reffere + "','" + refercontact + "','"+address+"',"+photo+")"
here pic is the image column... I'm converting the image into byte array using the following method
MemoryStream ms = new MemoryStream();
//save the image into memory stream
pBoxMember.Image.Save(ms, ImageFormat.Jpeg);
//assign the byte array with total size of memorystream
photo = new byte[ms.Length];
ms.Position = 0;
ms.Read(photo, 0, photo.Length);
return true;
But it is giving me this error
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
invalid syntax near ".
If this should work at all this should look like this:
var sql = "INSERT INTO Member (F_NAME, L_NAME, D_O_B, UAE_ID_NO, MOBILE_NO, " +
"EMAIL_ID, REFERER, REF_CONTACT, ADDRESS, PICTURE) " +
"VALUES ('" + fname + "','" + lname + "','" + dob.ToShortDateString() + "','" + uaeid + "','" + mobile + "','" + emailid + "','" + reffere + "','" + refercontact + "','" + address + "'," + photo + ")"
But you should use SQL Params for this, something like:
string queryString = "INSERT INTO Member (F_NAME, L_NAME, D_O_B, UAE_ID_NO, ... VALUES(#fname ,#lname ....)";
SqlCommand cmd = new SqlCommand(queryString, dbConnection);
cmd.Parameters.AddWithValue("#fname",fname);
cmd.Parameters.AddWithValue("#lname",lname);
...
cmd.Parameters.AddWithValue("#blobParam",YourBytesArray);
...
cmd.ExecuteNonQuery();
I am getting an error while i am trying to insert a user id of my client in the ms access database.
The error i am getting is Overflow.
when i am trying to insert its getting the above error.
I am using these code.
OleDbCommand cmd = new OleDbCommand("insert into UserInfo " + "([firstname], [lastname], [gender], [occupation], [expirydate], [UserId], [phoneno]) " + " values('" + txt_FirstName.Text + "','" + txt_LastName.Text + "','" + cmb_Gender.Text + "','" + cmb_Occupation.Text + "','" + txt_expiryDate.Text + "','" + txt_HardDiskId.Text + "','" + txt_PhoneNo.Text + "');", con);
OleDbCommand cmd1 = new OleDbCommand("select * from UserInfo where (HardDiskId='" + txt_HardDiskId.Text + "')", con);
int temp = 0;
try
{
con.Open();
string count = (string)cmd1.ExecuteScalar();
if ((count == "") || (count == null))
{
temp = cmd.ExecuteNonQuery();
if (temp > 0)
{
MessageBox.Show("User ID of " + txt_FirstName.Text + " " + txt_LastName.Text + " has been added");
}
else
{
MessageBox.Show("Record not added");
}
}
else
{
MessageBox.Show("User ID of " + txt_FirstName.Text + " already exists. Try another user ID.");
}
}
Aside from being open to SQL Injection (which you should parameterize your OleDbCommand), first thought on a problem is what you are trying to store the data. Do any of the text fields have special characters or apostrophe in name which would otherwise pre-terminate your embedded .... '" + nextField + "' ..." entries and throw the balance off.
Another... don't know if the parser is picky or not... but a space after values, before open paren.... " values(" to " values (".
Third, and more probable the issue is the expiration date. If its a date field, and you are trying to put in as text, it might be failing on the data type conversion.