C# Mysql - The given key was not present in the dictionary - mysql

I am trying to execute the following code:
_cmd.CommandText = "SELECT * FROM category";
MySqlDataReader ret;
_cmd.Connection = _con;
_con.Open();
ret = _cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
_con.Close();
return ret;
Yet, I am getting a strange error:
The given key was not present in the dictionary.
The connection string is being read correctly from web.config (I can see this using the debuger). I also have other methods that use the same connectionString (that are used to insert data) and they work correctly. Anything I am missing here?!
This is the method I am trying to invoke:
public MySqlDataReader ExecuteReader(String sql, MySqlParameter[] param)
{
if (param != null)
_cmd.Parameters.AddRange(param);
_cmd.CommandText = sql;
MySqlDataReader ret;
_con.Open();
ret = _cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
return ret;
}
It is invoked from this web service:
[WebMethod]
public string[] GetCategories()
{
String sql = "SELECT CategoryName FROM category";
DatabaseHelper dh = new DatabaseHelper();
MySqlDataReader dr = dh.ExecuteReader(sql, null);
List<String> categories = new List<string>();
while (dr.Read())
{
categories.Add(dr[0].ToString());
}
dr.Close();
return categories.ToArray();
}

Related

Json from DataTable returns single element as an array

I'm trying to create an api endpoint that returns an element by id , but JsonResult makes an array from DataTable which is supposed to have only one object
[HttpGet("{id:int}")]
public JsonResult GetUser(int id)
{
string query = #"select id,number,name,lastName from dbo.Users where id=" + id;
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("UsersDb");
SqlDataReader myreader;
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
{
myCon.Open();
using (SqlCommand myComm = new SqlCommand(query, myCon))
{
myreader = myComm.ExecuteReader();
table.Load(myreader);
myreader.Close();
myCon.Close();
}
}
return new JsonResult(table);
}
However i get this result with squared brackets on the sides
[{"id":4,"number":10,"name":"Peter","lastName":"Peterson"}]
try this
return new JsonResult(JArray.FromObject(dt).First())
result
{"id":4,"number":10,"name":"Peter","lastName":"Peterson"}
You can just return table.Rows[0] rather than the whole table.
There are other improvements here:
Parameterize your query. Do not inject data into your SQL.
Missing using on the reader.
Consider making this function async
[HttpGet("{id:int}")]
public JsonResult GetUser(int id)
{
const string query = #"#
select
id,
number,
name,
lastName
from dbo.Users
where id = #id;
";
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("UsersDb");
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
using (SqlCommand myComm = new SqlCommand(query, myCon))
{
myComm.Parameters.Add("#id", SqlDbType.Int).Value = id;
myCon.Open();
using(var myreader = myComm.ExecuteReader())
{
table.Load(myreader);
}
}
return new JsonResult(table.Rows[0]);
}

MySql.Data.MySqlClient.MySqlException : Incorrect datetime value

