I have a table named t_Student in Microsoft SQL Server 2005 database. In that table there are three columns named student_regiNo, student_Name, student_Email.
I'm using following code segment to retrieve "student_Name". But instead of showing "student_Name" it shows "System.Data.SqlClient.SqlDataReader". Whats the problem?
private void GetDatabaseConnection()
{
string connectionString = #"server=RZS-F839AD139AA\SQLEXPRESS; Integrated Security = SSPI; database = StudentCourseInformation";
connection = new SqlConnection(connectionString);
connection.Open();
}
public string GateStudentName(string selectedStudentRegiNo)
{
GetDatabaseConnection();
string selectedStudentQuery = #"SELECT student_Name FROM t_Student WHERE (
student_regiNo =
'" +selectedStudentRegiNo+ #"'
)";
SqlCommand command = new SqlCommand(selectedStudentQuery, connection);
SqlDataReader reader = command.ExecuteReader();
string selectedStudentName = Convert.ToString(reader);
return selectedStudentName;
}
Use
return (string)command.ExecuteScalar();
as far as you have to return "the first column of the first row in the result set returned by the query" (from MSDN)
Also use parametrized query:
var command = new connection.CreateCommand()
command.CommandText = "SELECT student_Name FROM t_Student WHERE student_regiNo = #number";
command.Parameters.AddWithValue(#number, selectedStudentRegiNo);
ExecuteReader returns a SqlDataReader. You need to use the SqlDataReader API to read the data from it. Don't forget that a query can return multiple rows, with multiple columns in each row. For example:
while (reader.Read())
{
string name = reader.GetString(0);
Console.WriteLine("Read name: {0}", name);
}
Further note that you should use a parameterized query rather than including the ID directly into the SQL - otherwise you leave yourself open to SQL injection attacks. See the docs for SqlCommand.Parameters for more information.
Finally, you should use using statements for the SqlConnection, SqlCommand and SqlDataReader so that you dispose of them appropriately. Otherwise you're going to leak database connections.
if (reader.Read())
{
string selectedStudentName = reader.GetString(0);
}
SqlCommand command = new SqlCommand(selectedStudentQuery, connection);
SqlDataReader reader = command.ExecuteReader();
if(reader.Read())
{
return reader["student_Name"];
}
return "not exist";
Related
This is my code, and I want to be able to search for a name, and then pull from the database the name, status, member_id into the textboxes in my form.
I got the name to work but how do I get the other columns and parse the output into the textboxes with the additional columns (member_id, status)? Let's say the other textboxes have the standard name such as textbox2, 3, 4...
string connetionString = null;
SqlConnection connection;
SqlCommand command;
string sql = null;
string sql1 = null;
SqlDataReader dataReader;
connetionString = "Data Source=......"
sql = "SELECT NAME FROM Test_Employee WHERE Name LIKE '" + textBox1.Text.ToString() + "%'";
connection = new SqlConnection(connetionString);
{
connection.Open();
command = new SqlCommand(sql, connection);
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
textBox9.Text = dataReader[0].ToString();
textBox7.Text = dataReader[0].ToString();
}
connection.Close();
}
Are the fields Member_Id and Status also in the table Test_Employee? You can add them in your Select statement and get them from your SqlReader, like the code below (assuming you are using c#7 and below). You may copy and paste this code.
var connectionString = "";
var sql = #"SELECT TOP 1 Name, Member_Id, Status
FROM Test_Employee
WHERE Name LIKE #name + '%'";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("name", SqlDbType.NVarChar, 100).Value = textBox1.Text.ToString();
connection.Open();
var reader = command.ExecuteReader();
if (reader.Read())
{
textBox9.Text = dataReader["Name"].ToString();
textBox7.Text = dataReader["Name"].ToString();
textBox2.Text = dataReader["Member_Id"].ToString();
textBox3.Text = dataReader["Status"].ToString();
}
}
You will notice that instead of including the Textbox1.Text's value in your Select statement, it is added as a parameter in the SQLCommand object's Parameters. In this way your query is protected from SQL Injection. If you want to learn more, you can search c# sqlcommand parameters and why it is very important to build data access code this way.
Also, notice that I added Top 1 in your Select statement, and instead of using while, I am using if. This is because a textbox can only hold 1 result at a time in a comprehensible way. If you meant to show multiple results clearly, you need to use a different control other than a TextBox.
The using statements allow you to dispose the connection, so you don't have to call connection.Close().
I am trying to get the result from a select command:
string strName = dtTable.Rows[i][myName].ToString();
string selectBrand = "SELECT [brand] FROM [myTable] WHERE [myName] = '" + strName + "'";
SqlCommand sqlCmdSelectBrand = new SqlCommand(selectBrand , sqlConn);
sqlCmdSelectBrand .Connection.Open();
sqlCmdSelectBrand .ExecuteNonQuery();
string newBrand = Convert.ToString(sqlCmdSelectBrand .ExecuteScalar());
sqlCmdSelectBrand .Connection.Close();
The select works, I have executed it in SQL Studio, but it does not assign to my variable on the second to last line. Nothing gets assigned to that variable when I debug it...
Any advice?
Your approach to read data returned from a SELECT query is (in this particular context) a bit wrong. Usually you call ExecuteReader of the SqlCommand instance to get back your data.
string strName = dtTable.Rows[i][myName].ToString();
string selectBrand = "SELECT [brand] FROM [myTable] WHERE [myName] = #name";
using(SqlCommand sqlCmdSelectBrand = new SqlCommand(selectBrand , sqlConn))
{
sqlCmdSelectBrand.Parameters.Add(
new SqlParameter("#name", SqlDbType.NVarChar)).Value = strName;
sqlCmdSelectBrand .Connection.Open();
using(SqlDataReader reader = sqlCmdSelectBrand.ExecuteReader())
{
if(reader.HasRows)
{
reader.Read();
string newBrand = reader.GetString(reader.GetOrdinal("Brand"));
..... work with the string newBrand....
}
else
// Message for data not found...
sqlCmdSelectBrand .Connection.Close();
}
}
In your context, the call to ExecuteNonQuery is not required because it doesn't return anything from a SELECT query. The call to ExecuteScalar should work if you have at least one record that match to the WHERE condition
Notice also that you should always use a parameterized query when building an sql command text. Also if you think to have full control of the inputs, concatenating string is the open door to Sql Injection
I have got the input to work but now I need to add to the original number every time I input to the database but I do not know how to do that, any help would be appreciated :)
String myConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:/coursework/Databases/runner database.accdb;"; // location of the database
OleDbConnection myConnection = new OleDbConnection(myConnectionString); // To create the database connection
OleDbCommand myCommand = new OleDbCommand(); // Use the connection for the command
myCommand.Connection = myConnection;
try
{
myConnection.Open(); // Opens the database connection
string query = "insert into tblTrainingInformation ([Username],[Calories Burnt]) values('"+GlobalUsername.username+"','" + this.txtCaloriesBurntRun.Text + "')";
OleDbCommand createCommand = new OleDbCommand(query, myConnection);
createCommand.ExecuteNonQuery();
MessageBox.Show("Your running information has been saved");
myConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
If you want to UPDATE an existing record adding a new value to your field or INSERT a new record if it is not present you need to know if your database already contains the Username.
So you need to run a SELECT query before and then decide if you need an UPDATE or an INSERT
(Access doesn't have some kind of UPSERT statement like MySql or Sql Server)
String myConnectionString = ".....";
string querySel = #"SELECT [Username],[Calories Burnt]
FROM tblTrainingInformation
WHERE [Username] = #uname";
using(OleDbConnection myConnection = new OleDbConnection(myConnectionString))
using(OleDbCommand myCommand = new OleDbCommand(querySel, myConnection))
{
myConnection.Open();
myCommand.Parameters.AddWithValue("#uname", GlobalUsername.username);
using(OleDbDataReader reader = myCommand.ExecuteReader())
{
int calories = 0;
string query = "";
if(reader.Read())
{
// The record exists, read the calories and add the new value
// then execute the UPDATE
calories = Convert.ToInt32(reader["Calories Burnt"]);
calories += Convert.ToInt32(this.txtCaloriesBurntRun.Text);
query = #"UPDATE tblTrainingInformation
SET [Calories Burnt] = #cal
WHERE [Username] = #uname";
}
else
{
// Record doesn't exist, INSERT the new data
calories = Convert.ToInt32(this.txtCaloriesBurntRun.Text);
query = #"INSERT INTO tblTrainingInformation
([Calories Burnt],[Username])
VALUES(#cal, #uname)";
}
reader.Close();
myCommand.Parameters.Clear();
myCommand.Parameters.AddWithValue("#cal", calories);
myCommand.Parameters.AddWithValue("#uname", GlobalUsername.username);
myCommand.ExecuteNonQuery();
MessageBox.Show("Your running information has been saved");
}
}
I have made a couple of assumption here.
First I assume that UserName is the primary key in this table so you can retrieve the record using the WHERE on username value.
The second assumption is the type of the field Calories Burnt.
It should be a numeric field and, to simplify the example, I have considered it to be an integer.
These assumptions should be checked and fixed if they are not true.
Said that, notice the use of the Using Statement to correctly dispose the connection, command and reader. The removing of string concatenation from your queries is another important point. You should ALWAYS use the parameter collection to avoid Sql Injection (albeit improbable with Access) and error in parsing your values.
A final note on the order of the parameters. OleDb wants the parameter in the exact order in which the parameter placeholders appear in the query text so I have reversed the order of the INSERT to be compatible with the UPDATE command
public string checkUsername(string username, string password)
{
string result = "invalid username/password";
string connectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~\\myDB\\database.mdb");
string queryString = "SELECT * FROM Table WHERE [username]='" + username + "' AND [password]='" + password + "';";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
OleDbCommand command = connection.CreateCommand();
command.CommandText = queryString;
OleDbDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
result = "";
}
}
finally
{
reader.Close();
connection.Close();
}
}
return result;
}
System.Data.OleDb.OleDbException: Data type mismatch in criteria expression.
pointing around this line:
OleDbDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
wanted to try:
cmd.Parameters.AddWithValue("#password", txtBoxPassword.Text);
but that "txtBoxPassword" doesnt exist in current context.
just learned c# for few months now but still need guidance.
The way you have your SQL statement, you are wide open for SQL injection. It should be parameterized as you were optionally shooting for... Put that as your statement.
SELECT * FROM Table WHERE [username]=#parmUserName AND [password]=#parmPassword
Then, add your parameters as you were going for, but you should probably clean them too for sanity purposes. Here, the inbound parameters of username, password are NOT the column names for the query. You are setting these VALUES into the parameter objects.
cmd.Parameters.AddWithValue ( "#parmUserName", username);
cmd.Parameters.AddWithValue ( "#parmPassword", password);
The code below returns an empty records but gave records from SQL+.
DbProviderFactory factory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
DbConnection connection = factory.CreateConnection();
connection.ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=Simplex-IT-02)(PORT=1521)))
(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=Simplex))); User Id=User_Test;Password=password;";
DataTable table = new DataTable();
DbCommand command = connection.CreateCommand();
command.Connection = connection;
command.CommandText = "SELECT text FROM user_views WHERE (view_name='ACCOUNT_BALANCES_BY_PERIOD');";
DbDataReader dataReader = command.ExecuteReader();
table.Load(dataReader);
dataReader.Close();
Meanwhile, when I replaced the command.CommandText with "SELECT DISTINCT view_name FROM user_views" it gave me list of all available views for the given schema.
Why can't I get the sql text of a given view?
The problem is the ; at the end of the query. Remove it and it should return values.
command.CommandText = "SELECT text FROM user_views WHERE
(view_name='ACCOUNT_BALANCES_BY_PERIOD')";