SQLCommand throw new NotImplementedException(); - c#

Hi i am trying to store the value of a group of textboxes into a sql database, I have created the database and written the sql script. I have created the connection to sql database from my project when the script runs i get the error
An unhandled exception of type 'System.NotImplementedException' occurred in >PLUPROG.exe
Additional information: The method or operation is not implemented.
Casued by.
public static implicit operator SqlCommand(Sqlcommand v)
{
throw new NotImplementedException();
}
The code for my SQL script is
private void btnAddPlu_Click(object sender, EventArgs e)
{
using (SqlConnection sqlConn = new SqlConnection("Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = PluProg; Integrated Security = True"))
{
string query = "INSERT INTO Departments VALUES (#Name, #Type, #SubDept)";
SqlCommand cmd = new Sqlcommand(query, sqlConn);
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 50).Value = cbDeptName.Text;
cmd.Parameters.Add("#Type", SqlDbType.NVarChar, 50).Value = cbDeptType.Text;
cmd.Parameters.Add("#SubDept", SqlDbType.NVarChar, 50).Value = cbSubDept.Text;
cmd.Connection.Open();
try
{
cmd.ExecuteNonQuery();
}
catch ()

I really don't know what you're asking, but I feel bad that you've asked twice and clearly haven't figured out anything. Take a look at this and see if something answers your question. The following is not optimized/generalized - just basic stuff for you to see what's what and improve on in your own way.
public SqlConnection getConn()
{
return new SqlConnection(getConnString());
}
public string getConnString()
{
return #"Data Source=lily.arvixe.com;Initial Catalog=WM_Crawler;Persist Security Info=True;User ID={myUser};Password={MyPass};Connection Timeout=7000";
}
//This is how you flush a DataTable
public void saveDataTable(string tableName, DataTable table)
{
using (SqlConnection conn = getConn())
{
conn.Open();
using (var bulkCopy = new SqlBulkCopy(conn))//, SqlBulkCopyOptions.KeepIdentity))
{
// my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings
foreach (DataColumn col in table.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, "["+col.ColumnName+"]");
}
bulkCopy.BulkCopyTimeout = 8000;
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = 10000;
bulkCopy.EnableStreaming = true;
//bulkCopy.SqlRowsCopied += BulkCopy_SqlRowsCopied;
//bulkCopy.NotifyAfter = 10000;
bulkCopy.WriteToServer(table);
}
conn.Close();
}
}
//this is how you select one field from one row
public object scalar(string sql)
{
object ret;
using (SqlConnection conn = getConn())
{
conn.Open();
using (SqlCommand com = conn.CreateCommand())
{
com.CommandText = sql;
ret = com.ExecuteScalar();
}
conn.Close();
}
return ret;
}
//this is how you execute a command using SQL string (admin functions)
public void nonQuery(string sql)
{
using(SqlConnection conn = getConn())
{
conn.Open();
using(SqlCommand com = conn.CreateCommand())
{
com.CommandText = sql;
com.CommandTimeout = 5900;
com.ExecuteNonQuery();
}
conn.Close();
}
}
// This is how you execute a query using a predefined, parameterized command (user input)
public void nonQuery_With_Command(SqlCommand com)
{
using (SqlConnection conn = getConn())
{
conn.Open();
using (com)
{
com.Connection = conn;
com.ExecuteNonQuery();
}
conn.Close();
}
}
//this is how you execute several commands under one connection (sql or stored procedure)
public void nonQuery_List_Command(List<SqlCommand> comList)
{
using (SqlConnection conn = getConn())
{
conn.Open();
foreach (SqlCommand com in comList)
{
using (com)
{
com.Connection = conn;
try
{
com.ExecuteNonQuery();
}
catch(Exception n1)
{
Console.WriteLine(n1.Message);
Console.WriteLine(com.Parameters[1].Value.ToString());
}
}
}
conn.Close();
}
}
//This returns column names from a specific table (example of a datareader)
private List<string> get_Column_Names(string tableName)
{
List<string> ret = new List<string>();
using (SqlConnection conn = getConn())
{
conn.Open();
using(SqlCommand com = conn.CreateCommand())
{
com.CommandText = "select column_Name from INFORMATION_SCHEMA.COLUMNS where table_Name = '" + tableName + "'";
com.CommandTimeout = 600;
SqlDataReader read = com.ExecuteReader();
while (read.Read())
{
ret.Add(Convert.ToString(read[0]));
}
}
conn.Close();
}
return ret;
}
//This converts a reader to a class using fields. It is not optimized and is inefficient, but allows you to see what's happening. Yu can optimize it yourself
public static object[] sql_Reader_To_Type(Type t, SqlDataReader r)
{
List<object> ret = new List<object>();
while (r.Read())
{
FieldInfo[] f = t.GetFields();
object o = Activator.CreateInstance(t);
for (int i = 0; i < f.Length; i++)
{
string thisType = f[i].FieldType.ToString();
switch (thisType)
{
case "System.String":
f[i].SetValue(o, Convert.ToString(r[f[i].Name]));
break;
case "System.Int16":
f[i].SetValue(o, Convert.ToInt16(r[f[i].Name]));
break;
case "System.Int32":
f[i].SetValue(o, Convert.ToInt32(r[f[i].Name]));
break;
case "System.Int64":
f[i].SetValue(o, Convert.ToInt64(r[f[i].Name]));
break;
case "System.Double":
double th;
if (r[f[i].Name].GetType() == typeof(DBNull))
{
th = 0;
}
else
{
th = Convert.ToDouble(r[f[i].Name]);
}
}
try { f[i].SetValue(o, th); }
catch (Exception e1)
{
throw new Exception("can't convert " + f[i].Name + " to double - value =" + th);
}
break;
case "System.Boolean":
f[i].SetValue(o, Convert.ToInt32(r[f[i].Name]) == 1 ? true : false);
break;
case "System.DateTime":
f[i].SetValue(o, Convert.ToDateTime(r[f[i].Name]));
break;
default:
throw new Exception("Missed data type in sql select ");
}
}
ret.Add(o);
}
return ret.ToArray();
}
//these are basic (rudimentary) ways of converting class to DataTable
public static DataTable create_DataTable_From_Generic_Class(Type t)
{
DataTable d = new DataTable();
PropertyInfo[] pI = t.GetProperties();
for (int i = 0; i < pI.Length; i++)
{
DataColumn dC = new DataColumn(pI[i].Name, pI[i].PropertyType);
d.Columns.Add(dC);
}
return d;
}
public static object[] Create_Datatable_Row_From_Generic_Class(Type t, object instance, DataTable dt)
{
PropertyInfo[] p = t.GetProperties();
object[] ret = new object[dt.Columns.Count];
for (int i = 0; i < dt.Columns.Count; i++)
{
var temp = t.GetProperty(dt.Columns[i].ColumnName);
ret[i] = temp.GetValue(instance);
}
return ret;
}

