In window application, i am trying to work with database, how to write connection string in app.config. The below is connection string in app.config
<configuration>
<appSettings >
<add key ="mycon"
value ="server=192*****;database=*****;
uid=**;pwd=*****;"/>
</appSettings>
</configuration>
Code to connect database:
SqlConnection con = new SqlConnection(
ConfigurationSettings.AppSettings["mycon"].ToString()); con.Open();
SqlCommand cmd = new SqlCommand("Usp_chat_login", con);
cmd.CommandType = CommandType.StoredProcedure ;
cmd.Parameters.Add("#userid", SqlDbType.VarChar, 20);
cmd.Parameters["#userid"].Value = textBox1.Text;
cmd.Parameters.Add("#password", SqlDbType.VarChar, 20);
cmd.Parameters["#password"].Value = textBox2.Text;
int reslt = cmd.ExecuteNonQuery(); con.Close();
if (reslt > 0)
{
MessageBox.Show("Yes");
}
else
{
MessageBox.Show("No");
}
Every time i am getting reslt=-1, even if i pass correct credentials
Every time i am getting reslt=-1, even if i pass correct credentials
This has nothing to do with the credentials, nor does it pertain to the config file. If authentication/authorization to the database failed, an exception would be thrown.
The problem is likely in your Usp_chat_login procedure.
See the documentation for ExecuteNonQuery():
For UPDATE, INSERT, and DELETE statements, the return value is the
number of rows affected by the command. When a trigger exists on a
table being inserted or updated, the return value includes the number
of rows affected by both the insert or update operation and the number
of rows affected by the trigger or triggers. For all other types of
statements, the return value is -1. If a rollback occurs, the return
value is also -1.
Other notes:
Types which implement IDisposable should be disposed of, especially types which interact with unmanaged resources (e.g. database connections). A simple way to do this is to wrap the instances of these types in a using statement.
Plain-text passwords are considered insecure/irresponsible in any application.
Write it in App.XAML
public partial class App : Application
{
public App()
{
string connectionStr = "Data Source=system\\SQLExpress;Initial Catalog=DBName; user id=sa; password=test123;";
Application.Current.Properties["conStr"] = connectionStr;
}
}
and Access it in main form
static string strCon = Application.Current.Properties["conStr"].ToString();
Related
I am developing an asp.net web application and I am trying to add a user xp system to it. I have a SQL Server database connected to it and I am trying to make a function that will give 5 experience points to the user.
I queried to the user that is logged in, accessed the user_xp column, and I am trying to add +5 to the old session variable for xp, then send that back into the database to be stored. Here is my code, I am not sure what is wrong with it.
void generateXp()
{
try
{
SqlConnection con = new SqlConnection(strcon);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
SqlCommand cmd = new SqlCommand("UPDATE member_master_tbl SET user_xp = #user_xp WHERE " +
"user_name = '" + Session["username"].ToString().Trim() + "'", con);
int xp = 5;
int current_xp = Convert.ToInt32(Session["user_xp"]);
int new_xp = xp + current_xp;
string new_xp2 = Convert.ToString(new_xp);
cmd.Parameters.AddWithValue("user_xp", new_xp2);
}
catch (Exception ex)
{
}
}
Try renaming the SQL parameter to #user_xp.
cmd.Parameters.AddWithValue("#user_xp", new_xp2);
I don't have an accessible database to test. Also, you need to add the command to execute the query at the end.
cmd.ExecuteNonQuery()
That being said, it's a good practice to learn to separate DB queries to stored procedures or functions.
As others noted, you simply forgot to do a execute non query to run the command that you setup.
However, you can write things this way. You don't mention or note what the data type the experience points column is - I assumed "int".
So, your code block can be written this way:
using (SqlCommand cmd = new SqlCommand("UPDATE member_master_tbl SET user_xp = #user_xp WHERE user_name = #user",
new SqlConnection(strcon)))
{
cmd.Parameters.Add("#user_xp", SqlDbType.Int).Value = 5 + Session("user_xp");
cmd.Parameters.Add("#user", SqlDbType.NVarChar).Value = Session("username");
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
note how the command object has a connection object (so we don't need a separate one).
And while several people here "lamented" the string concentration to build the sql and warned about sql injection?
Actually, the introduction of # parameters for both values cleans up the code. So you get nice parameters - nice type checking, and you don't have to remember to add/use/have things like quotes around teh string, but not for numbers.
And I let .net cast the number expression from session() - this also likely is ok.
Also the "using block" also correctly cleans up the command object and also the connection object - so the using block is a good idea here.
I'm having problems with updating a row in the Users table of my Access DB. Here is the code below:
private void SaveProfileInfo()
{
try
{
ChangeForeColorOfStatusMsg(Color.Black);
ChangeTextOfStatusMsg("Saving new profile information...");
const string cmd = #"UPDATE Users SET LastName=#LastName,FirstName=#FirstName,MiddleName=#MiddleName,Add_Num=#Add_Num,Add_Street=#Add_Street,Add_Brgy=#Add_Brgy,Add_City=#Add_City,MobileNumber=#MobileNumber,Gender=#Gender WHERE ID=#ID;";
var dbConn = new OleDbConnection(cs);
var dbCmd = new OleDbCommand(cmd, dbConn);
dbCmd.Parameters.AddWithValue("#ID", UserLoggedIn.ID);
dbCmd.Parameters.AddWithValue("#LastName", txtLastName.Text);
dbCmd.Parameters.AddWithValue("#FirstName", txtFirstName.Text);
dbCmd.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text);
dbCmd.Parameters.AddWithValue("#Add_Num", txtUnitNum.Text);
dbCmd.Parameters.AddWithValue("#Add_Street", txtStreet.Text);
dbCmd.Parameters.AddWithValue("#Add_Brgy", GetBrgySelectedItem());
dbCmd.Parameters.AddWithValue("#Add_City", GetCitySelectedItem());
dbCmd.Parameters.AddWithValue("#MobileNumber", txtMobileNumber.Text);
dbCmd.Parameters.AddWithValue("#Gender", GetGenderSelectedItem());
dbConn.Open();
dbCmd.ExecuteNonQuery();
dbConn.Close();
ChangeForeColorOfStatusMsg(Color.MediumSeaGreen);
ChangeTextOfStatusMsg("All changes have been saved! This window will close itself after two seconds.");
Thread.Sleep(2000);
CloseForm();
}
catch (Exception)
{
ChangeForeColorOfStatusMsg(Color.Crimson);
ChangeTextOfStatusMsg("Something went wrong while we were connecting to our database. Please try again later.");
hasFinishedEditting = false;
}
}
This method will be done on a separate thread, when the user updates his profile information.
UserLoggedIn is actually a field of a User class (a class that defines a row in my table), which stores all the info of the user who's currently logged in.
When I run this, it does not produce any exceptions or errors. But when I check my table, the values are not updated.
I copy-pasted these codes from the registration form (which works) that I made with this system, and modified it into an UPDATE cmd than an INSERT cmd.
I also made Change Username and Password Forms that use the same cmd as shown below:
public void ChangePass()
{
try
{
ChangeForeColorOfMsg(Color.Silver);
ChangeTextOfMsg("Changing password...");
const string cmd = "update Users set Pass=#Pass where ID=#ID";
var dbConn = new OleDbConnection(cs);
var dbCmd = new OleDbCommand(cmd, dbConn);
dbCmd.Parameters.AddWithValue("#Pass", txtNewPass.Text);
dbCmd.Parameters.AddWithValue("#ID", UserLoggedIn.ID);
dbConn.Open();
dbCmd.ExecuteNonQuery();
dbConn.Close();
ChangeTextOfMsg("Password successfully changed!");
}
catch (Exception)
{
ChangeForeColorOfMsg(Color.Silver);
ChangeTextOfMsg("A problem occurred. Please try again later.");
}
}
And these codes work for me. So I'm really confused right now as to why this update cmd for the profile information isn't working... Is there something I'm not seeing here?
OleDb cannot recognize parameters by their name. It follows a strictly positional order when sending them to your database for updates. In your code above the first parameter is the #ID but this parameter is used last in your query. Thus everything is messed up.
You just need to move the add of the #ID parameter as last in the collection
As a side note, you should be very careful with AddWithValue. It is an handy shortcut, but it has a dark side that could result in wrong queries.
Take a look at
Can we stop using AddWithValue already?
My Windows form Application contains OleDbDataAdapter, it is consuming longer time to fetch data from remote DB. It is not able to retrieve/Hold table data like 5000 rows(Application gets struck). Here is my code.
environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1);
dataGridView1.DataSource = ds1.Tables[0];
Environment section is configured in app.config file :
<configuration>
<configSections>
<section name ="Environment" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<Environment>
<add key ="CIT" value ="Password=pwd123;User ID=abc123;Data Source=db1;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="SIT" value ="Password=pwd234;User ID=abc234;Data Source=db2;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="UAT" value ="Password=pwd345;User ID=abc345;Data Source=db3;Persist Security Info=True;Provider=MSDAORA"/>
</Environment>
</configuration>
It would be greatful if someone could suggest better approach/mechanism with code.
Did you try to work with threads. create a sub function somewhere in your program like below
public void dataPullingThread(){
try{
//your connection code goes here like below//
environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1);
dataGridView1.DataSource = ds1.Tables[0];
conn.Close();
}
catch (Exception e){
}
}
//call your thread from desired location in program///
using System.Threading;
Thread thread = new Thread (new ThreadStart(dataPullingThread));
thread.start;
//Your application will continuously run; however, the data will appear when ever the thread auto kills itself. You can boost the speed if you create more then one thread. That means each thread selecting different rows of the database, I hope this information will help you//
Here are some general ADO.NET optimization tricks:
Instead of doing SELECT *, please ensure that you really need all the fields. The problem is that many unused field values might be retrieved and it consume resources.
For example, do SELECT Field1, Field2, Field3 instead of SELECT * if your table contains more than those three fields.
Stick to the following connection open/close pattern:
Example:
using(var con = new OleDbConnection(strConnString))
{
con.Open();
...
con.Close();
}
So the connection is closed even if wrong things happens, and the connection pooling mechanism will be used on the server side.
The DbDataReader object is much faster. Please try to use a DbDataReader instead of a DbDataAdapter. Use it to fill a generic List, then bind your DataGrid to that List.
However, it looks like something is wrong with your connection itself. How can you be sure the application is fetching data or trying to establish a connection ? To check this, change your query to a very fast one like "select sysdate from dual" to check whether the problem is coming from a connection attempt or not.
I want to insert values in "Navn" row and "Varenr" row in the DB table, when I'm clicking on a button. I have following code:
private void button2_Click(object sender, EventArgs e)
{
using (SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"))
{
try
{
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
string col1 = textBox2.Text;
string col2 = textBox3.Text;
//generate sql statement
cm.CommandText = "INSERT INTO ProduktTable (Navn,Varenr) VALUES (#col1,#col2)";
//add some SqlParameters
SqlParameter sp_add_col1 = new SqlParameter();
sp_add_col1.ParameterName = "#col1";
//data type in sqlserver
sp_add_col1.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col1.Size = 20;
sp_add_col1.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col1);
//in your insert into statement, there are how many parameter, you must write the number of parameter
SqlParameter sp_add_col2 = new SqlParameter();
sp_add_col2.ParameterName = "#col2";
//data type in sqlserver
sp_add_col2.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col2.Size = 20;
sp_add_col2.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col2);
//open the DB to execute sql
cn.Open();
cm.ExecuteNonQuery();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
But unfortunately, my data table is still empty:
I have set a breakpoint on the ExecuteNonQuery function, and it is triggered, when pressing on the button:
My table definition:
Your connection string is causing this:
Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"
|DataDirectory| Your database that is being updated in this method is in your App Data Directory while the one you are trying to retrieve data from is in your project folder...
|DataDirectory| is a substitution string that indicates the path to the database. DataDirectory also makes it easy to share a project and also to deploy an application. For my PC my App Data Directory is:
C:\Users\MyUserName\AppData\...
If you browse to this location and then go to following folders
...\Local\Apps\2.0\Data
You will be able to find your particular application directory probably stored with your assembly name, or some hash when you go there you will find it the database there is being updated just fine. This connection string is best for deployment.
You can also try this:
If you notice that Server Explorer is detecting all the databases on my PC and you can notice that there are couple of MINDMUSCLE.MDF files but all are at different paths, this is because there is one file in DEBUG directory, one in my PROJECT directory, one in my APP DATA directory. The ones starting with the numbers are stored in my APP DATA directories... If you select your respective database file and then run the SELECT query against it, you will get your data.
I made a tutorial some time ago. May be it will help you:
Check the value that ExecuteNonQuery is returning. It should return an int with the number of records affected by the SQL statement.
If it comes back with a value other than 0, then you know a record is being inserted somewhere. Before you close the connection, run a SQL query against the table to select all of the records and see if they come back through the code.
SELECT * FROM ProduktTable
If you get some records, then you may want to double check the database you're looking at through the IDE and the one your inserting records into through the code. It could be possible that you've got two different databases and you're querying one while inserting into another one.
Those are the steps that I would go through to help narrow down the issue and sounds like something I've probably done before. I hope it helps!
My code works well but after trying to host it. Its database always response with the null value . I failed to host it. and now when i try to debug in my PC its also have the same problem of null response.
my class file and its scalar query code.
public Object ExecuteScalarQuery(String sp)
{
String _ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["rfid"].ConnectionString;
// string _ConnString = ConfigurationManager.ConnectionStrings["rfid"].ConnectionString;
SqlConnection myConnection = new SqlConnection(_ConnString);
SqlCommand cmd = new SqlCommand(sp, myConnection);
Object result = 0;
try
{
myConnection.Open();
result = cmd.ExecuteScalar();
}
catch (Exception ex)
{
//if (myConnection.State == ConnectionState.Open)
// myConnection.Close();
}
finally
{
//if (myConnection.State == ConnectionState.Open)
// myConnection.Close();
}
return result;
}
And web.config file having connectionstring
<connectionStrings>
<add name="rfid" connectionString="Data Source=CHINTAN-PC\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True " providerName="System.Data.SqlClient"/>
while doing step by step debugging its connectionstring look like this which is not being working.
"Data Source=CHINTAN-PC\\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True "
One thing to check is that results are being returned by your stored procedure. I copied your code, made a table and a stored procedure to query all records from it, and it returned null when the table was empty and the value of the first column of the first row when I added a couple records.
add the property 'pooling'.
<add name="rfid" connectionString="Data Source=CHINTAN-PC\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True; pooling=false;" providerName="System.Data.SqlClient"/>
go to server explorer, select you data base. in the right pane(Properties) copy connection string and paste it. if that doesn't work. go to sql management studio. its your windows authentication and sql authentication problem. make a new sql authentication login and give userid="" and password="" like "sa" and "sa123" in the connection string.
Use toString to retrieve the string value
String _ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["rfid"].ConnectionString.toString();