I have the following code:
static void InsertRes(string Data)
{
string query = "INSERT INTO results (gamenum,result) " + Data;
query += ";";
//open connection
if (OpenConnection() == true)
{
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery();
//close connection
CloseConnection();
}
}
I know it's not the best practices but I generate data within my application, how can I force this function to block until the query has been successfully executed upon the mysql database?
It will do that automatically.
cmd.ExecuteNonQuery(); will return after the insertion is finished.
That is standard programming behaviour. Doing multiple task simultaniously is where it gets tricky. Doing one thing after the other is just normal. Your program will continue to the next line only when the execution if the preivious line is finished.
Related
I'm just learning databases to store a (large amount) of user entry data.
I have the following code, which checks a record and chooses whether to update or create new
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sc1 = #"select count(*) from job1 where report = #report";
SqlCommand check = new SqlCommand(sc1, connection);
check.Parameters.AddWithValue("#report", jname);
// check if the report number already exists, if not make a new table otherwise insert
int test = (int)check.ExecuteScalar();
if (test > 0)
{
jobCardExistingTable(connection);
digCardExistingTable(connection);
//insert into existing table code
}
If I use either jobCardExistingTable or digCardExisting table, they work fine. If I use both, I get the error
require open and available connection
I assume that the first ExecuteNonQuery (which are contained in the jobCard and digCard methods) is doing something with the connection - can I keep this one open, or do I have to open a new one each time I call a method? Maybe I'm doing this all wrong anyways...each method is calling a new table in the database, should I be calling them all at once?
Edit: part of the issue is jobCardTable (digCardTable is identical, just a different query)
public void jobCardNewTable(SqlConnection connection)
{
using (connection)
{
string sc3 = "";
sc3 = #"INSERT INTO job1 (" + pv.jobstring + ") VALUES (" + pv.jobparam + ")";
SqlCommand cmd = new SqlCommand(sc3, connection);
queryParams(cmd, 0);
cmd.ExecuteNonQuery();
}
}
Edit: solved - realised that using{} disposes the connection. Took all the using{} out of the methods, and used a single using{} to encompass all the method calls and it works
You should not use using (connection) if you are using same connection in other part of code. using dispose connection and make unavailable for further connection.
So, your jobCardNewTable method implementation should be without using statement :
public void jobCardNewTable(SqlConnection connection)
{
string sc3 = "";
sc3 = #"INSERT INTO job1 (" + pv.jobstring + ") VALUES (" + pv.jobparam + ")";
SqlCommand cmd = new SqlCommand(sc3, connection);
queryParams(cmd, 0);
cmd.ExecuteNonQuery();
}
I would recommend to create new connection whenever you need it and dispose it.
How to write tests for delegate methods?
or
Beware of 2 open connections both with 'hooks' onto the same SQL table .... .
This was not straight forward to diagnose, test and prove is not a problem with my current solution.
How could I have TDD'd or written unit/integration tests to have trapped this? Redesign suggestions ...
Create a connection to the table 'TransferWebTransmit' to process
all rows.
Execute a Reader to loop through 'old' records, (ID=1)
Call a delegate method to process the 'old' record. (NB keep current
connection open until all rows are processed i.e. have called the delegate).
Delegate method:
Opens a new connection, executes a Stored Proc 'TransferWebTransmitUpdate'
which -> Updates the table 'TransferWebTransmit' row (ID=1), then does a SELECT on (ID=1) row
----> cursor lock!
----> .Net throws "System.Data.SqlClient.SqlException (0x801
31904): Timeout expired. The timeout period elapsed prior to completion of the
operation or the server is not responding".
----> Connections are locked.
----> Have to Kill processes to recover
Here's the delegate method:
public int Update(int transferID)
{
var obj = new TransferWebMessage();
using (SqlConnection conn = base.GetNewConnection())
{
using (SqlCommand sp_cmd = new SqlCommand())
{
sp_cmd.CommandText = "TransferWebTransmitUpdate";
sp_cmd.CommandType = CommandType.StoredProcedure;
sp_cmd.Parameters.AddWithValue("TransferID", transferID);
sp_cmd.Connection = conn;
conn.Open();
SqlDataReader rdr = sp_cmd.ExecuteReader();
int roweffected;
while (rdr.Read())
{
roweffected = rdr.GetInt32(0),
}
}
}
return roweffected;
}
Here's the call to get the rows to process and call the delegate:
public void WatchForDataTransferRequests(_delegateMethod callback)
{
using (SqlConnection conn = new SqlConnection(_insol_SubscriberConnectionString))
{
// Construct the command to get any new ProductReview rows from the database along with the corresponding product name
// from the Product table.
SqlCommand cmd = new SqlCommand(
"SELECT [TransferID]" +
" FROM [dbo].[TransferWebTransmit]" +
" ORDER BY [TransferID] ASC", conn);
cmd.Parameters.Add("#CurrentTransferID", SqlDbType.Int);
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
// Process the rows
while (rdr.Read())
{
Int32 transferID = (Int32)rdr.GetInt32(0);
callback(transferID);
}
}
}
I used to call several functions with this connection string:
class Solders_DB
{
SqlConnection connection;
SqlCommand query;
String command;
public Solders_DB()
{
connection = new SqlConnection();
connection.ConnectionString = "Server=localhost;Database=Scheduling_Employee ;Trusted_Connection=True;MultipleActiveResultSets=True;";
query = new SqlCommand();
}
As you see I used this MultipleActiveResultSets=True; in my connection but in this function :
command = #"SELECT [GID] FROM [Scheduling_Employee].[dbo].[Solder] where [ID]=#ID";
query.CommandText = command;
query.Parameters.Clear();
query.Parameters.AddWithValue("#ID", id);
Object o= query.ExecuteScalar();
I faced with this error:
There is already an open datareader associated with this command which must be closed first
The code in your question is not complete. Please explain yourself better for further assistance.
When using a SqlConnection is recommended to use the 'using' statement like this:
using (SqlConnection SqlConn = new SqlConnection(ConnString))
{
try
{
SqlConn.Open();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return null;
}
}
You're trying to read data from the first execution of your query, please update your question and put the complete code and the error stack.
Its usually when there was another query before that one and has not yet stopped executing inside the database engine (maybe it was a heavy script). You could try query = new SqlCommand();, query.Cancel() or
while(query.Connection.State != System.Data.ConnectionState.Open){ Threading.Sleep(100);}
I am having some issues with a class that I have created to perform different database commands.
1st) The program is local ran, and will only run locally. It will only ever connect to the database on the localhost.
Therefore I have a simple class setup, called databaseConnector that allows me to pass a string to it with the required Mysql query to perform the different functions.
For instance.
I use:
var db = new databaseConnector();
db.Update("UPDATE * WHERE.....");
However, it seems if I ever want to use a different query, or another query, it's not working and throwing errors.
For instance.
var db = new databaseConnector();
db.Update("UPDATE * WHERE...");
db.INSERT("INSERT INTO * WHERE.....");
Will give me an error on the insert execution. Any ideas why? I have resorted to creating it again. So I have to redo:
db = new databaseConnector();
to then use the Insert command.
Here is an example of my insert function.
public void Insert(string query)
{
//open connection
if (this.OpenConnection() == true)
{
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery();
//close connection
this.CloseConnection();
}
}
Now that I think about it. Should I call my db.openConnection() before doing it. Since when I initialize it in the first var db = new databaseConnection(), it's opening? And then in each function it's closing it, but only checking if it's open, instead of attempting to open, doing query, then closing.
I am using Oracle.DataAccess.Client to work with Oracle database in my ASP.Net application. There is no help documentation in MSDN for ODP.Net and Oracle's documentation is really really bad. I am not able find the answer to this simple question.
Is it not possible to execute a simple update statement without having to build a dataset object and updating the dataset?
How to execute an update statement using Oracle ODP.Net in C#?
I will need to check the exact syntax, but here is some quick code off the top of my head
using (OracleConnection con = new OracleConnection(...))
{
con.Open();
OracleCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "update table set col1 = :param1, col2 = :param2 where key = :keyValue";
cmd.Parameters.AddWithValue("param1", 1);
cmd.Parameters.AddWithValue("param2", "Text data");
cmd.Parameters.AddWithValue("keyValue", "1");
cmd.ExecuteNonQuery();
}
The above creates a command object sets the command up to execute an SQL Update statement, in this example I show one way to setup a parameterized query, you should always go with a parameterized query. Once the command is setup you just call ExecuteNonQuery to actually execute the command.
So after a bit of sleuthing and working this one out for a while, I found that the method I used to add a new parameter to the connection command is as follows. I did not find the method as was stated in the previous post. Mind you I am using a query object that I am passing the values around with.
public Boolean InsertMethod(Query _query)
{
var success = false;
var queryString = string.Format(#"INSERT INTO TABLE(ID, OWNER, TEXT) VALUES (TABLE_SEQ.NEXTVAL,:OWNER, :TEXT)");
try
{
using (OracleConnection con = new OracleConnection(ConString))
{
con.Open();
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = queryString;
cmd.Parameters.Add("OWNER", _query.Owner);
cmd.Parameters.Add("TEXT", _query.Text);
int rowsUpdated = cmd.ExecuteNonQuery();
if (rowsUpdated > 0) success = true;
}
return success;
}
catch (Exception ex)
{
log.Error(ex);
throw;
}
}
Further to #Chris's answer, here is the documentation page of OracleParameter class which has sample code on using OracleCommand to execute Updates.
EDIT: Here is the entry point for ODP.net documentation.