Related

C# MySQL query result Visual Studio

public ArrayList P2a(string sql)
{
ArrayList result = new ArrayList();
MySqlCommand cmd = new MySqlCommand();
MySqlConnection mysqlconnection = new MySqlConnection(xxx);
cmd.Connection = mysqlconnection;
cmd.CommandText = sql;
try
{
cmd.Connection.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Dictionary<string, object> dict = new Dictionary<string, object>();
for (int count = 0; (count <= (reader.FieldCount - 1)); count++)
{
dict.Add(reader.GetName(count), reader[count]);
}
result.Add(dict);
}
return result;
} catch {
return result;
} finally {
cmd.Connection.Close();
}
}
C# Visual Studio 2017 MySQL void return echo problem.
I want to make sure that I print out the result properly.
Example:
ArrayList query = P2a("select id,site,comment from sites");
MessageBox.Show(query[0]["site"].toString());
To use it this way.
Can you make the necessary corrections in the function?
I recommend as a start to change your catch block.
You should be throwing the exception, ideally with more information.
I also recommend that you have an optional list of MySqlParameters (defaults to null), while its not obvious here, since there are no parameters, more than likely you have SQL that is suspectible to SQL injection. In most cases, if you have a where block and its not null, you have done something incorrectly.
Your code does not cleanup the disposable objects, so using will take care of that.
Use generics instead as the list item will now be a dictionary.
public List<Dictionary<String, object>> P2a(string sql, MySqlParameter[] parameters)
{
List<Dictionary<String, object>> result = new List<Dictionary<String, object>>();
using (MySqlCommand cmd = new MySqlCommand())
{
using (MySqlConnection mysqlconnection = new MySqlConnection(xxx))
{
cmd.Connection = mysqlconnection;
cmd.CommandText = sql;
if (parameters != null)
{
foreach (MySqlParameter p in parameters)
{
cmd.Parameters.Add(p);
}
}
try
{
cmd.Connection.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Dictionary<string, object> dict = new Dictionary<string, object>();
for (int count = 0; (count <= (reader.FieldCount - 1)); count++)
{
dict.Add(reader.GetName(count), reader[count]);
}
result.Add(dict);
}
}
return result;
}
catch (ApplicationException ex)
{
throw new ApplicationException("Error Executing " + sql, ex);
}
finally
{
cmd.Connection.Close();
}
}
}
}
I solved the problem myself
I wrote a new function
public DataTable query(string sql) {
DataTable table = new DataTable();
MySqlConnection connection = null;
MySqlDataReader reader = null;
try {
connection = new MySqlConnection(xxx);
connection.Open();
MySqlDataAdapter dataAdapter = new MySqlDataAdapter();
dataAdapter.SelectCommand = new MySqlCommand(sql, connection);
dataAdapter.Fill(table);
return table;
} catch {
return table;
} finally {
if (reader != null)
reader.Close();
if (connection != null)
connection.Close();
}}
use off
DataTable list = query("select * from tablename");
MessageBox.Show(list.Rows["rowsname"]["cellname"].ToString());

