I have code like
DatabaseConnection.MyExecuteNonQuery(comd);
cmd.CommandText = "select heads,formulla,fields from tbl_empsalstructear where empcode='" + emp.empid + "' order by headid";
OleDbDataReader rdr = DatabaseConnection.MyExecuteReader(cmd);
while (rdr.Read())
{
Here I have another function which returns a string value
string abc=function();
and then I use
string jkl=rdr[0].tostring()
which returns no value
and says no data in row n column but when I remove that function inside while it works properly and in that function I have another data reader that is closed
}
Maybe try checking for NULL values before trying to access the data.
The link above states;
Call this method to look for null column values before calling the typed get methods (for example, GetByte, GetChar, and so on) to avoid raising an error.
I typically use SqlDataReader, but an example of what I do is as follows. Note the rdr.IsDBNull call. Do that for any column that allows nulls;
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myconnstring"].ConnectionString))
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = SQL_COURSE_COMPONENTS; // Constant to my SQL statement containing a parameter #CourseId
SqlParameter param = new SqlParameter();
param.ParameterName = "#CourseId";
param.Value = CourseId;
cmd.Parameters.Add(param);
using (SqlDataReader rdr = cmd.ExecuteReader())
{
int CODE_ORDINAL = rdr.GetOrdinal("Code");
while (rdr.Read())
{
string code = rdr.IsDBNull(CODE_ORDINAL) ? (string)null : rdr.GetString(CODE_ORDINAL);
// .... Rest of the code here
}
}
}
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().
Below is a snapshot of my code. I am trying to access the only column in the customer table and place the values into a textbox on the form. I keep getting the error with my code "InvalidOperationException was unhandled" at the line declaring dr as a OleDbDataReader object.
What do I have wrong with the below code that would be giving me this error?
Should I do a list to pick out the text I want from the database?
How can I return the column values from access into a list in C# so that I can search the list for a particular value?
string strsql = "Select * from Customer";
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
textBox1.Text += dr["Customer"].ToString();
}
conn.Close();
A command carries the info to be executed, a connection carries the info to reach the database server. The two objects should be linked together to produce any result. You miss that line
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
cmd.Connection = conn; // <= here
conn.Open();
Remember also that disposable objects like a command, a reader and a connection should be disposed immediately after usage. For this pattern exists the using statement
So you should write
string cmdText = "Select * from Customer";
using(OleDbConnection conn = new OleDbConnection(.....constring...))
using(OleDbCommand cmd = new OleDbCommand(cmdText, conn))
{
conn.Open();
using(OleDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
.....
}
}
Here is some sample code.
try
{
using (OleDbConnection myConnection = new OleDbConnection())//make use of the using statement
{
myConnection.ConnectionString = myConnectionString;
myConnection.Open();//Open your connection
OleDbCommand cmdNotReturned = myConnection.CreateCommand();//Create a command
cmdNotReturned.CommandText = "someQuery";
OleDbDataReader readerNotReturned = cmdNotReturned.ExecuteReader(CommandBehavior.CloseConnection);
// close conn after complete
// Load the result into a DataTable
if (readerNotReturned != null) someDataTable.Load(readerNotReturned);
}
}
After that you have a Datatable containing your data. Ofcourse you can afterwards search for records in the Datatable any way you like.
IN THE LAST PART I WROTE THE working solution:
I have this stored procedure in SQL Server :
alter PROCEDURE [dbo].[ProcedureName]
#v nvarchar(10),
#L NVarChar(2)
AS
BEGIN
SET NOCOUNT ON;
SELECT B,M,V
FROM XXXX
WHERE V = #v and L = #L
END
and I am passing the parameters but I cannot retrieve the SELECT part I need to retrieve B,M,V of Select B,M,V also
SqlCommand Cmd = new SqlCommand("ProcedureName", cnn);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.Add("#v", SqlDbType.NVarChar, 10).Value = v;
Cmd.Parameters.Add("#L", SqlDbType.NVarChar, 2).Value = lo;
if (Cmd.Connection.State == ConnectionState.Closed)
{
Cmd.Connection.Open();
}
Cmd.ExecuteNonQuery();
THIS IS THE WOKING SOLUTION THANKS TO THE HELP I GOT HERE :
SqlCommand Cmd = new SqlCommand("ProcedureName", cnn);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.Add("#v", SqlDbType.NVarChar, 10).Value = v;
Cmd.Parameters.Add("#L", SqlDbType.NVarChar, 2).Value = lo;
if (Cmd.Connection.State == ConnectionState.Closed)
{
Cmd.Connection.Open();
}
using (SqlDataReader reader = Cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
ret = new MYCLASS();
ret.B = reader.GetString(0);
ret.M = reader.GetString(1);
ret.V = reader.GetString(2);
}
}
}
You'll need to make use of SqlDataReader to achieve this. Also make use of using block to ensure the connection object is closed and disposed correctly.
From MSDN
To ensure that connections are always closed, open the connection inside of a using block, as shown in the following code fragment. Doing so ensures that the connection is automatically closed when the code exits the block.
You can change your code to something like:
using(var con = new SqlConnection("ConnectionString")) {
using(var cmd = new SqlCommand("ProcedureName", con)) {
//Params here
con.Open();
using(var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
var bValue = reader.GetString(0);
//Same for the next two values
}
}
}
}
You're almost there, now if you pay close attention to your code you're not using the correct method for your procedure. This can be easily achieved with:
ExecuteReader Since you're only reading from your database.
instead of:
ExecuteNonQuery which is commonly used for UPDATE, INSERT, or DELETE statements
Conversion failed when converting the nvarchar value 'A' to data type int.
private void linksdetail(string id)
{
SqlConnection con = new SqlConnection(con_string);
con.Open();
SqlCommand cmd = new SqlCommand(" select a.solution_title,b.solution_sub_id,b.solutions_id,a.url from cms_solution_viewnew a, cms_solution_viewnew b where a.row_id = b.solution_sub_id and b.solutions_id='" + id + "'", con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
HyperLink1.Text = dr["solution_title"].ToString();
HyperLink1.NavigateUrl = dr["url"].ToString();
}
dr.Close();
con.Close();
}
How to solve it please help me.
solutions_id column data type is integer type and value of id is 9
Error message is pretty self explanatory. You try to assign sequence of characters to int typed column. Based on your example values, you don't need to use single quotes with your numeric columns. You can change your
b.solutions_id = '" + id + "'"
to
b.solutions_id = " + id
but as a better way, use parameterized queries. This kind of string concatenations are open for SQL Injection attacks. Also use using statement to dispose your SqlConnection, SqlCommand and SqlDataReader automatically instead of calling Close methods manually.
using(var con = new SqlConnection(con_string))
using(var cmd = con.CreateCommand())
{
cmd.CommandText = "select a.solution_title,b.solution_sub_id,b.solutions_id,a.url from cms_solution_viewnew a, cms_solution_viewnew b where a.row_id = b.solution_sub_id and b.solutions_id = #id";
cmd.Parameters.Add("#id", SqlDbType.Int).Value = id;
con.Open();
using(var dr = cmd.ExecuteReader())
{
// Do your stuff
}
}
I've been writing a lot of web services with SQL inserts based on a stored procedure, and I haven't really worked with any SELECTS.
The one SELECT I have in mind is very simple.
SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization
WHERE AD_SID = #userSID
However, I can't figure out based on my current INSERT code how to make that into a SELECT and return the value of ReturnCount... Can you help? Here is my INSERT code:
string ConnString = "Data Source=Removed";
string SqlString = "spInsertProgress";
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("attachment_guid", smGuid.ToString());
cmd.Parameters.AddWithValue("attachment_percentcomplete", fileProgress);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
Here is where you are going wrong:
cmd.ExecuteNonQuery();
You are executing a query.
You need to ExecuteReader or ExecuteScalar instead. ExecuteReader is used for a result set (several rows/columns), ExecuteScalar when the query returns a single result (it returns object, so the result needs to be cast to the correct type).
var result = (int)cmd.ExecuteScalar();
The results variable will now hold a OledbDataReader or a value with the results of the SELECT. You can iterate over the results (for a reader), or the scalar value (for a scalar).
Since you are only after a single value, you can use cmd.ExecuteScalar();
A complete example is as follows:
string ConnString = "Data Source=Removed";
string userSid = "SomeSid";
string SqlString = "SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization WHERE AD_SID = #userSID;";
int returnCount = 0;
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#userSID", userSid);
conn.Open();
returnCount = Convert.ToInt32(cmd.ExecuteScalar());
}
}
If you wanted to return MULTIPLE rows, you can use the ExecuteReader() method. This returns an IDataReader via which you can enumerate the result set row by row.
You need to use ExecuteScalar instead of ExecuteNonQuery:
String query = "SELECT COUNT(AD_SID) As ReturnCount FROM AD_Authorization WHERE AD_SID = #userSID ";
using (OleDbConnection conn = new OleDbConnection(ConnString)) {
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("userSID", userSID.ToString());
conn.Open();
int returnCount = (Int32) cmd.ExecuteScalar();
conn.Close();
}
}
cmd.executescalar will return a single value, such as your count.
You would use cmd.executereader when you are returning a list of records