Error in C# code - c#

public void ExecStoredProc(string strprocName, SqlConnection sqlConnect, List<string> Paramvalues)
{
if (ConnectToDB() == true)
{
SqlCommand cmd = new SqlCommand(strprocName, sqlConnect);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = strprocName;
SqlParameter parameters = new SqlParameter();
parameters.Value = Paramvalues;
cmd.ExecuteNonQuery();
}
}
This code is giving an error when I am passing the name of the procedure login which has two parameters,user and pwd. Though I am using the list to add parameters but it not not passed to the SP. Showing error in the line cmd.ExecuteNonQuery();

While you are declaring a new SqlParameter object you are not actually associating that object with cmd. Adding the below should help:
cmd.Parameters.Add(parameters)

You have to add sqlparamerter into cmd.Parameters
cmd.Parameters(new SqlParameter("Uid",value));
and no need to write CommandText.

cmd.Parameters.Add( new SqlParameter { ... }).Value = Paramvalues;

Other than the fact that you're not adding the parameter back to the command, you also have a list of strings as your parameter value. Your naming leads me to believe that each item in the list is a parameter. The way your code is at the moment, you're just creating one parameter (with no name).
You want something like this (except we don't know the parameter names):
foreach(string value in ParamValues)
{
cmd.Parameters.AddWithValue(/*ParamName*/, value);
}
If this is not the case and you want to pass the list of strings as a value for a single parameter then this question is more complicated and you need to clarify.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Model = ObjectLibrary.Model;
using System.Configuration;
using System.Collections;
using System.Data;
public class Base
{
protected ArrayList Parameter = new ArrayList();
public DataTable FetchData(string spName)
{
//if you want to get it form app config else just hard code here
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
return ConnectToSql(connectionString, spName);
}
protected void ClearParameter()
{
Parameter.Clear();
}
protected void AddParameter(string parameterName, object value)
{
Parameter.Add(new SqlParameter(parameterName,value));
}
private DataTable ConnectToSql(string connection, string spName)
{
System.Data.SqlClient.SqlConnection conn;
conn = new System.Data.SqlClient.SqlConnection();
conn.ConnectionString = connection;
try
{
conn.Open();
SqlCommand sqlCommand = new SqlCommand(spName, conn);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddRange(Parameter.ToArray());
SqlDataAdapter dataAdaptor = new SqlDataAdapter(sqlCommand);
DataTable dt = new DataTable();
dataAdaptor.Fill(dt);
conn.Close();
return dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
}
}
You can use this class

Related

error message in oledbcommand.executenonquery();

I wrote the following program in C#
I have no problem when inserting information in the database
But when deleting information and during debugging, it gets an error on the following
line
cmd.executenonquery();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace _01_AccessTestDB
{
public partial class frmUser : Form
{
public frmUser()
{
InitializeComponent();
}
OleDbConnection con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=TestDB.accdb");
OleDbCommand cmd = new OleDbCommand();
void display()
{
DataSet ds = new DataSet();
OleDbDataAdapter adp = new OleDbDataAdapter();
cmd.CommandType = CommandType.Text;
adp.SelectCommand=new OleDbCommand();
adp.SelectCommand.Connection= con;
adp.SelectCommand.CommandText="select * from TBLUser";
adp.Fill(ds, "TBLUser");
dgvUser.DataSource=ds;
dgvUser.DataMember=("TBLUser");
dgvUser.Columns[0].HeaderText="کد";
dgvUser.Columns[1].HeaderText="نام کاربری";
dgvUser.Columns[2].HeaderText="کلمه عبور";
}
private void frmUser_Load(object sender, EventArgs e)
{
display();
}
private void btnSave_Click(object sender, EventArgs e)
{
cmd.Parameters.Clear();
cmd.Connection = con;
con.Open();
cmd.CommandText="insert into TBLUser(ID,UserN,Pass)values(#a,#b,#c)";
cmd.Parameters.AddWithValue("#a", txtCode.Text);
cmd.Parameters.AddWithValue("#b", txtUser.Text);
cmd.Parameters.AddWithValue("#c", txtPass.Text);
cmd.ExecuteNonQuery();
con.Close();
string message, title;
title="تعریف کاربران";
message="اطلاعات جدید با موفقیت ثبت گردید";
MessageBox.Show(message, title, MessageBoxButtons.OK,
MessageBoxIcon.Information);
txtCode.Clear();
txtUser.Clear();
txtPass.Clear();
display();
}
The program is running correctly so far, but it encountered a problem in the data deletion section
private void btnDelet_Click(object sender, EventArgs e)
{
int h = Convert.ToInt32(dgvUser.SelectedCells[0].Value);
cmd.Parameters.Clear();
cmd.Connection=con;
cmd.CommandText="delet from TBLUser Where ID=#N";
cmd.Parameters.AddWithValue("#N", h);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
string message, title;
title="تعریف کاربران";
message="اطلاعات حذف گردید";
MessageBox.Show(message, title, MessageBoxButtons.OK,
MessageBoxIcon.Information);
display();
}
}
}
Change from
cmd.CommandText="delet from TBLUser Where ID=#N";
To
cmd.CommandText="delete from TBLUser Where ID=#N";
Also follow #user18387401 recommendations
In regards to cmd.Parameters.AddWithValue, use cmd.Parameters.Add instead.
Edit
Here is a model to use for removing a record use SQL-Server in .NET Core. Since you are using Access the connection and command change to OleDb. So don't copy-n-paste this code, adapt to your current code. The Remove method should reside in a separate class but can reside in the form.
Best to add in a BindingSource, this way cast someBindingSource.Current to whatever the current row in the DataGridView is e.g. if the source is a DataTable use ((DataRow)someBindingSource.Current).Row.Field... to get the primary key to use for deleting. Once the record is removed use someBindingSource.RemoveCurrent() to remove the record from your DataGridView.
public static (bool success, Exception exception) Remove(int identifier)
{
using var cn = new SqlConnection("TODO");
using var cmd = new SqlCommand
{
Connection = cn,
CommandText = "DELETE FROM TBLUser WHERE Id = #Identifier;"
};
try
{
cn.Open();
cmd.Parameters.Add("#Identifier", SqlDbType.Int).Value = identifier;
cmd.ExecuteNonQuery();
return (true, null);
}
catch (Exception localException)
{
return (false, localException);
}
}
Usage in your form (DataOperations is a separate class)
var (success, exception) = DataOperations.Remove(identifier);
if (success)
{
// record removed
}
else
{
// deal with exception using exception variable
}

Assign value from stored procedure to a variable

I'm using stored procedure to get the 'password' value from the database. and i need to assign this value to a variable. I'm using asp.net- mvc and Ado.net.
Here is my stored procedure.
CREATE PROCEDURE [dbo].[getPassword]
(
#Email VARCHAR(100)
)
AS
BEGIN
SELECT Password FROM dbo.Staff_Login WHERE Email=#Email
END
Here is my repository class.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
namespace Job_Recuitment_System.Repository
{
public class LoginRepository
{
private SqlConnection con;
//To handle sql connection
private void connection() {
string constr = ConfigurationManager.ConnectionStrings["mycon"].ToString();
con = new SqlConnection(constr);
}
//to get the password
public List<StaffLogin> getPassword(StaffLogin obj) {
connection();
List<StaffLogin> pword = new List<StaffLogin>();
SqlCommand com = new SqlCommand("getPassword", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#Email",obj.Email);
SqlDataAdapter da = new SqlDataAdapter(com);
DataTable dt = new DataTable();
con.Open();
da.Fill(dt);
con.Close();
//Bind StaffLogin
pword = (from DataRow dr in dt.Rows
select new StaffLogin()
{
Password = Convert.ToString(dr["Password"]),
}).ToList();
return pword;
}
}
}
I have use a list. But i need to assign value to a varible. because i only i need is one value (password).
You don't need an SqlDataAdapter but you just use the SqlCommand.ExecuteScalar
connection();
SqlCommand com = new SqlCommand("getPassword", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add("#Email",SqlDbType.NVarChar, 100). Value = obj.Email;
con.Open();
var result = com.ExecuteScalar();
if(result != null)
MessageBox.Show("Password = " + result.ToString();
con.Close();
ExecuteScalar returns the first column of the first row retrieved by the command and your query fits nicely this condition. However it is important to consider that ExecuteScalar could return NULL if the query doesn't produce any result so always test the result against a null value before using it.
On another matter I really suggest you to avoid stored procedures for these simple menial tasks unless there is a good reason to use them. Using the Add instead of AddWithValue and specifying the exact size of the parameter gives to the Sql optimizer enough hints to create an optimized query.
Finally, remember that storing/returning passwords in clear text is considered a very big security risk. Try to use a safer method as explained in this question: Best way to store passwords in a database
In this case you are retrieving the value of a single column, You can use ExecuteScalar() in such situations. Then the command execution will be like the following:
string passwordStr= (string)com.ExecuteScalar();
So the signature of the getPassword method will also be changed, its return type will become string instead for List<StaffLogin>; the new signature will be:
public string getPassword(StaffLogin obj)
{
connection();
string passwordStr = String.Empty;
using (SqlCommand com = new SqlCommand("getPassword", con))
{
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#Email", obj.Email);
passwordStr = (string)com.ExecuteScalar();
}
return passwordStr;
}

Is it safe to use static methods for accessing database in following scenario

I am upgrading a asp website to asp.net. I am trying to follow multi teir approach.
My basic dal layer is as follows which returns a datatable and insert a given query.
using System;
using System.Configuration;
using System.Data;
using MySql.Data.MySqlClient;
public class mydatautility
{
public mydatautility()
{
}
public static DataTable Table(string query)
{
string constr = ConfigurationManager.ConnectionStrings["db_con"].ConnectionString;
DataTable table = new DataTable();
try
{
using (MySqlConnection con = new MySqlConnection(constr))
{
con.Close();
MySqlCommand com = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(com);
con.Open();
da.Fill(table);
con.Close();
da = null;
com = null;
con.Dispose();
}
}
catch (Exception)
{
}
return table;
}
public static int Insert_intoemployee(string query)
{
string constr = ConfigurationManager.ConnectionStrings["db_con"].ConnectionString;
int done = 0;
try
{
using (MySqlConnection con = new MySqlConnection(constr))
{
MySqlCommand com = new MySqlCommand(query, con);
con.Open();
done = com.ExecuteNonQuery();
con.Close();
com = null;
con.Dispose();
}
}
catch (Exception)
{
}
return done;
}
}
I am not sure what will happen when 2 concurrent queries are run.How can I test it for concurrency problem?
There will no concurrency problem as each request has its own thread and static methods have individual call stacks for each thread. However, there are some suggestions in code.
using System;
using System.Configuration;
using System.Data;
using MySql.Data.MySqlClient;
public static class mydatautility//change to Utilities
{
public mydatautility()//not required in this scenario
{
}
public static DataTable Table(string query) //change method name to GetTable
{
string constr = ConfigurationManager.ConnectionStrings["db_con"].ConnectionString;
DataTable table = new DataTable();
try
{
using (MySqlConnection con = new MySqlConnection(constr))
{
con.Close();//not required
using(MySqlCommand com = new MySqlCommand(query, con))
{
MySqlDataAdapter da = new MySqlDataAdapter(com);
con.Open();
da.Fill(table);
con.Close();
da = null;// reduntant, not required
com = null;// reduntant, not required
con.Dispose();// reduntant, not required
}
}
}
catch (Exception)
{
}
return table;
}
public static bool InsertEmployee(string query)// consider changing int to bool since you only require result of operation
{
string constr = ConfigurationManager.ConnectionStrings["db_con"].ConnectionString;
int done = 0;
try
{
using (MySqlConnection con = new MySqlConnection(constr))
{
Using(MySqlCommand com = new MySqlCommand(query, con))
{
con.Open();
done = com.ExecuteNonQuery();
con.Close();
com = null;// reduntant, not required
con.Dispose();// reduntant, not required
}
}
}
catch (Exception)
{
}
return done > 0; // checks rows affected greater than 0
}
}
Using static methods in this scenario is safe. The variables inside the static method is isolated from concurrent calls! see this link too: variable in static methods inside static class
I think it is safe, but bad practice. If you use static methods to access live resource, then how do you want to unit test them? You can not really mock the database access any more.

c sharp return object from function

im facing a problem , when i creat my own class i want to create Mysql connection function and i want to use it inside all my forms i do this
program.cs
using MySql.Data.MySqlClient;
using MySql.Data.Types;
using System.Xml;
using System.IO;
public class testing
{
public string fahadt="Hello Class";
public void conncting()
{
MySqlConnection connection;
string cs = #"server=localhost;userid=root;password=;database=taxi";
connection = new MySqlConnection(cs);
try
{
connection.Open();
}
catch (MySqlException ex)
{
// MessageBox.Show(ex.ToString());
}
}
}
and in my form
private void button7_Click(object sender, EventArgs e)
{
testing fahad = new testing();
try
{
dataGridView1.Show();
fahad.conncting();
// here is error under fahad.conncting.createcommand();
MySqlCommand cmd = fahad.conncting.CreateCommand();
//cmd.CommandText = "SELECT * FROM ocms_visitors WHERE `id`='"+textBox4.Text+"'";
// MySqlDataAdapter adap = new MySqlDataAdapter(cmd);
//textBox4.Text = adap.id;
// DataSet ds = new DataSet();
// adap.Fill(ds);
// dataGridView1.DataSource = ds.Tables[0].DefaultView;
//MessageBox.Show("Yes Mysql Connection is Working Now !");
}
catch (Exception)
{
throw;
}
}
i dont know how i can do it im very new = C#
please help me and also i have another q should i use
using .... in class and form or Enough in class ?
thanks
You need to return MySqlConnection
Modify your function to:
public MySqlConnection conncting()
{
MySqlConnection connection;
string cs = #"server=localhost;userid=root;password=;database=taxi";
connection = new MySqlConnection(cs);
try
{
connection.Open();
return connection;
}
catch (MySqlException ex)
{
return null;
// MessageBox.Show(ex.ToString());
}
}
To answer your initial question, it looks to me like you have already created the connection you were looking for. Next steps for you would be to learn about the SqlCommand Class.
For reference/edification, try this link, and happy coding!
I suspect you want to return a connection from your conncting() method?
public MySqlConnection conncting()
{
string cs = #"server=localhost;userid=root;password=;database=taxi";
MySqlConnection connection = new MySqlConnection(cs);
connection.Open();
return connection;
}
To answer your second question, yes, using using {..} blocks is a good idea for IDisposable instances whenever possible. This includes connections, commands, data adapters, etc. The following might be a reasonable pattern:
using (MySqlConnection conn = fahad.conncting())
using (MySqlCommand cmd = new MySqlCommand("select * from table", conn))
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
using (DataTable dt = new DataTable())
{
da.Fill(dt);
// do something with datatable
}

How to create sql connection with c# code behind, access the sql server then conditionally redirect?

This is a question from an experienced beginner!
Using ASP.NET 4 C# AND SQL server,
I have a connection string in web.config to myDatabase named "myCS".
I have a database named myDB.
I have a table named myTable with a primary key named myPK
What are the NECESSARY lines of code behind (minimal code) to create a SQL connection, then select from myTable where myPK=="simpleText"
it will probably include:
sqlconnection conn = new sqlconnection(??? myCS)
string SQLcommand = select * from myDB.myTable where myPK==myTestString;
sqlCommand command = new SqlCommand(SQL,conn);
conn.Open();
booleanFlag = ????
conn.Close();
conn.Dispose();
then
If ( theAnswer != NULL ) // or (if flag)
{
Response.Redirect("Page1.aspx");
}
else
{
Response.Redirect("Page2.aspx");
}
Here is a limited simple tutorial:
First, you want to have a class to do the hard work for you, then you will use it with ease.
First, you have to crate the connection string in your web.config file and name it.
Here it is named DatabaseConnectionString, but you may named it myCS as required in the question.
Now, in App_Code create a new class file and name it SqlComm (this is just an example name) like:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
public class SqlComm
{
// this is a shortcut for your connection string
static string DatabaseConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConStr"].ConnectionString;
// this is for just executing sql command with no value to return
public static void SqlExecute(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
}
// with this you will be able to return a value
public static object SqlReturn(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
object result = (object)cmd.ExecuteScalar();
return result;
}
}
// with this you can retrieve an entire table or part of it
public static DataTable SqlDataTable(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
DataTable TempTable = new DataTable();
TempTable.Load(cmd.ExecuteReader());
return TempTable;
}
}
// sooner or later you will probably use stored procedures.
// you can use this in order to execute a stored procedure with 1 parameter
// it will work for returning a value or just executing with no returns
public static object SqlStoredProcedure1Param(string StoredProcedure, string PrmName1, object Param1)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(StoredProcedure, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(PrmName1, Param1.ToString()));
cmd.Connection.Open();
object obj = new object();
obj = cmd.ExecuteScalar();
return obj;
}
}
}
Okay, this only a class, and now you should know how to use it:
If you wish to execute a command like delete, insert, update etc. use this:
SqlComm.SqlExecute("TRUNCATE TABLE Table1");
but if you need to retrieve a specific value from the database use this:
int myRequiredScalar = 0;
object obj = new object();
obj = SqlComm.SqlReturn("SELECT TOP 1 Col1 FROM Table1");
if (obj != null) myRequiredScalar = (int)obj;
You can retrieve a bunch of rows from the database this way (others like other ways)
This is relevant to your sepecific question
int Col1Value = 0;
DataTable dt = new DataTable();
dt = SqlComm.SqlDataTable("SELECT * FROM myTable WHERE myPK='simpleText'");
if (dt.Rows.Count == 0)
{
// do something if the query return no rows
// you may insert the relevant redirection you asked for
}
else
{
// Get the value of Col1 in the 3rd row (0 is the first row)
Col1Value = (int)dt.Rows[2]["Col1"];
// or just make the other redirection from your question
}
If you need to execute a stored procedure with or without returning a value back this is the way to do that (in this example there are no returning value)
SqlComm.SqlStoredProcedure1Param("TheStoredProcedureName", "TheParameterName", TheParameterValue);
Again, for your specific question return the table using the SqlDataTable , and redirect if dt.Rows.Count >0
Have fun.
There are many ways: LINQ, SqlDataReader, SQLDataAdapter, according to what you want to read (single value, datatable ...), so here is an example:
using (SqlConnection con = new SqlConnection("SomeConnectionString"))
{
var cmd = new SqlCommand("select from myTable where myPK==N'"+ simpleText+ "'",con);
cmd.Connection.Open();
var sqlReader = cmd.ExecuteReader();
while(sqlReader.Read())
{
//Fill some data like : string result = sqlReader("SomeFieldName");
}
sqlReader.Close();
cmd.Connection.Close();
cmd.Dispose();
}

Categories