Using Prepare select statements in C#

I am having the below code where I am querying the MySQL database. I need to replace my select query to prepare statement
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
for (int i = 0; i < EmpList.Count; i++)
{
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr))
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
cmd.Parameters.Add("#Grp", MySqlDbType.VarChar).Value = Grp;
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = EmpList[i].Name;
conn.Open();
var reader = cmd.ExecuteReader();
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
conn.Close();
}
}
}
This code works perfectly. But for improvement I need to use the prepare statements instead of the query I am using. Because I am having similar kinds of various validation in my code, I am not sure how to reuse the parameters effectively.
You are very close. Just call cmd.Prepare(), keep references to the parameters, and reuse the command:
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr)) {
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
var prmGrp = cmd.Parameters.Add("#Grp", MySqlDbType.VarChar);
var prmName = cmd.Parameters.Add("#Name", MySqlDbType.VarChar);
cmd.Prepare();
for (int i = 0; i < EmpList.Count; i++)
{
prmGrp.Value = Grp;
prmName.Value = EmpList[i].Name;
using (var reader = cmd.ExecuteReader()) {
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
}
}
}
conn.Close();
}
}

How to use SqlCommand and SqlDataReader to return a Json result in C#

I'm trying to use a SQL query in SqlCommand and I'd like to see the complete result set that is returned from SQL Server database, and return Json format after that.
So here is the code in controller:
public ActionResult GetAllSummary()
{
string connectionString ="Data Source=...;Initial Catalog=...;Integrated Security=True";
string query = "SELECT v.date, v.name, v.numbers FROM view as v GROUP BY v.date,v.mane,v.numbers ORDER BY v.date,v.mane,v.numbers";
using(SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, conn);
try {
conn.Open();
SqlDataReader reader = command.ExecuteReader();
// In this part below, I want the SqlDataReader to
// read all of the records from database returned,
// and I want the result to be returned as Array or
// Json type, but I don't know how to write this part.
while(reader.Read())
{
ArrayList result = new ArrayList();
foreach(int i in reader)
// this line below was the code I wrote before.
// But since my query returns multiple
// types (datetime, string, decimal, etc..),
// I don't know what C# command I can use to return
// the results in foreach loop. Or say I even don't
// need a for/foreach loop.
result.Add(reader.GetValue(i));
return Json(result, JsonRequestBehavior.AllowGet);
}
reader.Close();
}
catch(Exception ex)
{
var error = ex.Message;
return View(error);
}
}
return View();
}
Anyone can help me to make this work? I will be greatly appreciated.
Kevin
public class data {
public DateTime date {get;set;}
public string name {get;set;}
public int numbers {get;set;}
}
public ActionResult GetAllSummary()
{
string connectionString ="Data Source=...;Initial Catalog=...;Integrated Security=True";
string query = "SELECT DISTINCT v.date, v.name, v.numbers FROM view as v ORDER BY v.date,v.name,v.numbers";
using(SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, conn);
try {
conn.Open();
SqlDataReader reader = command.ExecuteReader();
// In this part below, I want the SqlDataReader to
// read all of the records from database returned,
// and I want the result to be returned as Array or
// Json type, but I don't know how to write this part.
while(reader.Read())
{
List<data> result = new List<data>();
var d=new data();
d.date=reader[0]; // Probably needs fixing
d.name=reader[1]; // Probably needs fixing
d.numbers=reader[2]; // Probably needs fixing
result.Add(data);
}
reader.Close();
return Json(result, JsonRequestBehavior.AllowGet);
}
catch(Exception ex)
{
var error = ex.Message;
return View(error);
}
}
return View();
}
or
public class data {
public DateTime date {get;set;}
public string name {get;set;}
public int numbers {get;set;}
}
public ActionResult GetAllSummary()
{
string connectionString ="Data Source=...;Initial Catalog=...;Integrated Security=True";
string query = "SELECT DISTINCT v.date, v.name, v.numbers FROM view as v ORDER BY v.date,v.name,v.numbers";
using(SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, conn);
try {
conn.Open();
SqlDataReader reader = command.ExecuteReader();
var dt=new DataTable();
dt.Load(myDataReader);
List<DataRow> result=dt.AsEnumerable().ToList();
reader.Close();
return Json(result, JsonRequestBehavior.AllowGet);
}
catch(Exception ex)
{
var error = ex.Message;
return View(error);
}
}
return View();
}
or (just the interesting part):
var dt=new DataTable();
dt.Load(myDataReader);
object[] result = new object[dt.Rows.Count + 1];
for (int i = 0; i <= dt.Rows.Count - 1; i++) {
result[i] = dt.Rows[i].ItemArray;
}
You can use this extension:
public static string ExecuteToJson(this SqlCommand cmd)
{
if (cmd.Connection.State == ConnectionState.Closed)
{
cmd.Connection.Open();
}
using (DataTable dt = new DataTable())
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row;
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
rows.Add(row);
}
return JsonConvert.SerializeObject(rows);
}
}
}
and the usage:
string connectionString = "** connstr **";
string query = "SELECT * FROM `table`";
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, conn))
{
string json = command.ExecuteToJson();
}
}
}
catch (Exception)
{
}

