The current program I am building is used to save invoices and I want to save data into a database. However instead of repeating this code shown below 20 times for each possible entry i would like to create a function with the text box name changing in the function.
All the text boxes are named with a number at the end from 1 to 20. I was wondering if there is a way to have a function that would change the number at the end and if its even worth doing compared to repeating this 20 times.
if (txtProductID1.Text.Length > 0)
{
OleDbConnection oledbconnection1 = new OleDbConnection();
oledbconnection1.ConnectionString = Con;
OleDbCommand cmd;
String strInsert = "";
//Generate SQL Statement
strInsert = "Insert into [InvoiceOrder] Values (";
strInsert += "'1', ";
strInsert += "'" + txtInvoiceNo.Text + "', ";
strInsert += "'" + txtProductDescription1.Text + "', ";
strInsert += "'" + txtOrderNo1.Text + "', ";
strInsert += "'" + cboUnit1.Text + "', ";
strInsert += "'" + txtAmount1.Text + "', ";
strInsert += "'" + txtPrice1.Text + "', ";
strInsert += "'" + txtSum1.Text + "', ";
strInsert += "'" + txtDiscount1.Text + "' ";
strInsert += ")";
try
{
oledbconnection1.Open();
cmd = new OleDbCommand();
cmd.CommandText = strInsert;
cmd.Connection = oledbconnection1;
cmd.ExecuteNonQuery();
//MessageBox.Show("Record saved");
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.ToString());
}
finally
{
oledbconnection1.Close();
}
}
First, parameterize your query. Aside from security, the query you're building up is going to trip you up when you forget a single apostrophe somewhere.
As for iterating through the controls, perhaps Controls.Find() will work for you. The following code assumes all controls have a number from 1 to 20, and each number occurs once and only once on the form. (In your example, txtInvoiceNo does not have a number - I assume that's a typo.)
I made a few other changes too, like replacing your finally block with a using block, which will close and dispose your connection for you.
for (var i = 1; i <= 20; i++)
{
if (!String.IsNullOrEmpty(Controls.Find("txtProductID" + i, true).Single().Text))
{
using (var oledbconnection1 = new OleDbConnection())
{
oledbconnection1.ConnectionString = Con;
oledbconnection1.Open();
var insertStatement =
"Insert into [InvoiceOrder] Values ('1', #InvoiceNo, #ProductDesc, #OrderNo, #Unit, #Amount, #Price, #Sum, #Discount)";
try
{
using (var cmd = new OleDbCommand(insertStatement, oledbconnection1))
{
cmd.Parameters.AddWithValue("#InvoiceNo", Controls.Find("txtInvoiceNo" + i, true).Single().Text);
...
...
cmd.Parameters.AddWithValue("#Discount", Controls.Find("txtDiscount" + i, true).Single().Text);
cmd.ExecuteNonQuery();
//MessageBox.Show("Record saved");
}
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.ToString());
}
}
}
}
Related
I've a problem with SqlConnection in C#. I do a large number of INSERT NonQuery, but in any case SqlConnection save in the database always the first 573 rows. This is the method I use for queries. In this method there is a lock because I use different thread to save the data.
public void InsertElement(string link, string titolo, string text)
{
string conString = "*****************";
using (SqlConnection connection = new SqlConnection(conString))
{
connection.Open();
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
}
This is the code of the loop that call the method InsertElement()
public void Save()
{
string[] DatiLetti;
string url = "";
while (result.Count > 0)
{
try
{
url = result.Last();
result.RemoveAt(result.Count - 1);
DatiLetti = ex.DirectExtractText(url);
if (DatiLetti[0].Length > 2)
{
ssc.InsertGare(url, DatiLetti[0], DatiLetti[1]);
}
}
catch (Exception exc)
{
logger.Error("Exception SpiderSave> " + exc);
}
}
}
Result is a volatile array that is progressively filled from other thread. I'm sure that the array contains more than 573 items.
I try to search one solution, but all the answers say that the number of database connections for SQLServer is over 32K at a time and I've already checked this number in my database. Is there anyone who can help me understand the problem?
Don't open a connection for every insert. Use one connection, then pass that connection through to your insert, like this :
public void InsertElement(string link, string titolo, string text, SqlConnection conn)
{
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
I recommend also looking at paramatizing your query, as well as using bulk inserts, and not individual inserts
If you are executing InsertElement() once for each rows of data to insert, then the execution will be too slow for large no. of rows. (Also, you are creating SqlConnection for each query execution.) Try adding many rows at once using a single INSERT query:
INSERT INTO tablename
(c1,c2,c3)
VALUES
(v1,v2,v3),
(v4,v5,v6)
...
I got a situation here. I need to insert values into tables depending on what a user provides on the Window form.
If a good does not exist and more than is necessary is acquired the the excess must be entered into a table called "BulkAvailable" this is where a big exists in my code as when I comment this part out the code runs well.
Please find the piece of code below
try
{
SqlConnection con = new SqlConnection("Data Source=PV10\\LOCALSERVER;Initial Catalog=SmallSoftwareDB;Integrated Security=True;Pooling=False");
con.Open();
float a = float.Parse(textBox8.Text, System.Globalization.CultureInfo.InvariantCulture);
int b = int.Parse(textBox9.Text);
float c = a * b;
var T = c.ToString(System.Globalization.CultureInfo.InvariantCulture);
float x = float.Parse(textBox4.Text, System.Globalization.CultureInfo.InvariantCulture);
int z = int.Parse(textBox3.Text);
float y = x * z;
var total = y.ToString(System.Globalization.CultureInfo.InvariantCulture);
int d = b - z;
string uba = "insert into BulkSale(ProductName, ProductSource, Date, Quantity, Type, UnitPrice, Total, Nature) values('" + textBox1.Text + "', '" + textBox2.Text + "', '" + dateTimePicker1.Value + "', '" + textBox3.Text + "', '" + textBox6.Text + "', '" + textBox4.Text + "', '" + textBox5.Text + "', '"+textBox7.Text+"')";
string A = "insert into BulkInput(ProductName, ProductSource, Date, Quantity, Type, UnitPrice, Total, Nature) values('"+textBox1.Text+"','"+textBox2.Text+"','"+dateTimePicker1.Value+"','"+b+"','"+textBox6.Text+"','"+a+"','"+c+"', '"+textBox7.Text+"')";
SqlCommand cmd = new SqlCommand(uba, con);
SqlCommand X = new SqlCommand(A, con);
cmd.ExecuteNonQuery();
X.ExecuteNonQuery();
try
{
if (int.Parse(textBox9.Text) > int.Parse(textBox3.Text))
{
string B = "insert into BulkAvailable(ProductSource,ProductName,Date,Quantity,Type) values('" + textBox2.Text + "','" + textBox1.Text + "','" + dateTimePicker1.Text + "','" + d + "','" + textBox6.Text + "')";
SqlCommand Bc = new SqlCommand(B, con);
Bc.ExecuteNonQuery();
}
else
{
MessageBox.Show("You successfully Bought and Sold", " ", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
catch (Exception aze)
{
MessageBox.Show(aze.Message, " ", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
MessageBox.Show("Operation Successfully Executed", " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
con.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message, " ", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
When I run the code it returns an exception message:
"String of binary data would be truncated. The statement has been terminated"
You should check your fields in database. This error means that you are tring to insert string with more length than the boundaries of the field.
So for an example if you have db field ProductName defined as varchar(50) and you try to insert value which have 52 characters in it, you will receive this error.
We can't tell you on which exact field this happen, you should check it manually. You can try to execute the query in the DB and see if the error gives you the field name, but in the past this not happen.
You should implement some validation checks about your fields, if they go over some Length show an error message or cut the string using Substring method.
I have a Sql Server connected to a C# form application which displays data strings. On the Sql Server side the data is saved as varChar(MAX) in all three instances. I would just like to display the data onto a RichTextBox on the form. The data is only showing a limited amount of the original data (coming out as incomplete) in the first RichTextBox (DataQualityTextBox) and it is not showing on the second and third RichTextBoxes (LoadFailureTextBox, and LoadPerformanceTextBox).
This is my code:
SqlConnection conDataBase = new SqlConnection(constring);
// POPULATING THE DATA QUALITY TAB
Query = "SELECT " + notes_field1 + ", "+ notes_field2 + ", " + notes_field3 + " FROM "+ database +" " +
" WHERE RunDate = '" + formattedDate + "'" +
" AND PackageName = '" + tdwl + "'" +
" AND Instance = '" + instance + "'; ";
SqlCommand cmdDataBase = new SqlCommand(Query, conDataBase);
SqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
DataQualityTextBox.Text = myReader[0].ToString();
LoadFailureTextBox.Text = myReader[1].ToString();
LoadPerformanceTextBox.Text = myReader[2].ToString();
}
conDataBase.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Thank you very much!
try:
while (myReader.Read())
{
DataQualityTextBox.Text += myReader[0].ToString();
LoadFailureTextBox.Text += myReader[1].ToString();
LoadPerformanceTextBox.Text += myReader[2].ToString();
}
or
while (myReader.Read())
{
DataQualityTextBox.AppendText(myReader[0].ToString());
LoadFailureTextBox.AppendText(myReader[1].ToString());
LoadPerformanceTextBox.AppendText( myReader[2].ToString());
}
It will Also be a good idea to use parameters in your query instead of concatenating strings
I have searched around and it seem's the only answer I can get is to do with LINQ, which I don't have available on my visual stuido 2005.
I am building a program that reads files and imports them into a database, the way it's set up at the moment, it reads the very latest date it finds.
I want to read the earliest file first.
Is there any way around this?
Here is my code
private string mDirectory; // this will hold the directory path you are working on
private string[] mFiles; // this will hold all files in the selected directory
private void ReadData()
{
this.toolStripStatusLabel1.Text = "Preparing To Read Data";
this.Refresh();
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};;persist security info=false;Extended Properties=dBase IV", mDirectory);
this.richTextBox1.Text = connectionString;
try
{
foreach (string file in mFiles)
{
mDirectory = #"C:\USERS\DESKTOP\Test Pressure\";
mFiles = System.IO.Directory.GetFiles(mDirectory, "*(WIDE).DBF");
DateTime dt = File.GetLastWriteTime(file);
string newdate = dt.ToString("yyyy-MM-dd HH:mm:ss");
DateTime DBTIME = new DateTime(2014, 01, 01, 00, 00, 00);
string date = String.Format("{0:yyyy-MM-dd HH:mm:ss}", DBTIME);
//this.richTextBox1.Text = date;
if (dt > DBTIME)
{
StringBuilder sb = new StringBuilder(300);
int n = GetShortPathName(file, sb, 300);
if (n == 0) // check for errors
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
else
{ }
string filenameWithoutPath1 = System.IO.Path.GetFileName(sb.ToString());
string queryString = string.Format("SELECT * FROM [" + "{0}]", filenameWithoutPath1);
this.richTextBox1.Text = queryString;
string where = " WHERE BAR > 20.0";
string myquery = queryString + where;
// this.richTextBox1.Text = myquery;
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(myquery, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
if (reader.IsDBNull(1))
{
this.richTextBox1.Text = "Null";
}
else
{
string Query = "REPLACE INTO hp42mis.hydrodata (FILEMOD, DOEYMD,TIMEHMS,DATETIMEM,MARKER,CONTRACT_CODE,STS_00" +
",PIPE,PIPE_NO,STS_01,MAX_PRESB,STS_02,MIN_PRESSB,STS_03,TESTP_BAR,STS_04,five,STS_05,six,STS_06,seven,STS_07," +
"eight,STS_08,nine,STS_09) values ('" + newdate.ToString() + "',";
Query += "'" + Convert.ToDateTime(reader["Date"]).ToString("yyyy-MM-dd") + "'";
Query += ",'" + reader.GetValue(1).ToString() + "'";
Query += ",'" + Convert.ToDateTime(reader["Date"]).ToString("yyyy-MM-dd") + " " + reader.GetValue(1).ToString() + "'";
Query += ",'" + reader.GetValue(2).ToString() + "'";
Query += ",'" + reader.GetValue(3).ToString() + "'";
Query += ",'" + reader.GetValue(4).ToString() + "'";
Query += ",'" + reader.GetValue(5).ToString() + "'";
Query += ",'" + reader.GetValue(3).ToString() + "" + reader.GetValue(5).ToString() + "'";
Query += ",'" + reader.GetValue(6).ToString() + "'";
Query += ",'" + reader.GetValue(7).ToString() + "'";
Query += ",'" + reader.GetValue(8).ToString() + "'";
Query += ",'" + reader.GetValue(9).ToString() + "'";
Query += ",'" + reader.GetValue(10).ToString() + "'";
Query += ",'" + reader.GetValue(11).ToString() + "'";
Query += ",'" + reader.GetValue(12).ToString() + "'";
Query += ",'" + reader.GetValue(13).ToString() + "'";
Query += ",'" + reader.GetValue(14).ToString() + "'";
Query += ",'" + reader.GetValue(15).ToString() + "'";
Query += ",'" + reader.GetValue(16).ToString() + "'";
Query += ",'" + reader.GetValue(17).ToString() + "'";
Query += ",'" + reader.GetValue(18).ToString() + "'";
Query += ",'" + reader.GetValue(19).ToString() + "'";
Query += ",'" + reader.GetValue(20).ToString() + "'";
Query += ",'" + reader.GetValue(21).ToString() + "'";
Query += ",'" + reader.GetValue(22).ToString() + "'";
Query += ")";
MySqlCommand cmd = new MySqlCommand(Query, conne);
this.richTextBox1.Text = Query;
this.Refresh();
int res = 0;
try
{
res = cmd.ExecuteNonQuery();
}
catch (MySqlException Myex)
{
MessageBox.Show(Myex.Message);
}
rowcounter++;
this.rowcount.Text = rowcounter.ToString();
this.Refresh();
conne.Dispose();
conne.Close();
}
}
reader.Close();
connection.Close();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I found an easier way how to sort the array of files...
mFiles = System.IO.Directory.GetFiles(mDirectory, "*(WIDE).DBF");
Array.Sort(mFiles);
If you want to walk over your mFiles array based on each file's last write time, see Sort List using string without Linq:
private IList<string> GetOrderedFiles(string[] files)
{
var fileList = new List<string>(files);
Comparison<string> compare = delegate(string file1, string file2)
{
DateTime file1Time = File.GetLastWriteTime(file1);
DateTime file2Time = File.GetLastWriteTime(file2);
return file1Time.CompareTo(file2Time);
};
fileList.Sort(compare);
return fileList;
}
Usage:
var sortedFiles = GetOrderedFiles(mFiles);
foreach (string file in sortedFiles)
{
}
As others have said, that code needs reformatting and probably isn't even correct (e.g. you're setting mFiles within a loop iterating through mFiles).
However, maybe this will help?
Sorting Directory.GetFiles()
The key is using FileInfo items rather than just GetFiles().
You can do this :
public class ReverseComparer : IComparer<FileSystemInfo>
{
public int Compare(FileSystemInfo x, FileSystemInfo y)
{
return x.CreationTime.CompareTo(y);
}
}
DirectoryInfo di = new DirectoryInfo("C:\\...");
FileSystemInfo[] files = di.GetFileSystemInfos();
Array.Sort(files, new ReverseComparer());
protected void save_Click(object sender, EventArgs e)
{
OleDbConnection conn = null;
try
{
string connString = "Provider=OraOLEDB.Oracle;Data Source=127.0.0.1;User ID=SYSTEM;Password=SYSTEM;Unicode=True";
conn = new OleDbConnection(connString);
conn.Open();
string strQuery = "update login set fname ='" + TextBox4.Text + "' and lname='" + TextBox5.Text + "' and place='" + TextBox6.Text + "' and dob='" + TextBox7.Text + "' where uname='" + Label1.Text + "'";
OleDbCommand obCmd = new OleDbCommand(strQuery, conn);
OleDbDataReader obReader = obCmd.ExecuteReader();
}
catch (OleDbException ex)
{
Response.Write("Send failure: " + ex.ToString());
}
catch (Exception exe)
{
Response.Write(exe.Message);
}
finally
{
if (null != conn)
{
conn.Close();
}
}
}
the update query syntax is wrong.
You cannot use AND while setting multiple columns. It should be seperated by comma.
string strQuery = "update login set fname ='" + TextBox4.Text + "',lname='" +
TextBox5.Text + "',place='" + TextBox6.Text + "',dob='" + TextBox7.Text +
"' where uname='" + Label1.Text + "'";
The values must be separated with a comma and there is one big problem in this code. Imagine what happens when someone puts the following into TextBox4:
' where 1 = 1 --
The result would be a table where all entries would be overwritten
update login set fname ='' where 1 = 1 --', lname='bla' ....
Use DbParameter instead:
string strQuery = #"
update LOGIN set
FNAME = :FNAME,
LNAME = :LNAME,
PLACE = :PLACE,
DOB = :DOB
where
UNAME = :UNAME
";
OleDbCommand obCmd = new OleDbCommand(strQuery, conn);
obCmd.Parameters.AddWithValue(":FNAME", TextBox4.Text);
obCmd.Parameters.AddWithValue(":LNAME", TextBox5.Text);
obCmd.Parameters.AddWithValue(":PLACE", TextBox6.Text);
obCmd.Parameters.AddWithValue(":DOB", TextBox7.Text);
obCmd.Parameters.AddWithValue(":UNAME", Label1.Text);
OleDbDataReader obReader = obCmd.ExecuteReader();
For Oracle the : should indicate a parameter (it's a # for Sybase and MS SQL). I named all params like the target columns, but you can use other names of course.