I have a OpenFileDialog which will suppose to select photo and save it to database
but the problem is when I access the class when the dialog result of the openFileDialog is OK
it says that no such table : PhotoFile when the SavePhoto function is called with following arguments:
TODO(P J):put values here
This is what I've tried so far
OpenFileDialog d = new OpenFileDialog();
d.Filter = ("JPEG Imange (*.jpg|*.jpg|PNG Image (*.png)|All Files*.*");
if ((d.ShowDialog()) == DialogResult.OK)
{
SavePhoto(txtID.text,d.fileName);
}
Here's the code for the function
try {
using (SQLite.SQLiteConnection SQLConnect = new SQLite.SQLiteConnection(g_constring)) {
byte[] photo = FileImageToByte(PhotoFile);
SQLConnect.Open();
if (SQLConnect.State == ConnectionState.Open) {
SQLiteCommand SQLcommand = new SQLiteCommand(SQLConnect);
SQLcommand = SQLConnect.CreateCommand;
SQLcommand.CommandText = "DELETE FROM PhotoFile WHERE PhotoID = '" + PhotoId + "'";
SQLcommand.ExecuteNonQuery();
SQLcommand.Parameters.Clear();
SQLcommand.CommandText = "INSERT INTO PhotoFile(PhotoID, Photo) VALUES(#EmployeeID, #Photo1)";
SQLiteParameter SQLparmID = new SQLiteParameter("#EmployeeID", PhotoId);
SQLparmID.DbType = DbType.String;
SQLparmID.Value = PhotoId;
SQLcommand.Parameters.Add(SQLparmID);
SQLiteParameter SQLparm = new SQLiteParameter("#Photo1", photo);
SQLparm.DbType = DbType.Binary;
SQLparm.Value = photo;
SQLcommand.Parameters.Add(SQLparm);
SQLcommand.ExecuteNonQuery();
bReturn = true;
} else {
bReturn = false;
}
}
} catch (System.Exception eX) {
MessageBox.Show(eX.Message.ToString(), "Error in database", MessageBoxButtons.OK, MessageBoxIcon.Error);
bReturn = false;
}
return bReturn;
}
PhotoFile table exist in my database in fact I've tried a Windows form and trigger the function if the dialog result = ok but when I used the openFileDialog it always produce the error as stated above.
This isn't anything to do with the OpenFileDialog per se, it's your SQL query failing and stating that the table doesn't exist (Photofile) - so I would suggest that it doesn't and you should either check your table name, or create it if necessary.
Other than that, there is concern over your query: your method indicates that a photo will be saved yet you use a DELETE. Also, if the table did exist/when you manage to sort the table name correctly, I'd suggest you don't use strings as identifiers. No saving going on anywhere.
Your AppMain.ConnectionString is pointing at the wrong database, which does not contain any PhotoTable table. You might want to double check it.
Your code deletes the record matching the provided PhotoID by the way, it's not saving anything to the database.
Related
Hallo I am still new in this game. I am struggling to select the username and password from the database to verify it.
What this below mentioned code can do is ONLY select the username.
I need help to modify the select statement to select both username and password.
public override int SelectUser(string username, ref User user)
{
int rc = 0;
try
{
_sqlCon = new SQLiteConnection(_conStr);
bool bRead = false;
user = new User();
_sqlCon.Open();
// This selection string is where I am struggling.
string selectQuery = "SELECT * FROM Users WHERE [uUsername] = ' " + username + " ' ";
SQLiteCommand sqlCmd = new SQLiteCommand(selectQuery, _sqlCon);
SQLiteDataReader dataReader = sqlCmd.ExecuteReader();
bRead = dataReader.Read();
if(bRead == true)
{
user.Username = Convert.ToString(dataReader["uUsername"]);
user.Password = Convert.ToString(dataReader["uPW"]);
rc = 0;
}// end if
else
{
rc = -1;
}// end else
dataReader.Close();
}// end try
catch(Exception ex)
{
throw ex;
}// end catch
finally
{
_sqlCon.Close();
}// end finally
return rc;
}// end method
You add the AND logical operator to the WHERE first condition to get a double condition. However, this whole approach using string concatenations is wrong.
It is a well known source of bugs and a big security risk called Sql Injection
Instead you use a parameterized query like this
string selectQuery = #"SELECT * FROM Users
WHERE [uUsername] = #name AND
[uPw] = #pass";
SQLiteCommand sqlCmd = new SQLiteCommand(selectQuery, _sqlCon);
sqlCmd.Parameters.Add("#name", DBType.String).Value = username;
sqlCmd.Parameters.Add("#pass", DBType.String).Value = password;
SQLiteDataReader dataReader = sqlCmd.ExecuteReader();
bRead = dataReader.Read();
....
I assume that you have in the variable password the value to search for, change it to your actual situation.
Consider also that storing passwords in clear text inside a database is another security risk to avoid. The question Best way to store password in a database explains in great detail the reasons and the correct way to do it
I've written a method which will try and delete a row from a db table based on a primary key id. The problem i have is that the try block is always returning "Success" even if a record has already been deleted / or it doesn't exist.
public string delete_visit(int id)
{
string deleteResponse = null;
string cnn = ConfigurationManager.ConnectionStrings[connname].ConnectionString;
using (SqlConnection connection = new SqlConnection(cnn))
{
string SQL = string.Empty;
SQL = "DELETE FROM [" + dbname + "].[dbo].[" + tbname + "] WHERE VisitorNumber = #IDNumber ";
using (SqlCommand command = new SqlCommand(SQL, connection))
{
command.Parameters.Add("#IDNumber", SqlDbType.Int);
command.Parameters["#IDNumber"].Value = id;
try
{
connection.Open();
command.ExecuteNonQuery();
deleteResponse = "Success";
}
catch (Exception ex)
{
deleteResponse = "There was a problem deleting the visit from the database. Error message: " + ex.Message;
}
}
}
return deleteResponse;
}
I want to be able to tell if the row was affected. I can do this in SQL Server Management Studio like so:
DELETE FROM Visits
WHERE VisitorNumber=88;
IF ##ROWCOUNT = 0
PRINT 'Warning: No rows were updated';
So i want to know how do i plug in the ##ROWCOUNT bit into my c# so that i can tell if the row was deleted?
thanks
ExecuteNonQuery() returns an int, indicating how many rows were affected.
So:
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 0)
{
deleteResponse = "No rows affected";
}
The problem is that this number can be influenced based on what the query actually does. Executing triggers or calling stored procedures could mess with the output, changing the affected number of rows. If you really must, then first execute a query where you check that the record with the given ID exists.
I have a form which displays selected datagridviewrow data in textboxes. I would like to edit and update the data from this form and update and save into the datatable when the user clicks update.
When I click update I get an error message:
There was an error parsing the query. [ Token line number = 1,Token line offset = 25,Token in error = ( ]
private void editBTN_Click(object sender, EventArgs e)
{
bool notEditable = true;
if (editBTN.Text == "Update")
{
UpdateDataBase();
editBTN.Text = "Edit";
deleteBTN.Visible = true;
notEditable = true;
}
else
{
deleteBTN.Visible = false;
editBTN.Text = "Update";
deleteBTN.Visible = false;
notEditable = false;
}
firstTxt.ReadOnly = notEditable;
surenameTxt.ReadOnly = notEditable;
address1Txt.ReadOnly = notEditable;
address2Txt.ReadOnly = notEditable;
countyTxt.ReadOnly = notEditable;
contactTxt.ReadOnly = notEditable;
emailTxt.ReadOnly = notEditable;
postTxt.ReadOnly = notEditable;
}
private void UpdateDataBase()
{
if (MessageBox.Show("Customer information will be updated. This change cannot be undone. Are you sure you want to continue? ", "Confirm Edit", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
string constring = #"Data Source=|DataDirectory|\LWADataBase.sdf";
string Query = "update customersTBL set ([First_Name] = '" + this.firstTxt.Text + "',surename= '" + this.surenameTxt.Text + "',[Address Line 1] = '" + this.address1Txt.Text + "',[Address Line 2] = '" + this.address2Txt.Text + "',County = '" + this.countyTxt.Text + "',[Post Code] = '" + this.postTxt.Text + "' , Email = '" + this.emailTxt.Text + "';,[Contact Number] = '" + this.contactTxt.Text + "');";
SqlCeConnection conDataBase = new SqlCeConnection(constring);
SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase);
SqlCeDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
MessageBox.Show("Customer information has been updated", "Update Sucessful");
while (myReader.Read())
{
}
MessageBox.Show("Please exit the Customers window and re-open to update the table");
this.Close();
//displays a system error message if a problem is found
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
There are some problems in your code.
One is trivial and could be easily fixed (remove the semicolon before the [Contact Number], but there are other hidden problems that potentially are more serious.
First: Remember to always close and dispose the disposable objects
(connection and command in this case). The using statement ensure
that the object enclosed by the using block will be correctly closed
and disposed also in case of exceptions
Second: Use a parameterized query. This avoids Sql Injections and
parsing problems. If one or more of your input data contains a single
quote, the string concatenation used to build the sql command text
will resul in an invalid command
Third: An update command acts on all the records present in the table
if you don't add a WHERE condition. Usually the WHERE condition is
added to identify the only record that need to be updated and it is
the value of a field with UNIQUE index or the PRIMARY KEY of your
table. Of course you could update more than one record with a less
restrictive WHERE clause but this doesn't seem to be the case
Fourth: Use the ExecuteNonQuery instead of ExecuteReader for commands
that update/insert the database (well it works equally but why use a
method that should be reserved for other uses?)
private void UpdateDataBase(int customerID)
{
string constring = #"Data Source=|DataDirectory|\LWADataBase.sdf";
string Query = #"update customersTBL set [First_Name] = #fname,
surename = #sur, [Address Line 1] = #addr1,
[Address Line 2] = #addr2, County = #county,
[Post Code] = #pcode, Email = #mail, [Contact Number] = #ctNo
WHERE customerID = #id";
using(SqlCeConnection conDataBase = new SqlCeConnection(constring))
using(SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase))
{
try
{
conDataBase.Open();
cndDataBase.Parameters.AddWithValue("#fname", this.firstTxt.Text);
cndDataBase.Parameters.AddWithValue("#sur", this.surenameTxt.Text );
cndDataBase.Parameters.AddWithValue("#addr1", this.address1Txt.Text );
cndDataBase.Parameters.AddWithValue("#addr2", this.address2Txt.Text );
cndDataBase.Parameters.AddWithValue("#county", this.countyTxt.Text );
cndDataBase.Parameters.AddWithValue("#pcode", this.postTxt.Text );
cndDataBase.Parameters.AddWithValue("#mail", this.emailTxt.Text );
cndDataBase.Parameters.AddWithValue("#ctNo", this.contactTxt.Text );
cndDataBase.Parameters.AddWithValue("#id", customerID );
int rowsUpdated = cmdDataBase.ExecuteNonQuery();
if(rowsUpdate == 0)
MessageBox.Show("No customer found to update");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
As you can see, with a parameterized query is more difficult to write a bad sql text with hidden problems and the quoting job is passed to the database code that knows better how to format the parameter values.
The only problem that you need to solve is how to retrieve the value for the customerID or some other value that you could use in the WHERE clause to uniquely identify the record of your customer
In this point you call the UpdateDatabase method that now required a UserID variable containing the key to identify your user on the table
private void editBTN_Click(object sender, EventArgs e)
{
bool notEditable = true;
if (editBTN.Text == "Update")
{
// Here you need to identify uniquely your modified user
// Usually when you load the data to edit you have this info extracted from your
// database table and you have saved it somewhere
// (of course the user should not edit in any way this value
int UserID = ... ???? (from an hidden textbox? from a global variable, it is up to you
UpdateDataBase( UserID );
I think your confusing the Update structure with an Insert.
For your update it looks like this:
update customersTBL set ([First_Name] = 'data', surename= '',[Address Line 1] = '',[Address Line 2] = '',County = '',[Post Code] = '' , Email = '';,[Contact Number] = '');
You need a where clause.
Update/Set does not put the changes in ()
After email you have a ';'
I want insert the data into the database.
string pa = "4898";
string equery="Insert into Users(pas)values('"+pa+"')";
while I inserting the data to the database,its says string or binary data would be truncated the statement has been terminated. So I changed nvarchar(50) into nvarchar(max) in the table.
And these statement has been executed and saved in the database of unreadable format like 傉䝎ਚ this. And how can be over come this problem and save the data in the database as "4898".
private void save_Click(object sender, EventArgs e)
{
string password = "4898";
string equery="Insert into Users(name,gender,dateofbirth,age,fathername,
address,citiy,state,country,zipcode,
mobile,phone,email,jobtitle,
dateofjoin,pic,passwords)
values('"+nametxt.Text.ToString().Trim()+"',
#gender,
'"+dateofbirth.Text.ToString().Trim()+"',
'"+age.Value.ToString().Trim()+"',
'"+fathertxt.Text.ToString().Trim()+"',
'"+addresstxt.Text.ToString().Trim()+"',
'"+citiytxt.Text.ToString().Trim()+"',
'"+statetxt.Text.ToString().Trim()+"',
'"+country.Text.ToString().Trim()+"',
'"+ziptxt.Text.ToString().Trim()+"',
'"+mobiletxt.Text.ToString().Trim()+"',
'"+phonetxt.Text.ToString().Trim()+"',
'"+emailtxt.Text.ToString().Trim()+"',
'"+jobtxt.Text.ToString().Trim()+
"','"+dateofjoin.Text.ToString().Trim()+"',
'"+password+"',#pic)";
SqlCommand cmd = new SqlCommand(equery, con);
if(male.Checked)
cmd.Parameters.AddWithValue("#gender","Male");
else
cmd.Parameters.AddWithValue("#gender","Female");
MemoryStream stream = new MemoryStream();
pictureBox1.Image.Save(stream,System.Drawing.Imaging.ImageFormat.Png);
byte[] pic = stream.ToArray();
cmd.Parameters.AddWithValue("#pic", pic);
try
{
con.Open();
cmd.ExecuteNonQuery();
MessageBox.Show("Saved Successfully");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
}
MessageBox.Show("Saved Successfully");
idtxt.Text = "";
nametxt.Text = "";
age.Value = Convert.ToDecimal(null);
male.Checked = false;
female.Checked = false;
dateofbirth.Text = "";
fathertxt.Text = "";
addresstxt.Text = "";
citiytxt.Text = "";
statetxt.Text = "";
country.Text = "";
ziptxt.Text = "";
mobiletxt.Text = "";
phonetxt.Text = "";
emailtxt.Text = "";
dateofjoin.Text = "";
jobtxt.Text = "";
pictureBox1.Image = null;
}
Looking at your insert statement:
"Insert into Users(... pic,passwords) values (... '"+password+"',#pic)";
it seems that you interchanged pic and passwords.
Also, as others already pointed out in the comments, you should use only parameterised queries (to prevent SQL Injection), especially when handling text inserted by an user or any other untrusted source.
There is a Logical error in your code. Interchange
'"+password+"',#pic)";
in your string equery.
By the way a suggestion! It is better to use 'linq to Sql' rather than query pass method! Because 'Linq to Sql' does every thing for you. you just have to give values :)
I have developed a windows application with vs2010 and c#. I would like to know a way to backup and restore my local mdf database programmatically. With sdf database I use File Copy but it doesn't seem to work with mdf files.
Can anyone help?
Try in this way:
Go to Sql Management Studio and select the database you want to
backup
Right click and select 'Tasks' -> 'Backup'
Adjust the parameters as you like, but don't confirm the dialog
Press the button SCRIPT and dismiss the dialog
On the query window insert the following text before the backup
command
CREATE PROCEDURE DO_BACKUP
AS
BEGIN
-- HERE GOES THE BACKUP TEXT CREATED BY THE SCRIPT BUTTON
-- FOR EXAMPLE
BACKUP DATABASE [Customers]
TO DISK = N'E:\backups\customers.bak'
WITH NOFORMAT, NOINIT,
NAME = N'Customers - Full Database Backup',
SKIP, NOREWIND, NOUNLOAD, STATS = 10
END
and execute (selecting the correct database) using the exclamation mark button.
Now you have a stored procedure called DO_BACKUP that you can call from your code using the normal ADO.NET objects like SqlConnection and SqlCommand
I struggled a lot with this, and the accepted answer does not do the trick, so here is a solution that worked for me (thanks to dnxit)
it may help someone.
Backup
try
{
var dlg = new System.Windows.Forms.FolderBrowserDialog();
var result = dlg.ShowDialog(this.GetIWin32Window());
if (result.ToString() == "OK")
{
var dbfileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "LibraryManger.mdf");
var backupConn = new SqlConnection { ConnectionString = eb.GetConnectionString() };
backupConn.Open();
var backupcomm = backupConn.CreateCommand();
var backupdb = $#"BACKUP DATABASE ""{dbfileName}"" TO DISK='{Path.Combine(dlg.SelectedPath,"LibraryManagement.bak")}'";
var backupcreatecomm = new SqlCommand(backupdb, backupConn);
backupcreatecomm.ExecuteNonQuery();
backupConn.Close();
MessageBox.Show($"Database backup has successfully stored in {Path.Combine(dlg.SelectedPath, "LibraryManagement.bak")}", "Confirmation");
}
}
catch (Exception ex)
{
if(ex.Message.Contains("Operating system error"))
{
MessageBox.Show("Please chose a public folder.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
else
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
Restore
You'll have to close existing connection before you restore
try
{
if (eb != null)
{
eb.DisposeConnection();
eb = null;
}
var dlg = new OpenFileDialog();
dlg.InitialDirectory = "C:\\";
dlg.Filter = "Database file (*.bak)|*.bak";
dlg.RestoreDirectory = true;
if (Equals(dlg.ShowDialog(), true))
{
using (var con = new SqlConnection())
{
con.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;Database=Master;Integrated Security=True;Connect Timeout=30;";
con.Open();
var dbfileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "LibraryManger.mdf");
using (var cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = $#"RESTORE DATABASE ""{dbfileName}"" FROM DISK='{dlg.FileName}'";
cmd.ExecuteNonQuery();
}
con.Close();
}
MessageBox.Show($"Database backup has successfully restored.", "Confirmation");
eb = new EntityBroker.EntityBroker();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}