Provider & query

I want to create a C # application that can create and populate a DataTable.
Here is my code:
public DataTable GetData(string query)
{
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OracleClient");
using (DbConnection conn = factory.CreateConnection())
{
try
{
DbConnectionStringBuilder csb = factory.CreateConnectionStringBuilder();
csb["Data Source"] = #"";
csb["User Id"] = #"";
csb["Password"] = #"";
conn.ConnectionString = csb.ConnectionString;
conn.Open();
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = query;
using (DataTable dt = new DataTable())
{
DbDataAdapter da = factory.CreateDataAdapter();
cmd.CommandType = CommandType.Text;
da.SelectCommand = cmd;
da.Fill(dt);
return dt;
}
}
}
catch (Exception ex)
{
throw new Exception("Error", ex);
}
finally
{
if (conn.State != ConnectionState.Closed)
conn.Close();
}
}
}
In a second time, I have a class containing my various queries.
public class Query
{
public string SQL;
public string query1()
{
this.SQL = "select * from table1"
return this.SQL;
}
public string query2(string param)
{
this.SQL = "select * from table1 where id = '" + param + "' ";
return this.SQL;
}
I wish I could go query1 and / or query2 as parameter of my method GetData.
public DataTable GetData(query1)
{
//...
}
But I do not know how!
Thank you in advance for your help!

Quick insert from C# CLR

I am working on a huge set of data, and using CLR for processing it. The CLR processing is working quick, but I need a quick way to move the processed data to the database(through CLR).
For example, see the following clr code
protected static string Normalize(string s) // space and special character remover
{
char[] arr = s.ToCharArray();
arr = Array.FindAll<char>(arr, (c => char.IsLetterOrDigit(c)));
return new string(arr).ToLower();
}
[Microsoft.SqlServer.Server.SqlProcedure]
public static void udpNormStr ()
{
SqlConnection con = new SqlConnection("context connection = true");
SqlCommand cmd = new SqlCommand("Select cName from NamesTable", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
DataTable fill = new DataTable();
fill.Columns.Add("NormName", typeof(string));
da.Fill(dt);
cmd.CommandText = "insert into NormTable values (#nName)";
cmd.Parameters.Add("#nName", SqlDbType.VarChar);
foreach (DataRow row in dt.Rows)
{
fill.Rows.Add(Normalize(row[0].ToString()));
}
con.Open();
foreach (DataRow row in fill.Rows)
{
cmd.Parameters["#nName"].Value = row[0];
cmd.ExecuteNonQuery();
}
con.Close();
}
It is taking lot of time to execute, and is wasting 90% of that time in the insert operations.
Please suggest a better way of moving processed data to database(through CLR).
SqlBulkCopy; since you have a DataTable already, you can use:
using (var bcp = new SqlBulkCopy(con))
{
bcp.DestinationTableName = "NormTable";
bcp.WriteToServer(dt);
}
Note that for streaming data, you can also create a custom IDataReader implementation and feed that to WriteToServer.
Wrap your connection with a SqlTransaction to avoid implicit transactions.
con = new SqlConnection("context connection=true");
con.Open();
using (con)
{
using (var sqlTrans = con.BeginTransaction()) //one transaction instead of many from each insert implicit
{
const string cmdText = #"INSERT INTO [table1] ([a],[b],[c],[d],[e]) VALUES (#a,#b,#c,#d,#e)";
using (var cmd = new SqlCommand(cmdText, con, sqlTrans))
{
var aField = cmd.Parameters.Add("#a", SqlDbType.NVarChar, 255);
var bField = cmd.Parameters.Add("#b", SqlDbType.Int);
var cField = cmd.Parameters.Add("#c", SqlDbType.Bit);
var dField = cmd.Parameters.Add("#d", SqlDbType.NVarChar, 255);
var eField = cmd.Parameters.Add("#e", SqlDbType.Int);
//same for all
cField.Value = false;
dField.Value = "d";
eField.Value = 1;
foreach (var someValue in valueCollection)
{
aField.Value = someValue.Key;
bField.Value = someValue.Value;
cmd.ExecuteNonQuery();
}
}
sqlTrans.Commit();
}
con.Close();
}
If this work is SQL/CLR, then that is tricky. One idea might be to make that method only return the data, for example as a CLR Table-Valued Function, and then do the INSERT back in TSQL pulling from the table-valued function.
Try to use SQLBulkCopy Class
this is sample method to Inset DataTable to Database in one Shot
public static bool SaveDetails(DataTable dbTable)
{
try
{
SqlConnection conn = new SqlConnection("Data Source=akshay;Initial Catalog=CosmosDB;User Id=sa;Password=Nttdata123");
conn.Open();
SqlBulkCopy sbc = new SqlBulkCopy(conn);
if (dbTable.Rows.Count > 0)
{
sbc.DestinationTableName = "Employee";
sbc.WriteToServer(dbTable);
}
sbc.Close();
conn.Close();
return true;
}
catch (Exception exp)
{
return false;
}
}

Categories

Resources