How to insert a value starting with "#" in a MySQL table? - c#

I am trying to insert a large list of data in a MySQL table.
Due to performance issues, I'am filling a List<string> and with this list I generate my command string to do an unique insert with all my rows.
Here is my code:
StringBuilder cmdText = new StringBuilder("INSERT INTO my_Table (ColumnA, ColumnB) VALUES ");
List<string> aux = new List<string>();
using (MySqlConnection conn = new MySqlConnection(connString))
{
foreach (DataRow row in dataTable.Rows)
{
aux.Add(string.Format("('{0}','{1}')", row[0].ToString(), row[1].ToSTring()));
}
cmdText.Append(string.Join(",", aux));
cmdText.Append(";");
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(cmdText.ToString(), conn))
{
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 0;
cmd.ExecuteNonQuery();
};
This way, the result of my cmdText, finally is something like this:
INSERT INTO my_Table (ColumnA, ColumnB) VALUES ('Value1','Value2') ('Value3','Value4') ...;
with aproximately 500k rows in teh same insert.
One or more of this rows can contain values starting with '#'
I'm not using parameters ('#parameter'), but when I execute my application,
I get an error like this:
Fatal error encountered during command execution.
"Parameter '#GMAIL.COM' must be defined."
#gmail.com is a value, not a parameter. But it still been interpreted like a #parameter.
Anyone knows the way to indicate that this is not a param but a value??

Related

C# sqlite copy a datatable to another datatable in faster way

