in C# project , I have made a datagridview in my form that has some columns.column[0]& column[1] names are fix (day and date) and the other column names are variable and will change by user.these columns have time period thatsis shown with starting and finishing time.
such as from 6 am to 14 pm is shown as 6_14 as columns name.we have a listbox that has variable number of items(counter "i").
///sqlite doesn't accept columns name that start and finish with Numbers.I added word "f" to start and end of each
///column name
string data_str = "";
string data_str2="";
for (int i = 0; i < listBox1.Items.Count;i++ )
{
string temp = "f"+ listBox1.Items[i].ToString()+"f";
data_str = data_str + temp +",";
string temp2 = "#"+listBox1.Items[i].ToString()+",";
data_str2=data_str2+temp2;
}
data_str=data_str.TrimEnd(',');
data_str2=data_str2.TrimEnd(',');
in first step,I made two columns "day" & "date" in data table in my database and imported my data to it successfully.(It works)
string Q_insert = "insert into " + table_name + " (day,date) values (#day,#date)";
SQLiteConnection connect = new SQLiteConnection(connection_string);
SQLiteCommand insert_cmd = new SQLiteCommand(Q_insert, connect);
foreach (DataGridViewRow row in shift_datagrid.Rows)
{
insert_cmd.Parameters.AddWithValue("#day", row.Cells[0].Value.ToString().Trim());
insert_cmd.Parameters.AddWithValue("#date", row.Cells[1].Value.ToString().Trim());
connect.Open();
insert_cmd.ExecuteNonQuery();
connect.Close();
}
in second step,I need to import user data from datagridview to data table but the error takes place.(it doesn't work)
int col_cnt = listBox1.Items.Count;
Q_insert = "insert into " + table_name + " (" + data_str + ") values (" + data_str2 + ")";
connect = new SQLiteConnection(connection_string);
insert_cmd = new SQLiteCommand(Q_insert, connect);
foreach (DataGridViewRow row in shift_datagrid.Rows)
{
string temp1 = "";
for (int i = 0; i < col_cnt; i++)
{
temp1 = "\"#" + listBox1.Items[i].ToString() +"\"";
insert_cmd.Parameters.AddWithValue(temp1, row.Cells[i + 2].Value.ToString().Trim());
}
connect.Open();
insert_cmd.ExecuteNonQuery();
connect.Close();
}
unfortunately, this error occurs:
unknown Error : Insufficient parameters supplied to the command
I googled this error and checked solution ways for same problems but they were not useful for my problem and they couldn't help me anyway.
this is the example of output command strings that insert to data to database (two steps):
1. Insert into [table_name] (day,date) values (#day,#date) -------------->(it works)
2. Insert into [table_name] (f6_14f,f14_22f,f22_6f) values (#6_14,#14_22,#22_6) ------->(it doesn't work)
please help me
thanks
The following may be causing the error:
temp1 = "\"#" + listBox1.Items[i].ToString() +"\"";
insert_cmd.Parameters.AddWithValue(temp1, row.Cells[i + 2].Value.ToString().Trim());
Syntax requires that you don't construct the # as part of the variable value.# is not data. Use it as part of the variable name as you did before like this:
insert_cmd.Parameters.AddWithValue("#Col1",listBox1.Items[i+2].Value.ToString().Trim());
Where #Col1 is a column name of your table.
I don't think you can build the parameter name in a for loop, if so, you have to list the insert statements with each column name parameter prefixed with # as in the above example/code.
Related
I want to create excel file by oledb, and my code is
int index = 0;
foreach (DataColumn col in dt.Columns)
{
datatype[index] = $"[{col.ColumnName}]" + " String";
index++;
}
string query = string.Join(",", datatype);
cmd.CommandText = $"CREATE TABLE [{sheetName}] ({query});";
cmd.ExecuteNonQuery();
and I have column name like Product material[EN]
I used break point and check my command string
CREATE TABLE [products]
(
[another Title] String,
[Use of product[EN]] String,
[Product material[EN]] String,
[another Title] String
);
I've tried
Product material[EN]
Product material[[EN]]]
[Product material[EN]]
'[Product material[EN]]'
Product material[[]EN]
['Product material[EN]']
let all columns in query without bracket
CREATE TABLE [products]
(
another Title String,
Use of product[EN] String,
Product material[EN] String,
another Title String
);
let all value in query without bracket
CREATE TABLE [products]
(
another Title String,
Use of product EN String,
Product material EN String,
another Title String
);
but the above syntax all received Syntax error in field definition.
If using parameter and modify the code
cmd.CommandText = $"CREATE TABLE [{sheetName}] (";
for (int i = 0; i < dt.Columns.Count; i++)
{
cmd.CommandText = cmd.CommandText + "[#var" + i.ToString() + "] String,";
cmd.Parameters.AddWithValue("#var" + i.ToString(), datatype[i]);
}
cmd.CommandText = cmd.CommandText.Remove(cmd.CommandText.Length - 1, 1) + ");";
or change
cmd.Parameters.AddWithValue("#var" + i.ToString(), datatype[i]);
to
cmd.Parameters.Add(new OleDbParameter("#var" + i.ToString(), datatype[i]));
and get the command string
CREATE TABLE [products]
(
[#var0] String,
...
[#varN] String
);
will get a successful excel file but with #varxx column names
change to Product material(EN) is work but I need to use bracket []
how do I add bracket into column name use oledb ?
Basically I have this list of students (alunos) and I want to double click in one of the students and I want it to show a MessageBox containing:
Student No.: {student no. from the selected student here}
Name: {student name from the selected student here}
etc...
Here's the code I have:
void lstAlunos_MouseDoubleClick(object sender, MouseEventArgs e)
{
string query = "SELECT * FROM (" +
"SELECT" +
"ROW_NUMBER() AS rownumber," +
"columns" +
"FROM Alunos" +
") AS foo" +
"WHERE rownumber = " + lstAlunos.SelectedIndex;
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (var reader = command.ExecuteReader())
{
connection.Open();
reader.Read();
string numAluno = reader.GetString(0);
string nomeAluno = reader.GetString(1);
string apelidoAluno = reader.GetString(2);
string contactoAluno = reader.GetString(3);
string emailAluno = reader.GetString(4);
}
int index = this.lstAlunos.IndexFromPoint(e.Location);
if (index != System.Windows.Forms.ListBox.NoMatches)
{
MessageBox.Show("Nome: " + nomeAluno);
}
}
Add spaces to the ends of the strings you're concatenating. Right now this segment:
"columns" +
"FROM" +
will give you "columnsFROM" which is obviously bad SQL.
Some other suggestions:
Add error handling. The exception you got from this should give you a clue as to where the problem is.
Use parameters instead of concatenating string values. It will protect you from SQL Injection attacks and take care of formatting for you.
Don't use ROW_NUMBER() without some sore of explicit order. THere's no guarantee that you'll get the rows in the same order that they were saved in previously. Use an ID column instead.
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
}
I want to pass a column2 to a function and update column3 with output of function. I have made func function to calculae the output. When i run the program
it only takes last value as input and outputs all columns with same value.What am i doing wrong?
sqlite1 = new SQLiteConnection("DataSource = D:/datab.db;version=3");
sqlite1.Open();
string query1 = "select * from ramrotable";
SQLiteCommand cmd = new SQLiteCommand(query1, sqlite1);
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("Age::" + reader["age"]);
//int data = Convert.ToInt16(reader["age"]);
string tempquery = string.Format("UPDATE ramrotable SET num =
func({0})",reader["age"]);
cmd = new SQLiteCommand(tempquery, sqlite1);
cmd.ExecuteNonQuery();
}
string query4 = "select * from ramrotable";
cmd = new SQLiteCommand(query4, sqlite1);
reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("Name: " + reader["name"] + " Age: " +
reader["age"] + " Num: " + reader["num"]);
}
You need to use a WHERE clause to tell SQLite which record to update exactly. Otherwise all records will be affected. Please make sure that in the WHERE clause you use a column (or a combination of columns) the identify the record uniquely!
Ideally, every record will have an ID column that contains a unique value and is the Primary Key.
I understand from the comments to the question that you actually want to update the value of the num column depending on a value from the age column of the same record, for all the records in the table.
To do this, you neither need to fetch all the records nor do you need to loop. All you need to do is invoke the following statement:
UPDATE ramrotable SET num = func(age)
This takes the value of the age column, passes it to func and sets the result as the new value for the num column for each record in the table.
So all of what you've written above can be shortened to
sqlite1 = new SQLiteConnection("DataSource = D:/datab.db;version=3");
sqlite1.Open();
cmd = new SQLiteCommand("UPDATE ramrotable SET num = func(age)", sqlite1);
cmd.ExecuteNonQuery();
When using
string tempquery = string.Format("UPDATE ramrotable SET num =
func({0})",reader["age"]);
you are updating each row with current func(age) value.
For updating each row with exact value you should use single command outside of the while loop:
string updatequery = "UPDATE ramrotable SET num = func(age)";
cmd = new SQLiteCommand(updatequery, sqlite1);
cmd.ExecuteNonQuery();
The problem:
I'm trying to insert a date time into an access database using the Oledb interface in C#.
Hacking solution: Generate my on insert string without using command.Properties
I can insert text into the database with no problem, but when trying datetime, I end up with this error: System.Data.OleDb.OleDbException {"Data type mismatch in criteria expression."}
There are several posts similar to this but alas with no working solution.
Here is my code:
void TransferData()
{
string instCmd = Get_InsertCommand(0); // hard coded table 0 for testing
Fill_ProductTable_ToInsert();
con.Open();
// It would be nice not to have to separate the date indexes
int[] textIndex = { 0, 1, 2, 3, 4, 7 };
int[] dateIndex = { 5, 6 };
try
{
foreach (DataRow row in DataToStore.Tables[0].Rows)
{
OleDbCommand command = new OleDbCommand();
command.Connection = con;
command.CommandText = instCmd;
foreach(int j in textIndex)
command.Parameters.AddWithValue("#" + j, row[j]);
foreach (int j in dateIndex)
{
// TESTING CODE
///////////////////////////////////////////////////////////////////////////
string input = "#\'" +DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") +"\'#";
command.Parameters.AddWithValue("#" + j, input.ToString());
Program.WriteLine(input.ToString());
///////////////////////////////////////////////////////////////////////////
}
command.ExecuteNonQuery();
}
}
finally
{
con.Close();
}
}
string Get_InsertCommand(int i)
{
string sqlIns = "INSERT INTO " + DataToStore.Tables[0].TableName + " (";
string temp = "VALUES (";
for (int j = 0; j < expected_header[i].Length - 1; j++)
{
sqlIns += expected_header[i][j] + ", ";
temp += "#" + j + ", ";
}
int lastIndex = expected_header[i].Length -1;
sqlIns += expected_header[i][lastIndex] + ") ";
temp += "#" + lastIndex + ")";
sqlIns += temp;
return sqlIns;
}
Inside the area labeled testing code, I have tried every permutation of date time I could think of.
I tried every format with # and '
I tried these formats: yyyy-MM-dd, yyyyMMdd, yyyy\MM\dd, yyyy/MM/dd
I also tried ToOADate()
And ToString(), ToShortDateString()
I also tried setting the database to accept ANSI-92 Sql
I'm running out of ideas.
Note: This code is set up to deal with multiple tables from multiple databases, mind the loops...
Use parameters properly, and don't worry about the format of the datetime value that you concatenate in your query.
I don't understand why you want to convert the datetime value to a string value ?
DateTime theDate = new DateTime(2012,10,16);
var cmd = new OleDbCommand();
cmd.CommandText = "INSERT INTO sometable (column) VALUES (#p_bar)";
cmd.Parameters.Add ("#p_bar", OleDbType.DateTime).Value = theDate;
I was able to solve this issue by not using command properties. I generated my own sql input and set it to cmd.commandText. The text input for datetime to a data base is #yyyy-MM-dd#