Problems with double queries - c#

I'm trying to execute 2 query in one button click.. It doesn't seem to work and just closes automatically. Can anyone help me or explain to me why my code doesn't work? Here's the code:
test = 1;
{
connection.Open();
string strTemp = " [StudentNum] Text, [StudentName] Text, [Section] Text, [TimeIn] Text, [TimeOut] Text, [Status] Text";
OleDbCommand myCommand = new OleDbCommand();
myCommand.Connection = connection;
myCommand.CommandText = "CREATE TABLE [" + date + "](" + strTemp + ")";
myCommand.ExecuteNonQuery();
if (test == 1)
{
OleDbCommand commandl = new OleDbCommand();
commandl.Connection = connection;
commandl.CommandText = "INSERT INTO ['" + date + "']([StudentNum],[StudentName],[Section]) select [StudentNo],[Name],[Section] from StudInfo";
commandl.ExecuteNonQuery();
}

Remove the apostrophes delimiting table name.
commandl.CommandText = "INSERT INTO [" + date + "]([StudentNum],[StudentName],[Section]) select [StudentNo],[Name],[Section] from StudInfo";

Related

Insert data to Mysql getting slower and slower

I need to insert 388 datas per minute to local Database.
At first when the table is Empty, I only need 5 second to Insert to database.
But when the table gets larger, the program efficacy slow down to more than one minute when the amount of rows comes to 1,026,558.
And the useage of CPU is 100%. It's unusual.
here is my code:
public static void dataToDB(String[] routeIDArray,String[] levelArray,String[] valueArray,String[] travelTimeArray, int amountOfData)
{
MySqlConnection con = new MySqlConnection(connStr);
MySqlCommand cmd = null;
MySqlDataReader rdr = null;
String sqlCmd, updateSqlCmd = "UPDATE `datetimetable` SET ";
for(int counter = 0; counter < amountOfData; counter++)
{
sqlCmd = "ALTER TABLE `datetimetable` ADD COLUMN IF NOT EXISTS `" + routeIDArray[counter] + "` INT NULL;"
+ "INSERT INTO `roadvalue`.`data` (`level`,`value`,`traveltime`) VALUES ("
+ levelArray[counter] + ","
+ valueArray[counter] + ","
+ travelTimeArray[counter] + ");"
+ "SELECT LAST_INSERT_ID() FROM `data`;";
cmd = new MySqlCommand(sqlCmd, con);
con.Open();
rdr = cmd.ExecuteReader();
rdr.Read();
updateSqlCmd += "`" + routeIDArray[counter] + "` = " + rdr[0] + ",";
rdr.Close();
}
updateSqlCmd = updateSqlCmd.TrimEnd(',');
updateSqlCmd += " WHERE EXISTS (SELECT * WHERE dateTime = '" + dateTime.ToString("yyyy-MM-dd HH:mm:00") + "');";
cmd = new MySqlCommand(updateSqlCmd, con);//update data key to datetimetable
cmd.ExecuteNonQuery();
Console.WriteLine("Done.");
con.Close();
}
public static void checkDateTimeExisted()
{
MySqlConnection con = new MySqlConnection(connStr);
MySqlCommand cmd;
String sqlCmd;
sqlCmd = "INSERT INTO `datetimetable` (`dateTime`) SELECT * FROM (SELECT '" + dateTime.ToString("yyyy-MM-dd HH:mm:00")
+ "') AS tmp WHERE NOT EXISTS(SELECT `dateTime` FROM `datetimetable` WHERE `dateTime` = '" + dateTime.ToString("yyyy-MM-dd HH:mm:00") + "') LIMIT 1; ";
con.Open();
cmd = new MySqlCommand(sqlCmd, con);
cmd.ExecuteNonQuery();
con.Close();
}
And Mysql Engine is InooDB, table "data" has one Auto_Increment Primary key, table "datetimetable" has an Auto_Increment Primary key and a not duplicate datetime as index.
What have I done wrong?
I find the answer, the command "SELECT LAST_INSERT_ID() FROM data;" should add LIMIT 1 or it will get all the ID kill the performance.
Do not use ALTER TABLE in a loop -- Plan ahead and provide all the columns before starting.
Do not use multiple statements in a single string. This has security implications, etc.
Do not use WHERE EXISTS... when (I think) a simple WHERE would work.
If there is UNIQUE(datetime), then the final INSERT can be simply
INSERT IGNORE INTO datetimetable
(datetime)
VALUE
('...');
Do batch inserts unless you need the LAST_INSERT_ID(). LIMIT 1 should not be necessary.
Do not 'Normalize' datetime values; it only slows things down. Just put the datetime as is in the main table.

Multiple parameterized updates with C# and Oracle

I'm trying to execute multiple updates like this
UPDATE clients SET name = :name WHERE clientId = :clientID
I've tried something like this
OracleConnection con = new OracleConnection(connectionString);
con.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = con;
cmd.CommandText =
"begin " +
" UPDATE clients SET name = " + name1 + " WHERE clientId = " + clientId1 +
" UPDATE clients SET name = " + name2 + " WHERE clientId = " + clientId2 +
"end;";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
con.Close();
but I need to execute hundreds of parameterized updates like the first one

Using ExecuteReader to return a primary key

How Do I Find the ID from the first query and return this value so it can be inserted into query2? This is the code that needs done when a user completes a form on front end. I need to populate two tables and they will relate through the ID "StoryID" which is a primary key that is automatically created.
protected void Upload2_Click(object sender, EventArgs e)
{
userStoryForm.Visible = false;
info.Text = "You have successfully added a new user story.";
String connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
String usernameData = username.Text.ToString();
int captureProjectID = Convert.ToInt32(Request.QueryString.Get("ProjectID"));
String storyno = StoryNoTextBox.Text;
String userstory = StoryTextTextBox.Text;
//Create connection
SqlConnection myConnection = new SqlConnection(connectionString);
//open connection
myConnection.Open();
String query = "INSERT INTO UserStories (StoryNo, StoryText, ProductOwner, ProjectID) " +
"VALUES ('" + storyno + "','" + userstory + "','" + usernameData + "','" + captureProjectID + "')" +
"SELECT SCOPE_IDENTITY() AS StoryID;";
SqlCommand myCommand = new SqlCommand(query, myConnection);
// Call GetOrdinal and assign value to variable.
SqlDataReader reader = myCommand.ExecuteReader();
int StoryIDData = reader.GetOrdinal("StoryID");
// Use variable with GetString inside of loop.
while (reader.Read())
{
Console.WriteLine("StoryID={0}", reader.GetString(StoryIDData));
}
// Call Close when done reading.
reader.Close();
//insert productowner, projectID and storyID into ProductBacklog table
String query2 = "INSERT INTO ProductBacklog (ProductOwner, ProjectID, StoryID) VALUES ('" + usernameData + "', #returnProjectID,'" + StoryIDData + "')";
SqlCommand myCommand2 = new SqlCommand(query2, myConnection);
myCommand2.Parameters.AddWithValue("#returnProjectID", captureProjectID);
//close connection
myConnection.Close();
}
}
Most important - use parameters in your SQL command. Never concatenate strings like that. You're asking for an SQL injection attack.
string query = #"
INSERT INTO UserStories (StoryNo, StoryText, ProductOwner, ProjectID)
VALUES (#storyno, #userstory, #usernameData, #captureProjectID)
SELECT CAST(SCOPE_IDENTITY() AS INT)";
SqlCommand myCommand = new SqlCommand(query);
myCommand.Parameters.Add("#storyno", DbType.String).Value = storyno;
...
To get the returned id, use ExecuteScalar():
int StoryIDData = (int)myCommand.ExecuteScalar();
Also, you don't dispose your resources correctly. If an exception is thrown in the method, the SQLConnection will not be closed. You should put it in a using statement.

Get selected dataGridView column data?

C# Windows Form
I have a button that removes the selected row from the dataGridView.
I also want the button to retrieve the selected rows "ordre" column value, so I can use it in a query that deletes the order from the sql table.
Here is what my code looks like:
dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
//SQL connection
SqlConnection con = new SqlConnection(#"Data Source=" + globalvariables.hosttxt + "," + globalvariables.porttxt + "\\SQLEXPRESS;Database=ha;Persist Security Info=false; UID='" + globalvariables.user + "' ; PWD='" + globalvariables.psw + "'");
SqlCommand command = con.CreateCommand();
//SQL QUERY
command.CommandText = "DELETE FROM bestillinger WHERE ordrenr = #ordre";
command.Parameters.AddWithValue("#ordre",dataGridView1.SelectedRows[0].Cells["ordre"].Value.ToString())
con.Open();
var ordre = command.ExecuteScalar();
con.Close();
But it doesn't work! No record was deleted
After delete the row you can not get the value. So change your code like this
//SQL connection
SqlConnection con = new SqlConnection(#"Data Source=" + globalvariables.hosttxt
+ "," + globalvariables.porttxt + "\\SQLEXPRESS;Database=ha;Persist Security
Info=false; UID='" + globalvariables.user + "' ; PWD='" + globalvariables.psw + "'");
SqlCommand command = con.CreateCommand();
//SQL QUERY
command.CommandText = "DELETE FROM bestillinger WHERE ordrenr = #ordre";
command.Parameters.AddWithValue("#ordre",dataGridView1.
SelectedRows[0].Cells["ordre"].Value.ToString())
con.Open();
var ordre = command.ExecuteScalar();
con.Close();
dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
It is wrong logic.
Since the row has been removed by RemoveAt(),
you cannot get a wrong row from dataGridView1.SelectedRows[0].
I think you want this.
private void grdform1_CellClick(object sender, DataGridViewCellEventArgs e)
{
If(e.ColumnIndex==0 ||e.ColumnIndex==1)
{
txtshowcolunm.text=e.ColumnIndex;
}
else
{
txtshowcolunm.text=e.ColumnIndex;
}
}

C# Database Insert (ASP.NET) - ExecuteNonQuery: CommandText property has not been initialized

first time I'm doing an insert from ASP.NET/C# and I'm having a little issue. I keep getting the following error every time this code runs: " ExecuteNonQuery: CommandText property has not been initialized" Does anyone know what this means and how I fix it?
Thanks in advance!
string sqlQuery = "INSERT INTO ATI_LOG_IO (Date, Connect_Time, Disconnect_Time, ATI_Rep, Reason_For_Access, Property_Contact, Case_Number, Comments, Property_ID)";
sqlQuery += "VALUES (#Today, #Connect, #Disconnect, #Rep, #Reason, #Contact, #CaseNum, #Comments, #PropertyID)";
using (SqlConnection dataConnection = new SqlConnection(connectionString))
{
using (SqlCommand dataCommand = dataConnection.CreateCommand())
{
dataConnection.Open();
dataCommand.CommandType = CommandType.Text;
dataCommand.CommandText = sqlQuery;
dataCommand.Parameters.Add("#Today", DateTime.Today.ToString());
dataCommand.Parameters.Add("#Connect", txtInDate.Text + " " + fromHrs.Text + ":" + fromMins.Text + ":00");
dataCommand.Parameters.Add("#Disconnect", txtOutdate.Text + " " + toHrs.Text + ":" + fromMins.Text + ":00");
dataCommand.Parameters.Add("#Rep", repID);
dataCommand.Parameters.Add("#Reason", txtReason.Text);
dataCommand.Parameters.Add("#Contact", txtContact.Text);
dataCommand.Parameters.Add("#CaseNum", txtCaseNum.Text);
dataCommand.Parameters.Add("#Comments", txtComments.Text);
dataCommand.Parameters.Add("#PropertyID", lstProperties.SelectedValue);
dataCommand.ExecuteNonQuery();
dataConnection.Close();
}
}
string sqlQuery = "INSERT INTO ATI_LOG_IO (Date, Connect_Time, Disconnect_Time, ATI_Rep, Reason_For_Access, Property_Contact, Case_Number, Comments, Property_ID)";
sqlQuery += " VALUES (#Today, #Connect, #Disconnect, #Rep, #Reason, #Contact, #CaseNum, #Comments, #PropertyID)";
using (SqlConnection dataConnection = new SqlConnection(connectionString))
{
using (SqlCommand dataCommand = new SqlCommand(sqlQuery, dataConnection))
{
dataCommand.Parameters.AddWithValue("Today", DateTime.Today.ToString());
dataCommand.Parameters.AddWithValue("Connect", txtInDate.Text + " " + fromHrs.Text + ":" + fromMins.Text + ":00");
dataCommand.Parameters.AddWithValue("Disconnect", txtOutdate.Text + " " + toHrs.Text + ":" + fromMins.Text + ":00");
dataCommand.Parameters.AddWithValue("Rep", repID);
dataCommand.Parameters.AddWithValue("Reason", txtReason.Text);
dataCommand.Parameters.AddWithValue("Contact", txtContact.Text);
dataCommand.Parameters.AddWithValue("CaseNum", txtCaseNum.Text);
dataCommand.Parameters.AddWithValue("Comments", txtComments.Text);
dataCommand.Parameters.AddWithValue("PropertyID", lstProperties.SelectedValue);
dataConnection.Open();
dataCommand.ExecuteNonQuery();
dataConnection.Close();
}
}
Copy-paste should do the trick
This usually means you haven't set the CommandText property, but in your case, you have.
You should try testing that the sqlQuery string is actually not empty at this line:
dataCommand.CommandText = sqlQuery;
P.S. As a "best practice", you may want to consider opening the connection AFTER setting up the SqlCommand object, to minimize the time spent with an open connection:
dataCommand.CommandType = CommandType.Text;
dataCommand.CommandText = sqlQuery;
dataCommand.Parameters.Add("#Today", DateTime.Today.ToString());
//...
dataConnection.Open();
dataCommand.ExecuteNonQuery();
dataConnection.Close();
Looking at your string sql query, you're not leaving a space between the "INTO" part and "VALUES" part.
...............Property_ID)";
sqlQuery += "VALUES (#Today, ..............
SHOULD BE:
...............Property_ID)";
sqlQuery += " VALUES (#Today, ..............

Categories

Resources