Can anyone share how to coding copy a datatable to another datatable in faster way for C# sqlite? Thanks.
And also need to change column name also. i tried to manually select and update, but encountered error. Appreciate for your sharing. Thanks.
or how can i amend the column header when display datatable in datagridview? Thanks.
dbConnect = new SQLiteConnection("Data Source=school.db;Version=3;");
dbConnect.Open();
cmd4 = new SQLiteCommand();
cmd4 = dbConnect.CreateCommand();
cmd4.CommandText = "DELETE FROM GroupEven";
cmd4.ExecuteNonQuery();
cmd4.CommandText = "SELECT Day, Day_ID, Standard, Timeslot1_TeacherName, Timeslot1_Subject, Timeslot2_TeacherName, Timeslot2_Subject, Timeslot3_TeacherName, Timeslot3_Subject, Timeslot4_TeacherName, Timeslot4_Subject, Timeslot5_TeacherName, Timeslot5_Subject, Timeslot6, Timeslot7_TeacherName, Timeslot7_Subject, Timeslot8_TeacherName, Timeslot8_Subject, Timeslot9_TeacherName, Timeslot9_Subject, Timeslot10_TeacherName, Timeslot10_Subject, Timeslot11_TeacherName, Timeslot11_Subject FROM TimetableFinal";
DataTable dt4 = new DataTable();
SQLiteDataAdapter da4 = new SQLiteDataAdapter(cmd4);
da4.Fill(dt4);
foreach (DataRow dr4 in dt4.Rows)
{
cmd4.CommandText = "INSERT INTO TimetableFinal2 (Day, Day_ID, Standard, 7:30am-8:00am, 7.30am-8.00am, 8:00am-8:30am, 8.00am-8.30am, 8:30am-9:00am, 8.30am-9.00am, 9:00am-9:30am, 9.00am-9.30am, 9:30am-10:00am, 9.30am-10.00am, 10:00am-10:20am, 10:20am-10:50am, 10.20am-10.50am, 10:50am-11:20am, 10.50am-11.20am, 11:20am-11:50am, 11.20am-11.50am, 11:50am-12:20pm, 11.50am-12.20pm, 12:20pm-12:50pm, 12.20pm-12.50pm) VALUES (#Day, #Day_ID, #Standard, #7:30am-8:00am, #7.30am-8.00am, #8:00am-8:30am, #8.00am-8.30am, #8:30am-9:00am, #8.30am-9.00am, #9:00am-9:30am, #9.00am-9.30am, #9:30am-10:00am, #9.30am-10.00am, #10:00am-10:20am, #10:20am-10:50am, #10.20am-10.50am, #10:50am-11:20am, #10.50am-11.20am, #11:20am-11:50am, #11.20am-11.50am, #11:50am-12:20pm, #11.50am-12.20pm, #12:20pm-12:50pm, #12.20pm-12.50pm)";
cmd4.Parameters.AddWithValue("#Day", dr4["Day"].ToString());
SQLite does support Joinings Insert statements, something like this.
INSERT INTO 'tablename' ('column1', 'column2')
VALUES
('data1', 'data2'),
('data3', 'data4'),
('data5', 'data6'),
('data7', 'data8');
See this.. http://www.sqlite.org/lang_insert.html
and then execute this in one go. Also, Make sure you do this in transactions and wrap around in using statements
using(var dbConnect = new SQLiteConnection("DataSource=school.db;Version=3;"))
{
dbConnect.Open();
using(var transaction = dbConnect.BeginTransaction())
{
string insertQuery = ...// your insert query
using (var cmd = dbConnect.CreateCommand())
{
cmd.CommandText = insertQuery;
foreach (DataRow dr4 in dt4.Rows)
{
cmd.Parameters.AddWithValue(...);
}
cmd.ExecuteNonQuery()
}
transaction.Commit();
}
}
Regarding your second part: How can i amend the column header when display datatable in datagridview,
thats totally separate, has nothing to do with Sqlite insertions.
After getting the data source you can do something like this
dataGridView1.Columns[i].HeaderText = "My New header";

Syntax error while trying to fetch data from MySql

So I am trying to fetch a value from the database, selecting the row using WHERE INT.
conn = new MySqlConnection(DBdetails.connStr);
conn.Open();
query = "SELECT * FROM tables WHERE table=#tafel";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("#tafel", tafel);
cmd.ExecuteNonQuery();
However it wont pass 'cmd.ExecuteNonQuery()', it throws a error saying the syntax isnt right like: "near table=1", "near table=2"
I tried fetching a other one in the same table that is a var char and it worked perfectly.
Don't really see what I am doing wrong. The 'table' column is a int and 'tafel' is a int to.
Thanks!
Put your field name table in backticks (table is a reserved word in MySQL) :
query = "SELECT * FROM `tables` WHERE `table` = #tafel";
As others said, table is a reserved word in MySQL. You need to use quote with it like
query = "SELECT * FROM tables WHERE `table` = #tafel";
However, the best solution is to change the name to a nonreserved word.
Also use using statement to dispose your MySqlConnection and MySqlCommand like;
using(MySqlConnection conn = new MySqlConnection(DBdetails.connStr))
using(MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM tables WHERE `table` = #tafel";
cmd.Parameters.AddWithValue("#tafel", tafel);
conn.Open();
cmd.ExecuteNonQuery();
}
By the way, I don't understand why you use ExecuteNonQuery with SELECT statement. It just executes your query. It doesn't even return any value.
If you want to get the result of your query, you can use ExecuteReader method which returns SqlDataReader as your result rows.

Copying rows from one database from another with parameters on C#

I'm trying to make a program that copies data from one table to the other in other server.
The thing is table is not exactly same. So Let's say these are my tables:
Server A:
TableA (Col1, Col2, Col3)
Server B:
TableB (Col1, Col2)
I want to copy from ServerA.TableA to ServerB.TableB.
My code:
Truncate_table(ConnectionB, "TableB");
MySqlCommand CmdB = new MySqlCommand("", ConnectionB);
CmdB.CommandText = "INSERT INTO ServerB.TableB (col1, col2) VALUES (#val1, #val2)";
using (MySqlCommand cmd = new MySqlCommand("", ConnectionA))
{
cmd.CommandText = "SELECT col2, col3 FROM ServerA.TableA";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
CmdB.Parameters.AddWithValue("#val1", reader.GetInt32(0));
CmdB.Parameters.AddWithValue("#val2", reader.GetInt32(1));
CmdB.ExecuteNonQuery();
}
}
}
However, it gives error saying 'Parameter '#val1' has already been defined.'.
Can you guys give me a piece of advice?
And is there more efficient way to do this? but I want to do this in C#.
Try adding the parameters once, then setting the value of those parameters within the while-loop:
MySqlCommand CmdB = new MySqlCommand("", ConnectionB);
CmdB.CommandText = "INSERT INTO ServerB.TableB (col1, col2) VALUES (#val1, #val2)";
CmdB.Parameters.AddWithValue("#val1", 0); // Default values
CmdB.Parameters.AddWithValue("#val2", 0);
using (MySqlCommand cmd = new MySqlCommand("", ConnectionA))
{
cmd.CommandText = "SELECT col2, col3 FROM ServerA.TableA";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
CmdB.Parameters["#val1"].Value = reader.GetInt32(0));
CmdB.Parameters["#val2"].Value = reader.GetInt32(1));
CmdB.ExecuteNonQuery();
}
}
}
Also, I could be wrong, but I believe you need to use ? to delimit parameters for MySql. If you have any other issues you might try replacing #val1 and #val2 with ?val1 and ?val2.
You are coping row by row the data. This is a very inefficient way to copy from a table to another. You can achieve the same result with a similar code executing just one INSERT on the database, you just need to read previously all the rows you want to insert.
Oh I just added
CmdB.Parameters.Clear();
After
CmdB.ExecuteNonQuery();

