So I'm trying to use a MySqlDataReader to acquire data from my database. I know that the database does in fact respond (insert, delete, and update all work fine from my program).
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
// Open a connection
conn.Open();
MySqlCommand command = conn.CreateCommand();
command.CommandText = "select * from cs3500_u0848199.PairedGames";
// Execute the command and cycle through the DataReader object
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{ /*do something here*/}
}
}
The problem does not appear to be with the command itself, as the command works in the MySQL workbench. Anyways, upon executing this line of code
using (MySqlConnection conn = new MySqlConnection(connectionString))
the VS debugger notes that the following exception was thrown
System.FormatException was unhandled by user code
HResult=-2146233033 Message=Guid should contain 32 digits with 4
dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). Source=mscorlib
StackTrace:
at System.Guid.TryParseGuidWithNoStyle(String guidString, GuidResult& result)
at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
at System.Guid..ctor(String g)
at MySql.Data.Types.MySqlGuid.MySql.Data.Types.IMySqlValue.ReadValue(MySqlPacket
packet, Int64 length, Boolean nullVal)
at MySql.Data.MySqlClient.NativeDriver.ReadColumnValue(Int32 index, MySqlField field, IMySqlValue valObject)
at MySql.Data.MySqlClient.Driver.ReadColumnValue(Int32 index, MySqlField field, IMySqlValue value)
at MySql.Data.MySqlClient.ResultSet.ReadColumnData(Boolean outputParms)
at MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlDataReader.Read()
at ToDoList.BoggleService.GetBriefStatus(String gameToken) in d:\repositories\x0848199\PS11\ToDoService\BoggleService.svc.cs:line
443
at SyncInvokeGetBriefStatus(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object
instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
rpc) InnerException:
Really unsure as to why it's telling me about the guid format since i'm not using Guids in this code.
Any help will be greatly appreciated.
it appears that appending ;old guids=true; to the connection string resolved the issue.
Related
Details:
System.InvalidOperationException
HResult=0x80131509
Message=BeginExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
Source=System.Data.SqlClient
StackTrace:
at System.Data.SqlClient.SqlCommand.ValidateCommand(Boolean async, String method)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName) at System.Data.SqlClient.SqlCommand.BeginExecuteNonQuery(AsyncCallback callback, Object stateObject) at System.Threading.Tasks.TaskFactory1.FromAsyncImpl(Func3 beginMethod, Func2 endFunction, Action1 endAction, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory1.FromAsync(Func3 beginMethod, Func2 endMethod, Object state)
at System.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Praktika.Form1.<button2_Click>d__9.MoveNext() in D:\Programminng\практика\Praktika\Praktika\Form1.cs:line 149
This exception was originally thrown at this call stack:
[External Code]
Praktika.Form1.button2_Click(object, System.EventArgs) in Form1.cs
private async void button2_Click(object sender, EventArgs e)
{
if (label8.Visible)
label8.Visible = false;
if (!string.IsNullOrEmpty(textBox11.Text) && !string.IsNullOrWhiteSpace(textBox11.Text) &&
!string.IsNullOrEmpty(textBox6.Text) && !string.IsNullOrWhiteSpace(textBox6.Text) &&
!string.IsNullOrEmpty(textBox5.Text) && !string.IsNullOrWhiteSpace(textBox5.Text) &&
!string.IsNullOrEmpty(textBox4.Text) && !string.IsNullOrWhiteSpace(textBox4.Text))
{
SqlCommand command = new SqlCommand("UPDATE [Praktika] SET [LastNAme]=#LastNAme,[Passport]=#Passport,[Cod]=#Cod WHERE [Id]=#Id", sqlConnection);
command.Parameters.AddWithValue("Id", textBox11);
command.Parameters.AddWithValue("LastName", textBox6);
command.Parameters.AddWithValue("Passport", textBox5);
command.Parameters.AddWithValue("Cod", textBox4);
await command.ExecuteNonQueryAsync();
}
else if(!string.IsNullOrEmpty(textBox11.Text) && !string.IsNullOrWhiteSpace(textBox11.Text))
{
label8.Visible = true;
label8.Text = "Id должен быть заполнен!";
}
else
{
label8.Visible = true;
label8.Text = "Поля 'Фамилия','Пасспорт и 'Код' должны быть заполнены";
}
}
[enter image description here][1]
[1]: https://i.stack.imgur.com/F9oyl.png
BeginExecuteNonQuery requires an open and available Connection. The connection's current state is closed
You need to call sqlConnection.Open() before you await command.ExecuteNonQueryAsync();
I don't recommend holding onto a connection at class level; hold a connection string instead and make a new connection:
using var conn = new SqlConnection(classLevelConnStr);
using var command = new SqlCommand(sql, conn);
//parameters etc here
conn.Open();
command.Execute...
conn.Close(); //if you're going to do more work before you return, close after you execute
If you aren't going to do more work after you execute, you can leave the exiting of the using scope to dispose/close the connection. Opening/closing doesn't actually forge a TCP connection to the server, it simply leases and returns a connection from a pool of kept-open TCP connections, for best performance, unless you've turned off pooling (don't).
By holding onto a connection for a long time you can accidentally leave it open (leased), which prevents its re-use, and you can also increase the risk of running into "the connection already has an open reader" type issues if you do something like looping a reader and firing off update queries while you loop; make a new connection every time you want one - it's not a slow thing to create
--
Separately to this:
Please rename your controls after you drop them on a form. It takes seconds to do and prevents your code filling up with meaningless variable names. The process of filling code with junk variable names is called obfuscation, a technique designed to make code hard to read and understand. At some point someone else will have to read your code (us, your coworker or replacement, even you in 6 months time..) and they would rather read firstNameTextBox, ageNumericUpDown than textBox57, numericUpDown13. To understand why it's important, just imagine how confusing C# would be if instead of names like string.Length, string.Substring(int start, int length) Microsoft had called them things like Type1.Integer1, Type1.Method1(Type2 parameter1, Type2 parameter2) to chop up a string you'd be writing code like Type1 s = "Hello"; s = s.Method1(0, s.Integer1 - 3); - it's gobbledegook
To rename a control, you right click on it, choose Properties, and then type a new name in the (Name) line of the property grid - it's at the top. You don't even have to right click if the properties grid is already open, just left click the control
Avoid using AddWithValue on SQLServer. Some databases don't care, but SQLS does: https://www.dbdelta.com/addwithvalue-is-evil/
This code is wonky:
command.Parameters.AddWithValue("LastName", textBox6);
It should look something like:
command.Parameters.Add("#LastName", SqlDbType.VarChar, 30).Value = lastNameTextBox.Text);
Replace 30 with the size of the db column and if your column is an NVarChar change the SqlDbType.VarChar to SqlDbType.NVarChar too
This latter form implements the "rename your controls", it adds a parameter using the exact type on the DB side, and it sets the value to the Text of the textbox.. This latter point is important; the text the user typed is in the .Text property. If you just add a textbox object itself you'll probably end up filling your db up with [System.Windows.Forms.TextBox] in every cell of every row
I'm using Dapper for calling MySql stored procedure. The procedure executes just fine, but after that the code throws an exception. The code block that is problematic is like this:
using (var conn = DataFactory.InitializeConnection(false))
{
conn.Query("ProcedureName", new
{
puserid = ID
}, commandType: System.Data.CommandType.StoredProcedure);
}
Where DataFactory is the following static class:
public static class DataFactory
{
public static IDbConnection InitializeConnection(bool open = true, string connectionstring = "", string databaseServerType = "MYSQL")
{
if (string.Equals(databaseServerType, "MYSQL"))
{
if (string.IsNullOrEmpty(connectionstring))
connectionstring = Settings.Default.DataConnectionString;
var csb = new MySql.Data.MySqlClient.MySqlConnectionStringBuilder(connectionstring);
var conn = new MySql.Data.MySqlClient.MySqlConnection(csb.ConnectionString);
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
if (open)
conn.Open();
return conn;
}
throw new NotImplementedException("Not implemented for your database provider");
}
}
I have no bogus_table in my database, tho it is shown in the error message:
MySql.Data.MySqlClient.MySqlException (0x80004005): SELECT command
denied to user 'XXX'#'YYY' for table 'bogus_table' at
MySql.Data.MySqlClient.MySqlStream.ReadPacket() at
MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow,
Int64& insertedId) at
MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean
force) at MySql.Data.MySqlClient.MySqlDataReader.NextResult() at
MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior
behavior) at MySql.Data.MySqlClient.MySqlDataReader.ClearKillFlag()
at MySql.Data.MySqlClient.MySqlDataReader.Close() at
MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing)
at MySql.Data.MySqlClient.MySqlDataReader.Dispose() at
Dapper.SqlMapper.d__1361.<>m__Finally1() at
Dapper.SqlMapper.<QueryImpl>d__1361.MoveNext()
it's maybe problem in Mysql Driver implementation; here is code block that mentions bogus_table.
if your procedure has empty result try to call with Execute (because it implements execute non query inside) instead of Query.
using (var conn = DataFactory.InitializeConnection(false))
{
conn.Execute("ProcedureName", new
{
puserid = ID
}, commandType: System.Data.CommandType.StoredProcedure);
}
I encountered, kind of like same issue with 'bogus_table' which indeed comes from MySql code!
MySql.Data.MySqlClient.MySqlException: 'Table 'myspector.bogus_table' doesn't exist'
You are maybe in debug mode with all exceptions enabled.
When this exception raises, uncheck 'break when this exception is thrown' like in the image below:
Then, restart / continue, and you will see that this exception and is catched by another exception handler in the stack : it is transformed into a classic InvalidOperationException:
{"Sequence contains no elements"} System.Exception {System.InvalidOperationException}
I have installed postgres in my windows machine and started working on a POC. I am able to connect to the database from the windows command line. But, I am unable to connect from the C# application.
It seems i have some issues in the connection string. I have gone through multiple tutorials but every tutorial has their own way of providing the connection string parameters.Is there any standard way of giving the hostname,port,username,password and database.
I am trying to query using a rest api. Am, I doing the right way.
// GET api/values
[HttpGet]
public IActionResult Get()
{
Test test = new Test();
return Ok(test.Table2Json());
}
using Npgsql;
using System;
namespace Zeiss.MCCNeo.DataMigration.Utilities
{
public class Test
{
private readonly NpgsqlConnection conn;
public Test()
{
conn = new NpgsqlConnection("Server=127.0.0.1;User Id=postgres;" +
"Password=postgres;Database=postgres;");
//also tried using this
conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User
Id=postgres;" +
"Password=postgres;Database=postgres;");
}
public string Table2Json()
{
string value = null;
NpgsqlCommand command = new NpgsqlCommand("select * from test",
conn);
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
value = dr[0].ToString();
}
return value;
}
}
}
Exception:
- $exception {System.InvalidOperationException: Connection is not open
at Npgsql.NpgsqlConnection.CheckReadyAndGetConnector()
at Npgsql.NpgsqlCommand.<ExecuteDbDataReader>d__92.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at Npgsql.NpgsqlCommand.ExecuteReader()
at Zeiss.MCCNeo.DataMigration.Utilities.Test.Table2Json() in c:\users\inpyadav\documents\visual studio 2017\Projects\DataMigration\Zeiss.MCCNeo.DataMigration.Utilities\Test.cs:line 19
at DataMigration.Controllers.ValuesController.Get() in c:\users\inpyadav\documents\visual studio 2017\Projects\DataMigration\DataMigration\Controllers\ValuesController.cs:line 18
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()} System.InvalidOperationException
Why don't you open connection as it says in error message?
conn.Open();
I have some code that periodically runs a query against a SQL Server database and stores the rows in a dictionary. This code has been running fine in our production environment for about 3 years. Just recently, it has been crashing with an unhandled exception. For troubleshooting purposes, I've removed everything but the column reads, and wrapped everything in a try-catch. Here is the exception:
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadByteArray(Byte[] buff, Int32 offset, Int32 len)
at System.Data.SqlClient.TdsParser.SkipValue(SqlMetaDataPriv md, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.SkipRow(_SqlMetaDataSet columns, Int32 startCol, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.CleanPartialRead()
at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
I'm using something very similar to:
// query is a simple select from 1 table, not long running by any means
string query = "SELECT col1, col2, col3, col4 FROM db.dbo.tbl_name WITH (nolock)"; //connection timeout
string query = "SELECT col1, col2, col3, col4 FROM db.dbo.tbl_name WITH (nolock) order by col1, col2"; //connection does not time out
SqlCommand command = new SqlCommand(query,connection)
SqlDataReader reader = command.ExecuteReader();
while (!reader.IsClosed && reader.Read()) {
try {
string test0 = reader[0].ToString();
string test1 = reader[1].ToString();
string test2 = reader[2].ToString();
string test3 = reader[3].ToString();
// here is where I would normally processes and store into dictionary
}
catch (Exception e){
//make some noises
}
}
When I run the query with other methods, It returns almost instantly (well under a second), but just to see what would happen, I increased the CommandTimeout to 60 seconds (from the default 30), which just increased the amount of time my program would hang before throwing an exception.
At #frisbee's suggestion I added an order by clause to the query, which stops the connection from timing out.
What I think is happening is that one of the Read() operations is not returning, and then causing the connection to timeout, but I have no idea what would cause this. This usually happens on a certain row when reading column 3, but not always. The query returns just under 50k rows, and sometimes it will make it through all, and sometimes only through 15k
Why don't you go ahead and set the CommandTimeout property of your SqlCommand instance to a high number? This will get your code working.
On the other end, you'll need to debug whatever's taking the server so long to finish its work. You can't do anything about that from the .NET side. You'll have to step through the underlying code that is executed on the SQL Server.
Why is it you are checking if the reader is closed on your while loop?
Try using using to ensure things are getting handled correctly. The following should make everything flow smoothly for you.
using (SqlConnection connection = MyDBConnection)
{
connection.Open();
SqlCommand command = new SqlCommand("SQL Query Here", connection) { CommandTimeout = 0 };
using (var reader = command.ExecuteReader())
{
try
{
while (reader.Read())
{
string test0 = reader[0].ToString();
string test1 = reader[1].ToString();
string test2 = reader[2].ToString();
string test3 = reader[3].ToString();
}
}
catch (Exception e)
{
//Make some Noise
}
}
}
Every other run? Are you possibly sharing a command?
If you are using MARS and sharing a connection - don't
using (SqlCommand cmd = con.CreateCommand)
{
using (SqlDataReader rdr = cmd.ExecuteReader())
{
}
}
The following line of code sometimes results in "Specified cast is not valid" exception:
public static object Select(string sql, OleDbTransaction dbt)
{
try
{
OleDbCommand cmd = new OleDbCommand(sql, lib.dbc, dbt);
object obj = cmd.ExecuteScalar(); /* <- this is what fails */
return obj;
}
catch (Exception ex)
{
/* deleted code - error message to the user */
return null;
}
}
This function is executed several times in the program before it fails. If fails olny when it's executed in a new execution thread, and then only sometimes. When I call the part of the program which performs processing in a thread, and it calls this function, either it works all the time (=> I click the button, it executes, no error, I click and execute again and again...), or it never works (=> I click the button and execute, exception, I click and execute again, exception again...).
lib.dbc -> static variable of type OleDbConnection initialized only at program startup and used very often throughout the code, valid
I have no idea how to debug it any further, and above all, what assignment to a variable of type object can fail? ExecuteScalar should return object or null. Database I'm using is Jet (MS Access).
In the exception I find this stack trace, maybe it can help:
at System.Data.OleDb.OleDbConnection.IOpenRowset()
at System.Data.OleDb.OleDbCommand.ExecuteTableDirect(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteScalar()
at FK.sql.Select(String sql, OleDbTransaction dbt)
If fails olny when it's executed in a new execution thread, and then only sometimes.
This statement, combined with the fact you're passing in the connection as a parameter, suggests you may be trying to use the same database connection, and maybe transaction, on multiple threads.
Don't: instead create a new connection each time you want to access the database: connection pooling means that this will be efficient.
Try this, just as a diagnostic tool:
public static object Select(string sql, OleDbTransaction dbt)
{
try
{
using (OleDbConnection con = new OleDbConnection(lib.dbc.ConnectionString))
using (OleDbCommand cmd = new OleDbCommand(sql, con, dbt))
{
object obj = cmd.ExecuteScalar();
return obj;
}
}
catch (Exception ex)
{
/* deleted code - error message to the user */
return null;
}
}
This may help determine whether you have a threading problem.