I am new to .net and written the code to validate userid and password using sql stored procedure and code is below:
using System;
using System.Data;
using System.Data.SqlClient;
namespace *********
{
public static class DBHelper
{
public static bool ValidateUser(string userID, string password)
{
bool isCustomerExists = false;
string constr = "Data Source = ****-PC\\SQLEXPRESS; Initial Catalog = *******; Integrated Security = True";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Validate_User"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#UserId", userID);
cmd.Parameters.AddWithValue("#Password", password);
cmd.Connection = con;
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
if (reader["UserID"] != DBNull.Value)
{
isCustomerExists = true;
}
}
con.Close();
}
}
return isCustomerExists;
}
internal static bool AddNewCustomer(Customer customer)
{
bool isCustomerCreated = false;
try
{
string constr = "Data Source = *****-PC\\SQLEXPRESS; Initial Catalog = *****; Integrated Security = True";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("InserNewCustomer"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PFirstName", customer.FirstName);
cmd.Parameters.AddWithValue("#PLastName", customer.LastName);
cmd.Parameters.AddWithValue("#PLoginID", customer.LoginID);
cmd.Parameters.AddWithValue("#PCustomerPassword", customer.CustomerPassword);
cmd.Parameters.AddWithValue("#PConfirmCustomerPassword", customer.ConfirmCustomerPassword);
cmd.Parameters.AddWithValue("#PBirthday", customer.Birthday);
cmd.Parameters.AddWithValue("#PCustomerAddress", customer.CustomerAddress);
cmd.Connection = con;
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.RecordsAffected == 1)
{
isCustomerCreated = true;
}
con.Close();
}
}
}
catch (Exception ex)
{
isCustomerCreated = false;
}
return isCustomerCreated;
}
}
}
I want use the above code in MFC application project. Can anyone help me please. Thanks in advance.
It is a late reply but it may be useful for people learning mfc DB Connection.
Recently i got chance to Learn MFC and SQL Server Stored Procedure, i checked for many solutions and found this one i am sharing with you, Hope it will help.
I am Using VS2012 and SQL Server 2008.
I used your code data and tried to replicate your scenario.
Create Stored Procedures Accordingly in SQL.
bool ClassName::ValidateUser(string userID, string password)
{
bool isCustomerExists = false;
CDatabase database;
CString strConn;
strConn = L"Data Source = ****-PC\\SQLEXPRESS; Initial Catalog = *******; Integrated Security = True";
// your connection string, i was using ODBC Data source.
TRY
{
database.Open(NULL,0,0,strConn);
CRecordset recordset(&database);
CString strQuery;
strQuery.Format(L"{CALL Validate_User('%s','%s')}",userID,password);
recordset.Open(CRecordset::forwardOnly,strQuery,CRecordset::readOnly);
if(!recordset.IsBOF())
{
isCustomerExists = true;
}
recordset.Close();
database.Close();
}
CATCH(CDBException,e)
{
MessageBox(L"Exception: "+e->m_strError);
}
END_CATCH;
return isCustomerExists;
}
bool ClassName::AddNewCustomer(Customer customer)
{
bool isCustomerCreated;
CDatabase database;
CString strConn;
strConn = L"Data Source = ****-PC\\SQLEXPRESS; Initial Catalog = *******; Integrated Security = True";
//your connection string, i was using ODBC Data source.
TRY
{
database.Open(NULL,0,0,strConn);
CRecordset recordset(&database);
CString strQuery;
strQuery.Format(L"{CALL InserNewCustomer('%s','%s','%s','%s','%s','%s','%s')}",customer.FirstName,customer.LastName,customer.LoginID,customer.CustomerPassword,customer.ConfirmCustomerPassword,customer.Birthday,customer.CustomerAddress);
database.ExecuteSQL(strQuery);
isCustomerCreated = true;
database.Close();
}
CATCH(CDBException,e)
{
MessageBox(L"Exception: "+e->m_strError);
isCustomerCreated = false;
}
END_CATCH;
return isCustomerCreated;
}
If you have any doubts, you can ask me, i will try to solve it.
It is real easy to port this code to MFC. Take a look at CDatabase and CRecordset classes. You can also find the following article helpful: http://www.codeguru.com/cpp/data/mfc_database/storedprocedures/article.php/c1167/Calling-Stored-Procedures.htm
_T("{CALL your_sp_name(param list)}" is the only syntax that works for the CRecordset if the sp returns a result set, pay close attention to braces {} and ()
Related
I am trying to connect to database called Symfony while using MySql.Data.MySqlClient. The database is Maria and i can connect to the server it is running on, but once i say "use Symfony" it throws an exception: User access deny. I contacted BD maintenannce and they confirmed the user permission is setup correctly on their side
Once I had a similar problem in java caused by windows authentication. Isnt that the same problem?
class MariaConnector
{
private string connectionString;
private MySqlConnection connection;
private MySqlCommand command;
public MariaConnector(string connectionString)
{
this.connectionString = connectionString;
this.connection = new MySqlConnection();
this.connection.ConnectionString = connectionString;
this.command = this.connection.CreateCommand();
}
public bool EstablishConnection() {
this.connection.Open();
if (this.connection.State.ToString() == "Open"){
return true;
}
else{return false;}
}
public DataTable Query(string query) {
this.command.CommandType = CommandType.Text;
this.command.Connection = connection;
this.command.CommandTimeout = 300;
DataTable table = new DataTable();
this.command.CommandText = "use Symfony";
this.command.ExecuteReader();
this.command.CommandText = query;
table.Load(this.command.ExecuteReader());
this.command.Dispose();
return table;
}
}
I have a combobox on a windows form that I fill with a list of names. At the moment I have the following code inside the Form class and it works fine
// This section opens a connection to the database, selects all the portfolio names that have an "in Use" value of 1, and then
// fills Combo Box 2 with the values.
SqlConnection myConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\Users\Nick\Documents\Investments 4.mdf""; Integrated Security = True; Connect Timeout = 30");
myConnection.Open();
SqlCommand myCommand2 = new SqlCommand();
myCommand2.Connection = myConnection;
myCommand2.CommandText = "SELECT Portfolio_Name FROM Dbo.Name WHERE In_use = 1";
SqlDataReader myReader2 = myCommand2.ExecuteReader();
while (myReader2.Read())
{
comboBox2.Items.Add(myReader2[0]);
}
myConnection.Close();
I would like to be able to extract this into a separate method, and put it into a separate class for general utility methods. However, I'm stuck on a really simple issue. When I put the code into a class, I need to be able to tell it which combox box I want to fill, and I can't figure out how to pass in that information. Sorry if the answer is obvious, but any help would be gratefully received.
Thanks!
Well, if you want to extract, then extract:
// Let's extract a class: it should provide us standard cursors,
// e.g. Protfolio Names
public static class MyData {
// Let's enumerate items returned
public static IEnumerable<string> PortfolioNames() {
// Wrap IDisposable into using
//TODO: move Connection String into a separated method/property
using (SqlConnection con = new SqlConnection(/*connection string here*/)) {
con.Open();
// Make sql readable
//DONE: when presenting something to user, sort it (order by) esp. strings
string sql =
#" select Portfolio_Name
from Dbo.Name
where In_use = 1
order by Portfolio_Name";
// Wrap IDisposable into using
using (SqlCommand q = new SqlCommand(sql, con)) {
// Wrap IDisposable into using
using (var reader = q.ExecuteReader()) {
while (reader.Read())
yield return Convert.ToString(reader[0]);
}
}
}
}
}
And then use
// Adding items in one after one manner is often a bad idea:
// it makes UI repaint each time you add an item and cause blinking.
// Let's fill the ComboBox in one go via AddRange
comboBox2.Items.AddRange(MyData.PortfolioNames().ToArray());
You can use a helper class names Portfolio for data access. The method GetNames does not require a ComboBox instance. This increases the chance that you can reuse the method in another context.
public static class Portfolio
{
public static IList<string> GetNames()
{
SqlConnection myConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\Users\Nick\Documents\Investments 4.mdf""; Integrated Security = True; Connect Timeout = 30");
myConnection.Open();
SqlCommand myCommand2 = new SqlCommand();
myCommand2.Connection = myConnection;
myCommand2.CommandText = "SELECT Portfolio_Name FROM Dbo.Name WHERE In_use = 1";
SqlDataReader myReader2 = myCommand2.ExecuteReader();
var portfolioNames = new List<string>();
while (myReader2.Read())
{
portfolioNames.Add(myReader2[0]);
}
myConnection.Close();
return portfolioNames;
}
}
Then in your Form you can do something like this:
var names = Portfolio.GetNames();
foreach (var name in names)
{
combobox2.Items.Add(name);
}
It is so simple:
public class MyUtility
{
public static void FillComboBox(System.Windows.Forms.ComboBox comboBox)
{
//comboBox.Items.Clear(); //enable this line if required
using (SqlConnection myConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\Users\Nick\Documents\Investments 4.mdf""; Integrated Security = True; Connect Timeout = 30"))
{
myConnection.Open();
using (SqlCommand myCommand2 = new SqlCommand())
{
myCommand2.Connection = myConnection;
myCommand2.CommandText = "SELECT Portfolio_Name FROM Dbo.Name WHERE In_use = 1";
using (SqlDataReader myReader2 = myCommand2.ExecuteReader())
{
while (myReader2.Read())
{
comboBox.Items.Add(myReader2[0]);
}
}
}
//myConnection.Close(); //not required inside using block
}
}
}
you may use other methods to get connection string (e.g. from config file).
The usage is so simple, no extra code required:
MyUtility.FillComboBox(comboBox2);
I am missing something very simple. I have a form with 5 textBox and want to fill them with the data from the SQL Server database. Here is what I have so far:
As I debug this code line by line it returns to the calling block at the connection.open() line.
public void Get_Contact_Info()
{
using (DataAccessClass.sql_Connection)
{
string SQL = "SELECT * FROM Customer_Contacts WHERE Contact_ID = #contact_Id";
SqlCommand sqlCommand = new SqlCommand(SQL, DataAccessClass.sql_Connection);
sqlCommand.Parameters.AddWithValue("#Contact_Id", contact_Id);
sqlCommand.Parameters.AddWithValue("#Contact_Direct_Number", contact_Direct_NumberTextBox);
sqlCommand.Parameters.AddWithValue("#Contact_Cell_Number", contact_Cell_NumberTextBox);
sqlCommand.Parameters.AddWithValue("#Contact_Email", contact_EmailTextBox);
sqlCommand.Parameters.AddWithValue("#Contact_Department", contact_DepartmentTextBox);
DataAccessClass.sql_Connection.Open();
using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
{
while (sqlDataReader.Read())
{
contact_Id = sqlDataReader["Contact_ID"].ToString();
}
DataAccessClass.sql_Connection.Close();
}
}
}
I have been doing a pretty good job of getting info from the user and saving it to the SQL Server DataTable but know I want to get some out so that I can edit the info.
Any help will be gratefully appreciated.
Here is my DataAccessClass
public static class DataAccessClass
{
static SqlConnection sqlConnection = new SqlConnection();
public static SqlConnection sql_Connection
{
get { return sqlConnection; }
}
public static void OpenConnection()
{
string sqlString = Properties.Settings.Default.ConnectionString;
sqlConnection.ConnectionString = sqlString;
sqlConnection.Open();
}
public static void CloseConnection()
{
sqlConnection.Close();
}
}
Here is how I am calling Get_Contact_Info.
private void Customer_Add_Contact_Form_Load(object sender, EventArgs e)
{
this.customer_ContactsBindingSource.AddNew();
if (contact_Id == null)
{
contact_NameTextBox.Select();
}
else
{
Get_Contact_Info();
}
}
From a DataGridView I am selecting a row and passing customer_ID to the Customer_Add_Contact_Form so that I can edit the contact information. Here is the code for this step:
DataGridViewRow row = customer_ContactsDataGridView.CurrentCell.OwningRow;
string contact_ID = row.Cells[0].Value.ToString();
string customer_Ship_ID = null;
using (Form Customer_Add_Contact_Form = new Customer_Add_Contact_Form(customer_Ship_ID, contact_ID))
As discussed here it is better to let connection pooling manage the connections, so you can simplify your code to:
public void Get_Contact_Info()
{
using (var connection = new SqlConnection(roperties.Settings.Default.ConnectionString))
{
connection.Open();
var SQL = "SELECT * FROM Customer_Contacts WHERE Contact_ID = #contact_Id";
var sqlCommand = new SqlCommand(SQL, connection);
sqlCommand.Parameters.AddWithValue("#Contact_Id", contact_Id);
using (var sqlDataReader = sqlCommand.ExecuteReader())
{
while (sqlDataReader.Read())
{
contact_Id = sqlDataReader["Contact_ID"].ToString();
TextBoxName.Text = sqlDataReader["Contact_Name"].ToString();
//etc ...
}
}
}
}
I have removed unused parameters and created a new connection. Possibly you tried to open a connection using .Open() without initializing it with a connections string (is it roperties?)
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.
I am sending some data from windows mobile to webservice. Now i want to write a method in webservice to insert those values into sql database . How to proceed. please help
What you want is a Restful web service. That link is your basic howto.
there is good book called practical database programming with visual c#.NET by ying bai.
//base class
public class SQLInsertBase
{
public bool SQLInsertOK;
public string SQLInsertError;
public string lat;
public string lon;
public string id;
public SQLInsertBase()
{
//
// TODO: Add constructor logic here
//
}
}
[WebMethod]
public SQLInsertBase GetSQLInsertCourse(string id,string lat,string lon)
{
string cmdString = "INSERT into Location values(#id,#latitude,#longitude)";
SqlConnection sqlConnection = new SqlConnection();
SQLInsertBase GetSQLResult = new SQLInsertBase();
SqlDataReader sqlReader;
GetSQLResult.SQLInsertOK = true;
sqlConnection = SQLConn();
if (sqlConnection == null)
{
GetSQLResult.SQLInsertError = "Database connection is failed";
ReportError1(GetSQLResult);
return null;
}
SqlCommand sqlCommand = new SqlCommand(cmdString, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.Parameters.Add("#id", SqlDbType.Text).Value = id;
sqlCommand.Parameters.Add("#latitude", SqlDbType.Text).Value = lat;
sqlCommand.Parameters.Add("#longitude", SqlDbType.Text).Value = lon;
int result = sqlCommand.ExecuteNonQuery();
// if (sqlReader.HasRows == true)
// FillCourseDetail(ref GetSQLResult, sqlReader);
if (result == 0)
{
GetSQLResult.SQLInsertError = "cannot update ";
ReportError1(GetSQLResult);
}
/* else
{
GetSQLResult.SQLInsertError = "No matched found";
ReportError1(GetSQLResult);
}*/
// sqlReader.Close();
sqlConnection.Close();
sqlCommand.Dispose();
return GetSQLResult;
}
protected SqlConnection SQLConn()
{
string cmdString = ConfigurationManager.ConnectionStrings["sql_conn"].ConnectionString;
SqlConnection conn = new SqlConnection();
conn.ConnectionString = cmdString;
conn.Open();
if (conn.State != System.Data.ConnectionState.Open)
{
MessageBox.Show("Database Open failed");
conn = null;
}
return conn;
}
protected void ReportError1(SQLInsertBase ErrSource)
{
ErrSource.SQLInsertOK = false;
MessageBox.Show(ErrSource.SQLInsertError);
}
You may want to look into Linq To SQL which does a nice job of encapsulating your stored procedures into c# methods so you can access your data. You can also use it to read and update tables, but I prefer stored procedures personally.