Hai I have to add details from one table to another which should be within to dates. These dates are read from text boxes.
But i'm getting Error:
"An exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll but was not handled in user code
Additional information: Incorrect datetime value: '11/25/2015 12:00:00 AM' for column 'debissuedate' at row 1"
The first table is t_bondridapp with fields : id,cancode,canname,debissuedate...etc
And I have to copy from this table to new one named as bondlocal with fields :
bondid,cancode,canname,bonddate.
I've used the code
public class DBConnection
{
private DBConnection()
{
}
private string dbname = string.Empty;
public string DBName
{
get { return dbname;}
set { dbname = value;}
}
public string Password { get; set; }
private MySqlConnection mycon = null;
public MySqlConnection Connection
{
get { return mycon; }
}
private static DBConnection _instance = null;
public static DBConnection Instance()
{
if(_instance==null)
_instance=new DBConnection();
return _instance;
}
public bool IsConnect()
{
bool result = true;
if(mycon==null)
{
if (String.IsNullOrEmpty(dbname))
result = false;
string constr = string.Format("server=localhost;user id=root;password=mysql;database=pnys;",dbname);
mycon = new MySqlConnection(constr);
mycon.Open();
result = true;
}
return result;
}
public void Close()
{
mycon.Close();
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click1(object sender, EventArgs e)
{
MySqlDateTime fdate =new MySqlDateTime(DateTime.Parse(TextBox3.Text));
MySqlDateTime sdate = new MySqlDateTime(DateTime.Parse(TextBox4.Text));
var dbCon = DBConnection.Instance();
dbCon.DBName = "pnys";
if (dbCon.IsConnect())
{
string query = "INSERT INTO bondlocal (cancode,canname,bonddate) SELECT t_bondridapp.cancode,t_bondridapp.canname,t_bondridapp.debissuedate FROM t_bondridapp WHERE debissuedate>='" + fdate + "'AND debissuedate<='" + sdate + "'";
MySqlCommand cmd = new MySqlCommand(query, dbCon.Connection);
cmd.ExecuteNonQuery();
}
Server.Transfer("ReportBonds.aspx");
}
Pls Help Me...
Basically, the problem is how you're passing parameters into the database. You shouldn't need to create a MySqlDateTime yourself - just use parameterized SQL and it should be fine:
// TODO: Use a date/time control instead of parsing text to start with
DateTime fdate = DateTime.Parse(TextBox3.Text);
DateTime sdate = DateTime.Parse(TextBox4.Text);
string query = #"INSERT INTO bondlocal (cancode,canname,bonddate)
SELECT t_bondridapp.cancode,t_bondridapp.canname,t_bondridapp.debissuedate
FROM t_bondridapp
WHERE debissuedate >= #fdate AND debissuedate <= #sdate";
using (var command = new MySqlCommand(query, dbCon))
{
command.Parameters.Add("#fdate", MySqlDbType.Datetime).Value = fdate;
command.Parameters.Add("#sdate", MySqlDbType.Datetime).Value = sdate;
command.ExecuteNonQuery();
}
Basically, you should never specific values within SQL by just using string concatenation. Parameterized SQL prevents SQL injection attacks and conversion issues, and improves code readability.
(As an aside, I would urge you to ditch your current connection sharing, and instead always create and open a new MySqlDbConnection and dispose of it at the end of your operation - rely on the connection pool to make it efficient.)

Iam not able to retrieve completely the data from sql?

public string getString()
{
con.ConnectionString = ConnString;
con.Open();
string sp = "select top 3 hotelid from hotel order by NEWID()";
SqlCommand cmd = new SqlCommand(sp, con);
SqlDataAdapter sa = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
reader = cmd.ExecuteReader();
while (reader.Read()) //Call Read to move to next record returned by SQL //OR call --While(reader.Read())
{
det = reader[0].ToString();
}
reader.Close();
con.Close();
return det;
}
When I'm executing this code I'm able to retrieve only a single item of data?,
but when I am executing the SQL query I am able to retrieve randomly 3 items of data.
You are overwriting the det variable on each while loop.
You either need to create a collection and add to it, or concatenate the string (note the +=)...
det += reader[0].ToString();
UPDATE
As suggested above, another option is to create a collection, something like...
public List<string> getString()
{
...
List<string> ret = new List<string>;
while (reader.Read())
ret.Add(reader[0].ToString());
...
return ret;
}

Access import into SQL server not importing first line

I am using a function to import data from a access db into SQL server:
public string importDataFromAccess(string table, string fileName)
{
OleDbConnection OleDbConn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", fileName));
try
{
string sSQLTable = table;
string myExcelDataQuery = "Select * from " + sSQLTable;
string sSqlConnectionString = connStr;
string sClearSQL = "DELETE FROM " + sSQLTable;
SqlConnection SqlConn = new SqlConnection(sSqlConnectionString);
SqlCommand SqlCmd = new SqlCommand(sClearSQL, SqlConn);
SqlConn.Open();
SqlCmd.ExecuteNonQuery();
SqlConn.Close();
OleDbCommand OleDbCmd = new OleDbCommand(myExcelDataQuery, OleDbConn);
OleDbConn.Open();
OleDbDataReader dr = OleDbCmd.ExecuteReader();
SqlBulkCopy bulkCopy = new SqlBulkCopy(sSqlConnectionString);
bulkCopy.DestinationTableName = sSQLTable;
while (dr.Read())
{
bulkCopy.WriteToServer(dr);
}
OleDbConn.Close();
return "Done";
}
catch (Exception ex)
{
OleDbConn.Close();
return ex.ToString();
}
}
I noticed it isnt importing the first record of each table, can anyone help notice why and how to fix? Hopefully it is only the first row...
You shouldn't need the
while (dr.Read())
{
bulkCopy.WriteToServer(dr);
}
And you just need to replace that with
bulkCopy.WriteToServer(dr);
The WriteToServer method
Copies all rows in the supplied IDataReader to a destination table
specified by the DestinationTableName property of the SqlBulkCopy
object.
But the dr.Read() that you have called has read the first line out of the Reader and advanced the IDataReader to the next record (so it is not accessible to the WriteServer method).

MySQL System.FormatException: Input string was not in a correct format

Currently, I am creating an application using ASP.NET MVC3 and MySQL and when I try to retrieve a user's first name from the databse I receive a System.FormatException: Input string was not in a correct format.
This is my code:
public string GetUserFirstName(UInt64 id)
{
DBConnections databaseCnnString = new DBConnections();
string connectionString = "server=123.123.com;user=me;database=db1;port=3306;password=abcdef";
MySqlConnection cnn = new MySqlConnection(connectionString);
try
{
cnn.Open();
string sp_GetFName = "SP_GET_FNAME";
MySqlCommand cmd = new MySqlCommand(sp_GetFName, cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("id", id);
cmd.Parameters["id"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("first_name", MySqlDbType.VarChar);
cmd.Parameters["first_name"].Direction = ParameterDirection.Output;
object result = cmd.ExecuteScalar();
if (result != null)
{
string fname = Convert.ToString(result);
return fname;
}
else
{
string fname = "friend";
return fname;
}
}
catch (Exception ex)
{
throw (ex);
}
finally
{
cnn.Close();
cnn.Dispose();
}
}
This is MySQL Stored Procedure:
CREATE DEFINER=`0001`#`%` PROCEDURE `SP_GET_FNAME`(IN id BIGINT(20), OUT first_name VARCHAR(60))
BEGIN
DECLARE user_id BIGINT(20) DEFAULT id;
DECLARE output VARCHAR(60);
SELECT `FName` FROM `users` WHERE USERID=user_id INTO output;
SET first_name = output;
END
The problem seems to be when executing cmd.ExecuteScalar().
What is my problem here?
Thank you in advance!
Copy and paste error on my part. The correct code that works as expected is:
public string GetUserFirstName(UInt64 id)
{
DBConnections databaseCnnString = new DBConnections();
string connectionString = "server=123.123.com;user=me;database=db1;port=3306;password=abcdef";
MySqlConnection cnn = new MySqlConnection(connectionString);
try
{
cnn.Open();
string sp_GetFName = "SP_GET_FNAME";
MySqlCommand cmd = new MySqlCommand(sp_GetFName, cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("id", id);
cmd.Parameters["id"].Direction = ParameterDirection.Input;
cmd.Parameters.Add(new MySqlParameter("first_name", MySqlDbType.VarChar));
cmd.Parameters["first_name"].Direction = ParameterDirection.Output;
cmd.ExecuteScalar();
string fname = Convert.ToString((cmd.Parameters["first_name"].Value));
return fname;
}
catch (Exception ex)
{
throw (ex);
}
finally
{
cnn.Close();
cnn.Dispose();
}
}
CORRECTION: cmd.Parameters.Add(new MySqlParameter("first_name", MySqlDbType.VarChar));
NOT: cmd.Parameters.AddWithValue("first_name", MySqlDbType.VarChar);
In my case, the FNAME field in the user table cannot be NULL; therefore, checking for NULL values returned in the code is not necessary.
I would guess that the user is not found or the fname is null.
And I really hope you're not querying the database for each user column.
Good luck.
An additional comment.
When trying to return a string value the AddWithValue appears to be trying to convert the output from a string into a number. This results in the string format exception.