i have used a checkbox list in my project .am storing all the checked items values in arraylist using code below
ArrayList services= new ArrayList();
for (int i = 0; i < chkservices.Items.Count; i++)
{
if (chkservices.Items[i].Selected == true)
{
services.Add(chkservices.Items[i].Text+',');
}
}
now the problem is when i insert data in to database instead of data in the arraylist it gets inserted as 'System.Collections.ArrayList' how can i insert all values into database in a single insert statement?
EDIT
inserting into database
con.Open();
SqlCommand cmd = new SqlCommand("insert into XXX(First_Name,Last_Name,ServicesProvided) values ('" + txtfrstname.Text + "','" + txtlastname.Text + "','" + services + "')", con);
cmd.ExecuteNonQuery();
con.Close();
or could anyone provide me a alternative for arraylist..i need to save checked items from checkboxlist and save it in database
it should be saved in database as
First_Name Last_name ServicesProvided
user1firstname user1lastname selectedvalue1,
selectedvalue2,selectedvalue3
Why not to concatenate your data using the following code:
var mydata = String.Join(',', chkservices.Items
.Where( a => a.Selected).Select( b => b.Text));
So you can add your data as a string.
EDIT:
It is a very bad habit of concatenating strings to make a query! Apart from many side effects like in your case here it is a great security breach. Try the parameterized query instead:
SqlCommand cmd = new SqlCommand(
#"insert into XXX(First_Name,Last_Name,ServicesProvided) values
(#First_Name,#Last_Name,#ServicesProvided")", con);
cmd.Parameters.AddWithValue("#ServicesProvided", mydata);
cmd.Parameters.AddWithValue("#First_Name", frstname.Text);
cmd.Parameters.AddWithValue("#Last_Name", txtlastname.Text);
cmd.ExecuteNonQuery();
mydata is the variable from my first example.
You need to get the values of the array list and send them one by one
or create a stored procedure where you send all the values to using Alexanders Galkins example (or use the a Aggregate method). Then use the split function to split up the string and insert all the record
Using INSERT INTO statement you can insert only one row at a time unless you're using sub query to select data from other table.
As you don't have the data in the database, your only option is iterate over the array and insert each value as new row.
Don't use ArrayList, you have generic list for what you need:
List<string> services = new List<string>();
for (int i = 0; i < chkservices.Items.Count; i++)
{
if (chkservices.Items[i].Selected == true)
{
services.Add(chkservices.Items[i].Text);
}
}
//...connection stuff....
strSQL = "INSERT INTO MyTable (MyField) VALUES (#val)"
using (SqlCommand command = new SqlCommand(strSQL, connection))
{
command.Parameters.AddWithValue("#val", "");
foreach (string service in services)
{
command.Parameters["#val"].Value = service;
command.ExecuteNonQuery();
}
}
How many checkbox do you have? If you just have a little checkbox, so I suggest you transform each state of them into bit mask which represent a number, then store it to database.
long bitMask = 0; // All uncheck
for (int i = 0; i < chkServices.Items.Count; ++i) {
if (chkServices.Items[i].Checked) {
bitMask |= (1 << i);
}
}
// Store bitMask to Database
In later, you can get state via bitMask again when needed.
Related
In my current application I have a snippet of code that allows me to select a single row in a data grid view and store all the columns information into a variable to do with what I want. I use this primarily to send information from one SQL database table to another. It's great for only sending specified cells within a row.
Here is how I do a single row:
string ID = dataGridView1.SelectedRows[0].Cells[0].Value + string.Empty;
string itemOne= dataGridView1.SelectedRows[0].Cells[1].Value + string.Empty;
string itemTwo= dataGridView1.SelectedRows[0].Cells[2].Value + string.Empty;
string itemThree= dataGridView1.SelectedRows[0].Cells[3].Value + string.Empty;
var vItemOne = itemOne;
var vItemTwo= itemTwo;
var vItemThree= itemThree;
// ETC..
However, I now want to be able to select Multiple Rows and only insert specified columns within those rows to a SQL database.
I've tried modifying the above code to work... obviously it doesn't work.
I believe I need a loop, I haven't really used loops much so I'm not sure how to make it loop, skip certain columns, then insert into database.
This is what I am currently attempting, however I seem to be messing up somewhere.
using (SqlConnection con = new SqlConnection(Connection.MTRDataBaseConn))
{
for (int i = 0; i < dataGridView1.SelectedRows.Count; i++)
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "INSERT INTO dbo.[" + txtJobName.Text + "] ([Item One], [Item Two], [Item Three]) VALUES(#ItemOne,#ItemTwo,#ItemThree)";
cmd.Connection = con;
string strItemOne = this.dataGridView1.SelectedRows[i].Cells[1].Value + string.Empty;
string strItemTwo = this.dataGridView1.SelectedRows[i].Cells[2].Value + string.Empty;
string strItemThree = this.dataGridView1.SelectedRows[i].Cells[3].Value + string.Empty;
//Parameters
cmd.Parameters.AddWithValue("#ItemOne", strItemOne);
cmd.Parameters.AddWithValue("#ItemTwo", strItemTwo);
cmd.Parameters.AddWithValue("#ItemThree", strItemThree);
//execute
cmd.ExecuteNonQuery();
//close connection
con.Close();
}
}
...
While Debugging My dataGridView.SelectedRows.Count; i++ doesn't seem to be increasing and is staying at 0... I'm receiving the error when I try to return the selected row to a string. Shouldn't my selected rows still return a value?
I'm under the assumption my loop is wrong.
Can anyone help me with my issue?
Simply have to use a for each statement
string itemOne= dataGridView1.SelectedRows[0].Cells[1].Value + string.Empty;
string itemTwo= dataGridView1.SelectedRows[0].Cells[2].Value + string.Empty;
string itemThree= dataGridView1.SelectedRows[0].Cells[3].Value + string.Empty;
var vItemOne = itemOne;
var vItemTwo= itemTwo;
var vItemThree= itemThree;
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
//Insert Query Here
}
My code for processing an insert query:
for (int i = 0; i <= ListView1.Items.Count - 1; i++)
{
con = new OleDbConnection(cn);
string cd = "INSERT INTO ProductSold(ID, invoiceID, description, rate, ps_quantity, ps_mrp, free, totalamount) VALUES (#ID,'" + txtInvoiceNo.Text + "',#description,#Rate,#Quantity,#MRP,#free,#Totalamount)";
cmd = new OleDbCommand(cd);
cmd.Connection = con;
cmd.Parameters.AddWithValue("InvoiceNo", txtInvoiceNo.Text);
cmd.Parameters.AddWithValue("ID", ListView1.Items[i].SubItems[0].Text);
cmd.Parameters.AddWithValue("description", ListView1.Items[i].SubItems[1].Text);
cmd.Parameters.AddWithValue("Rate", ListView1.Items[i].SubItems[5].Text);
cmd.Parameters.AddWithValue("Quantity", ListView1.Items[i].SubItems[2].Text);
cmd.Parameters.AddWithValue("MRP", ListView1.Items[i].SubItems[3].Text);
cmd.Parameters.AddWithValue("free", ListView1.Items[i].SubItems[4].Text);
cmd.Parameters.AddWithValue("Totalamount", ListView1.Items[i].SubItems[6].Text);
con.Open();
cmd.ExecuteNonQuery(); `enter code here`/*error*/
con.Close();
}
Error: insert into table error on data mismatch on criteria?
You are probably messing up with the parameter value types, for some RDBMS they need to be of same type as the field they are referring to (your ID field may be an integer field, but you are using a string value from a TextBox for the ID parameter.
BTW: You are opening a new connection for each entry in your list view. Move the con declaration / assignment out of the loop.
I have to insert 90Mb of data into MySql Tables and I'm using INSERT IGNORE command to avoid the exception of duplicate key. The performance are 8 records a second but it seems very slow. Could I fast it up?
p.s. I'm inserting record per record since i read data from an sql compact database
using (SqlCeConnection sqlConnection = new SqlCeConnection(connectionstrCe))
{
sqlConnection.Open();
SqlCeCommand cmdCe = sqlConnection.CreateCommand();
{
{
mySQLConnection.Open();
foreach (KeyValuePair<string, List<string>> t in tablesCeNames) //reading the tables property from the dictionary - column names and datatypes
{
string tableData = t.Key;
List<string> columnData = t.Value;
//get the values from the table I want to transfer the data
cmdText = "SELECT * FROM " + tableData;
//compose the mysql command
cmdCe.CommandText = cmdText;
SqlCeDataReader dataReader = cmdCe.ExecuteReader(); //read
//InsertTable is a method that get the datareader and convert all the data from this table in a list array with the values to insert
inputValues = InsertTables(dataReader);
MySql.Data.MySqlClient.MySqlTransaction transakcija;
transakcija = mySQLConnection.BeginTransaction();
worker.ReportProgress(4, inputValues.Count);
foreach (string val in inputValues)//foreach row of values of the data table
{
cmdSqlText = "INSERT IGNORE INTO " + tableData + "("; //compose the command for sql
foreach (string cName in columnData) //forach column in a table
{
string[] data = cName.Split(' ');
if (!data[0].ToString().Equals("Id"))
{
cmdSqlText += data[0].ToString() + ","; //write the column names of the values that will be inserted
}
}
cmdSqlText = cmdSqlText.TrimEnd(',');
cmdSqlText += ") VALUES (";
//val contains the values of this current record that i want to insert
cmdSqlText += val; //final command with insert ignore and the values of one record
if (!val.Equals(""))
{
try
{
new MySql.Data.MySqlClient.MySqlCommand(cmdSqlText, mySQLConnection, transakcija).ExecuteNonQuery(); //execute insert on sql database
WriteToTxt("uspjeĆĄno upisano u mysql" + t.Key);
}
catch (MySql.Data.MySqlClient.MySqlException sqlEx)
{
}
}
}
if (TablicaSveOK)
{
transakcija.Commit();
}
else
{
transakcija.Rollback();
}
}
}
if (mySQLConnection.State != System.Data.ConnectionState.Closed)
{
mySQLConnection.Close();
}
}
What about getting the data from Sql to a file and use LOAD DATA?
http://dev.mysql.com/doc/refman/5.0/es/load-data.html
Rather then sending multiple calls you can send one call to insert all records. Insert it like this
insert into your table(col1, col2)
SELECT 'Name1', 'Location1'
UNION ALL
SELECT 'Name2', 'Location2'
UNION ALL
SELECT 'Name3', 'Location3'
A part from this it is possible that your code is the bottle neck rather than the insert statement. So i would recommend you to first check where the problem lies and then go for the solution.
The latest MySql.Connector has a class called MySqlBulkLoader that could be used to call the LOAD DATA syntax of MySql in a more NET oriented way. The class requires a comma separated value file to load from and is extremely fast.
So your job would be to read all of your Sql Compact records in a datatable and then, using a streamwriter or a specialized CSV Writer write down everything in a file.
Then the code to load your data in a MySql table is simple like this
string connStr = "server=localhost;user=root;database=........";
using(MySqlConnection conn = new MySqlConnection(connStr))
{
MySqlBulkLoader bl = new MySqlBulkLoader(conn);
bl.TableName = "yourdestinationtable";
bl.FieldTerminator = "\t";
bl.LineTerminator = "\n";
bl.FileName = "path_to_your_comma_separated_value_file";
try
{
conn.Open();
int count = bl.Load();
}
}
I'm trying to take items from a checkboxlist and add them to a SQL Server table. I assumed it would be as easy as looping through each item and then inserting it into the table, but I'm getting an unhandled exception with the following code:
using (SqlConnection connection = new SqlConnection(connectionString))
{
for (int i = 0; i <= UPCList.Items.Count; i++)
{
string finalSubmit =
"INSERT INTO Boxes (BoxNumber)"
+ "VALUES #selected";
SqlCommand command = new SqlCommand(finalSubmit, connection);
command.Parameters.AddWithValue("#selected", i);
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
}
}
Edit: one of the suggestions below worked, but it's putting in the ID of the item rather than the value of the list item itself. How can I insert the value for each item in the list into the SQL table?
Put the VALUES in paranthesis:
"INSERT INTO Boxes (BoxNumber) VALUES (#selected)";
Also, i assume you have to replace
for (int i = 0; i <= UPCList.Items.Count; i++)
with
for (int i = 0; i < UPCList.Items.Count; i++)
and you might want to insert the item's text instead of the index:
command.Parameters.AddWithValue("#selected", listBox.Items[i].ToString());
I'm creating an application in Visual Studio 2010 C# and MySQL where the user can add, edit, view an employee. I already done with adding and viewing part. However I'm little confused in editing. I have this listView in my form where it displays all the employee added to the database. What I want is that whenever the user will select an employee and click edit button I want the values saved in the database to show in the corresponding textboxes below the listView. Can someone give me any idea how to do this? Please
Screenshot:
Code for listView:
private void getEmployee()
{
listViewEmployee.Items.Clear();
string cmd = "select employee_number, employee_lastname, employee_firstname, employee_middlename, employee_position, employee_datehired from employee";
DBConn db = new DBConn();
DataTable tbl = db.retrieveRecord(cmd);
foreach (DataRow row in tbl.Rows)
{
ListViewItem lv = new ListViewItem(row[0].ToString());
lv.SubItems.Add(row[1].ToString() + ", " + row[2].ToString() + " " + row[3].ToString());
lv.SubItems.Add(row[4].ToString());
lv.SubItems.Add(row[5].ToString());
listViewEmployee.Items.Add(lv);
}
}
private void textBoxSearchEmployee_TextChanged(object sender, EventArgs e)
{
string cmd = "SELECT employee_number, employee_lastname, employee_firstname, employee_middlename, employee_position, employee_datehired FROM employee where employee_lastname Like '" + textBoxSearchEmployee.Text + "%'";
listViewEmployee.Items.Clear();
DBConn db = new DBConn();
DataTable tbl = db.retrieveRecord(cmd);
foreach (DataRow row in tbl.Rows)
{
ListViewItem lv = new ListViewItem(row[0].ToString());
lv.SubItems.Add(row[1].ToString() + ", " + row[2].ToString() + " " + row[3].ToString());
lv.SubItems.Add(row[4].ToString());
lv.SubItems.Add(row[5].ToString());
listViewEmployee.Items.Add(lv);
}
}
It seems to me you are able to populate the listView only.
A few pointers:
1) The way you're writing your SQL statement now is prone to SQL Injection. Use parameters in your SQL commands instead of directly concatenating the variables to your query. See this question for an example on how to do it.
2) Depending on where your other relevant data is located (i.e. if your database is normalized), you might have to do a join in your query.
string sqlQuery = "SELECT * FROM employee
JOIN other_employee_data_table on other_employee_data_table.employeeID = employee.ID
WHERE employee.employee_lastname LIKE #employee_lastname +'%'"
But if your employee table contains all the data, then no need to do a join. Just get all the relevant information from that table.
3) Once you got all the information you need, it's just a matter of reading those data and assigning them to their respective fields.
Pseudo Code:
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
MySqlCommand command = connection.CreateCommand();
command.CommandText = sqlQuery;
command.CommandType = System.Data.CommandType.Text;
// add parameters in this line
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// iterate in each row
for (int i = 0; i < reader.FieldCount; i++)
{
// iterate each column using reader.GetValue(i)
}
}
}
}
When the user presses the "edit" button...
Retrieve the selected employee
Use a SELECT to get the selected employee's information
Populate the text boxes with the selected employee's information
For example,
String employee = listViewEmployee.Text;
String cmd = "SELECT * FROM employee WHERE employee_lastname='" + employee + "'";
DBConn db = new DBConn();
DataTable tbl = db.retrieveRecord(cmd);
txtLastName.Text = tbl.Rows[0][0];
// ...
// etc.
Note: It's a bad idea to concatenate values into a SQL query because if the values are malicious, a different query could be executed. For example, if employee had the value of x' OR '1'='1; DROP TABLE employee; -- or something along those lines, then the employee table could be dropped. The way around this is using Stored Procedures or parameterized queries.