Return value from SQL Server Insert command using c#

Using C# in Visual Studio, I'm inserting a row into a table like this:
INSERT INTO foo (column_name)
VALUES ('bar')
I want to do something like this, but I don't know the correct syntax:
INSERT INTO foo (column_name)
VALUES ('bar')
RETURNING foo_id
This would return the foo_id column from the newly inserted row.
Furthermore, even if I find the correct syntax for this, I have another problem: I have SqlDataReader and SqlDataAdapter at my disposal. As far as I know, the former is for reading data, the second is for manipulating data. When inserting a row with a return statement, I am both manipulating and reading data, so I'm not sure what to use. Maybe there's something entirely different I should use for this?
SCOPE_IDENTITY returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
You can use SqlCommand.ExecuteScalar to execute the insert command and retrieve the new ID in one query.
using (var con = new SqlConnection(ConnectionString)) {
int newID;
var cmd = "INSERT INTO foo (column_name)VALUES (#Value);SELECT CAST(scope_identity() AS int)";
using (var insertCommand = new SqlCommand(cmd, con)) {
insertCommand.Parameters.AddWithValue("#Value", "bar");
con.Open();
newID = (int)insertCommand.ExecuteScalar();
}
}
try this:
INSERT INTO foo (column_name)
OUTPUT INSERTED.column_name,column_name,...
VALUES ('bar')
OUTPUT can return a result set (among other things), see: OUTPUT Clause (Transact-SQL). Also, if you insert multiple values (INSERT SELECT) this method will return one row per inserted row, where other methods will only return info on the last row.
working example:
declare #YourTable table (YourID int identity(1,1), YourCol1 varchar(5))
INSERT INTO #YourTable (YourCol1)
OUTPUT INSERTED.YourID
VALUES ('Bar')
OUTPUT:
YourID
-----------
1
(1 row(s) affected)
I think you can use ##IDENTITY for this, but I think there's some special rules/restrictions around it?
using (var con = new SqlConnection("connection string"))
{
con.Open();
string query = "INSERT INTO table (column) VALUES (#value)";
var command = new SqlCommand(query, con);
command.Parameters.Add("#value", value);
command.ExecuteNonQuery();
command.Parameters.Clear();
command.CommandText = "SELECT ##IDENTITY";
int identity = Convert.ToInt32(command.ExecuteScalar());
}

How can I insert each element in a 1D array into a new row in an SQL Database using C#?

I have an array containing a list of file paths that I want to insert into an SQL database.
string[] filePaths = Directory.GetFiles(#"C:\Test Folder");
I am confident in setting up and connecting to the database, I just can't figure out how to take each element and place it in a new row in the database.
Thanks,
Matt
It depends on which technology you are using (Please note that when inserting lots of rows the use of SqlBulkCopy is recommended).
ADO.NET
foreach (var path in filePaths)
{
var command = new SqlCommand("INSERT INTO mytable(col1) VALUES(#param1)", connection);
command.Parameters.AddWithValue("#param1", path);
command.ExecuteNonQuery();
}
LINQ-to-SQL
var projection = filePaths.Select(a => new MyTable() { Col1 = a });
myContext.InsertAllOnSubmit(projection);
myContext.SubmitChanges();
LINQ-to-Entities
foreach (var path in filePaths)
{
myModel.MyTable.AddObject(new MyTable() { Col1 = path });
}
myModel.SaveChanges();
foreach(string fp in filePaths)
{
InsertIntoDb(fp);
}
//Method
public void InsertIntoDb(string insert)
{
SqlConnection con = //Setup DB connection
SqlCommand command = new SqlCommand();
command.Connection = con;
command.CommandText = "Insert #insert into Table";
command.Parameters.AddWithValue("#insert", insert);
command.ExecuteNonQuery();
}
This leaves out a lot, but it should point you in the right direction. Essentially, you want to set up your connection, instantiate a SqlCommand object where the command text is the SQL Text to insert your value (Better would be a stored procedure or some other sanitized way to insert the data to avoid Sql Injection), and then call ExecuteNonQuery() to insert the actual data.
The most efficient way is to use SqlBulkCopy
you will have to project your data into a DataTable, DataRow[], etc. OR IDataReader (which is more efficient - refer this discussion and example) in order to use SqlBulkCopy

Categories