Respected Users,
I am extracting data using data set.
I want to put value in textbox. But value is not comming.
I have following Code
try
{
da = new SqlDataAdapter("select ID from Customer where Name='" + gvBkPendingSearch.SelectedRows[0].Cells[1].Value.ToString() + "'",con);
DataSet ds = new DataSet();
da.Fill(ds);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
txtCustomerID.Text = ds.Tables[0].Rows[0].ToString();
}
catch (Exception ex)
{
}
finally
{
}
txtCustomerID is my textbox.
It is capturing value as>>>>>System.Data.DataRow
Error is in txtCustomerID.Text = ds.Tables[0].Rows[0].ToString();
but i am not able to understand it.
Please help me.
change it like this
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
txtCustomerID.Text = ds.Tables[0].Rows[i]["ID"].ToString();
The mistake you are doing is, you are accessing this
ds.Tables[0].Rows[0].ToString();
means 0th row, the whole row!! not the column value
And the datatable row is System.Data.DataRow in .Net
You need to select the column:
txtCustomerID.Text = ds.Tables[0].Rows[i][0].ToString();
Also note that you are overwriting the value of the textbox on each iteration of the loop. So what you will end up with is the ID of the last record in this textbox.
Also your query seems vulnerable to SQL injection. Personally I would recommend you scraping the DataSets in favor of an ORM or even plain old ADO.NET:
public static IEnumerable<int> GetIds(string name)
{
using (var conn = new SqlConnection("Your connection string comes here"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "select ID from Customer where Name=#Name";
cmd.Parameters.AddWithValue("#Name", name);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return reader.GetInt32(reader.GetOrdinal("ID"));
}
}
}
}
And now you could happily use this function:
string name = gvBkPendingSearch.SelectedRows[0].Cells[1].Value.ToString();
int id = GetIds(name).FirstOrDefault();
txtCustomerID.Text = id.ToString();
Related
I am very new to database queries and even more so, Oracle. I am also new to development work and, believe it or not, am creating this an for work purely out of frustration with the current process. Anyway, I am attempting to collect input from a multi-line text box and run a query. Each line corresponds to a single string that needs to be passed into the WHERE statement and the results will be dumped into a data table. Unfortunately, Oracle has still not released its developer tools for VS2019 so I am having to do this the harder way.
UPDATE # 2:
I have completely rebuilt the query since it was not running even when using known working code from another query. Below is what I have pieced together from various places on the interwebs. While debugging, it appears to parse and format the text correctly and pass it into the OracleParameter without issue. I am getting a Missing Expression error but I don't know what I am missing.
var connString =
ConfigurationManager.ConnectionStrings["dB"].ConnectionString;
string query = "SELECT col1, col2, col3, col4 FROM table WHERE col5 IN (";
using (OracleConnection conn = new OracleConnection(connString))
try
{
var input = "";
input = uniLookup.UniList;
var uniList = string.Join(",", Regex.Split(input, #"(?:\r\n|\n|\r)"));
string allParams = uniList;
string formattedParams = allParams.Replace(" ", string.Empty);
string[] splitParams = formattedParams.Split(',');
List<OracleParameter> parameters = new List<OracleParameter>();
using (OracleCommand cmd = new OracleCommand(query, conn))
{
for (int i = 0; i < splitParams.Length; i++)
{
query += #":Uni" + i + ",";
parameters.Add(new OracleParameter(":Uni" + i, splitParams[i]));
{
query = query.Substring(0, (query.Length - 1));
query += ')';
conn.Open();
using (OracleDataReader reader = cmd.ExecuteReader()) <==ERROR
{
if (!reader.HasRows)
{
while (reader.Read())
{
reader.Read();
{
MessageBox.Show(reader.GetString(1));
}
}
}
You can use IN in your where clause in this way to get rows from multiple values as:
string query = "SELECT dummyCol FROM dummytable WHERE altCol IN ("+text+");";
where you just have to change your text as text="'value1','value2','value3'"; this will not produce any syntax error.
You can convert your multi line text into same comma separated values using this :
foreach (String s in textBox1.Text.Split('\n'))
{
text +="'"+ s+"',";
}
text = text.TrimEnd(',');
this will help you achieve what you need. you can ask If there is any confusion.
Your final code will become :
public void GetData()
{
if (string.IsNullOrWhiteSpace(textbox1.Text) || textbox1.Text == "")
{
MessageBox.Show("Please Enter at least 1 Value and Try Again!");
}
else
{
System.Data.DataTable dt = new System.Data.DataTable();
// string[] lines = textbox1.Text.Split('\n');
string text = "";
foreach (String s in textBox1.Text.Split('\n'))
{
text += "'" + s + "',";
}
text = text.TrimEnd(',');
//Connection Credentials
string credentials = "Credentials";
string query = "SELECT dummyCol FROM dummytable WHERE altCol IN ("+text+");";
OracleConnection conn = new OracleConnection(credentials);
try
{
//Open The Connection
conn.Open();
using (OracleCommand cmd = new OracleCommand(query, conn))
{
//Call the Oracle Reader
using (OracleDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
MessageBox.Show("Unable to Retrieve Data");
return;
}
else if (reader.HasRows)
{
reader.Read();
DataRow row = dt.NewRow();
// create variables to accept reader data for each column
// insert data from query into each column here
dt.Rows.Add(row);
}
}
}
}
}
}
Let's say the following code returns the entire result row:
using (SqlCommand cmdMessages = new SqlCommand("SELECT * FROM Email where Sender = #usernameLog", conn))
{
cmdMessages.Parameters.Add(new SqlParameter("#usernameLog", Sender));
using (SqlDataReader reader = cmdMessages.ExecuteReader())
{
while (reader.Read())
{
Console.Write(); // Receiver's Name which comes from database
Console.Write();// The message which comes from same row as the receiver's name
}
}
}
The query works fine in SQL Server.
Output from SQL Server:
User hi
I want to have the same output in console.
If you just want to display the values you are retreiving as you are iterating through the datareader, you can simply do this:
using (SqlCommand cmdMessages = new SqlCommand("SELECT * FROM Email where Sender = #usernameLog", conn))
{
cmdMessages.Parameters.Add(new SqlParameter("#usernameLog", Sender));
using (SqlDataReader reader = cmdMessages.ExecuteReader())
{
int count = reader.FieldCount;
while (reader.Read())
{
for(int i = 0 ; i < count ; i++)
{
Console.WriteLine(reader.GetValue(i));
}
}
}
}
Use int count = reader.FieldCount; to count the number of fields you are returning. Then you are going to iterate through with a for statement.
If you only have 2 values you want to be displayed, you can simply replace the for with:
Console.WriteLine(reader.GetValue(0) + " " + reader.GetValue(1));
to get column values you need:
while (reader.Read())
{
reader.GetString(1);
reader.Getstring(2);
}
or
reader.GetString("ColumnName1");
reader.GetString("ColumnName2");
EDIT: I am not able to format my code below, if any one can fix it.
I am new to sql queries and still learning.
Table Name: CommissionSetupTable.
I want to display #Paisa if gross_amount is between the range of #FromRate and #ToRate
Below is my code:
string paisa;
private void load_commission_setup()
{
SqlCeConnection conn = null;
SqlCeCommand cmd = null;
SqlCeDataReader rdr = null;
try
{
conn =
new SqlCeConnection(
#"Data Source=|DataDirectory|\Database.sdf;Persist Security Info=False");
conn.Open();
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
gross_amount = double.Parse(purchaseBillTableDataGridView[10, rowindex].Value.ToString());
// Gross Amount is between the ranges of FromRate and ToRate.
cmd = new SqlCeCommand("SELECT Paisa FROM CommissionSetupTable WHERE='" + gross_amount.ToString() + "' BETWEEN #FromRate AND #ToRate;", conn);
rdr = cmd.ExecuteReader();
if (rdr == null)
{
}
else
{
while (rdr.Read())
{
paisa = rdr["Paisa"].ToString();
}
rdr.Close();
cmd.Dispose();
}
}
finally
{
conn.Close();
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
purchaseBillTableDataGridView[11, rowindex].Value = paisa;
}
}
The correct syntax to use here is the following
cmd = new SqlCeCommand(#"SELECT Paisa FROM CommissionSetupTable
WHERE #gross BETWEEN FromRate AND ToRate;", conn);
Notice that the two field names should not be prefixed with #, otherwise they will be considered parameters placeholders.
And now, before executing the command, add the parameter for the #gross placeholder
cmd.Parameters.Add("#gross", SqlDbType.Decimal).Value = gross_amount;
I don't know what is the exact datatype of the columns FromRate and EndRate, but
note that you should use the correct datatype for your parameter. Do not pass a string and expect the database engine do the conversion for you. (or worse concatenate your value to the rest of the sql using ToString()). This is always wrong also if sometime the database engine could understand your values.
EDIT
Also, following your comments below, it appears that this line is wrong
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
If your DataGridView has the property AllowUserToAddRow set to True then you want to use
int rowindex = purchaseBillTableDataGridView.Rows.Count - 2;
because the first line points to the empty row added to the DataGridView for inserting a new record.
I am trying to show number of rows from a grid view using a label. I used SQL Count statement but it doesn't work. The problem is I only get only number 1 shown in the label which is not matched with the number of rows I have in my table! I have posted similar question but unfortunately no body gave a clear answer!
My codes as:
Basket.ac
public int td()
{
int customers;
//I tried this select query but still gets number 1
//String sql = String.Format("SELECT COUNT(*) FROM dbo.Baskets");
string sql = string.Format("SELECT COUNT(*) FROM Baskets");
customers = Db.RunQuery(sql).Rows.Count;
//customers = Convert.ToInt32(Db.RunQuery(sql).Rows.Count);
return customers;
}
DataBaseConn.ac
public class DataBaseConn
{
SqlConnection conn;
SqlCommand cmd;
DataTable tbl;
private void Intialise(CommandType commandtype, string DataBase)
{
conn = new SqlConnection();
cmd = new SqlCommand();
//Requirements
conn.ConnectionString = ConfigurationManager.ConnectionStrings[1].ToString();
cmd.Connection = conn;
cmd.CommandType = commandtype;
cmd.CommandText = DataBase;
conn.Open();
}
public int RunProcedure(string Procedure, SortedList ParameterV)
{
Intialise(CommandType.StoredProcedure, Procedure);
for (int i = 0; i < ParameterV.Count; i++)
try
{
if (ParameterV.GetByIndex(i) != null)
cmd.Parameters.AddWithValue(ParameterV.GetKey(i).ToString(),
PrameterV.GetByIndex(i).ToString());
}
catch { ;}
return RunUpdate();
}
public int RunUpdate(string InsDelUpd)
{
Intialise(CommandType.Text, InsDelUpd);
return RunUpdate();
}
private int RunUpdate()
{
try
{
int x = cmd.ExecuteNonQuery();
conn.Close();
return x;
}
catch (SqlException ex)
{
conn.Close();
return ex.Number;
}
}
public DataTable RunQuery(string Select)
{
Intialise(CommandType.Text, Select);
tbl = new DataTable();
tbl.Load(cmd.ExecuteReader());
conn.Close();
return tbl;
}
public bool EData(string selection)
{
if (RunQuery(selection).Rows.Count > 0)
return true;
else
return false;
}
}
Basket.aspx
lblQueue.Text = _b.td().ToString();
You don't want to return the data table's .Rows.Count - this will always be 1 (as in 1 row(s) affected) for your count(*) query.
You should instead look at using ExecuteScalar to return the first column of the first row from your query
I'm not sure how you want to build this into your DataBaseConn data helper class, but the gist of it is you need the following sequence:
using (var conn = new SqlConnection(connectionStringHere))
using (var cmd = new SqlCommand(conn))
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT COUNT(*) FROM Baskets";
return (int)cmd.ExecuteScalar();
}
Edit
If you aren't able to extend your DataBaseConn helper with an ExecuteScalar, then I guess you'll be able to use the existing RunQuery method which returns a DataTable. Just scrape the first column of the first row like so:
return Db.RunQuery(sql).Rows[0].Field<int>(0);
As a side note, you might look at replacing your DataHelper entirely with the Microsoft Patterns and Practices Data Application Access Block (DAAB), or, if you prefer, look at using an ORM like Entity Framework. By upgrading to a mainstream Data Access encapsulation, you won't need to spend as much time debugging data access issues like this one :)
so I'm trying to store values in an array of Lists in C# winForms. In the for loop in which I make the sql statment, everything works fine: the message box outputs a different medication name each time.
for (int i = 0; i < numberOfMeds; i++)
{
queryStr = "select * from biological where medication_name = '" + med_names[i] + "' and patient_id = " + patientID.patient_id;
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(queryStr, conn))
{
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
medObject.medication_date = (DateTime)rdr["patient_history_date_bio"];
medObject.medication_name = rdr["medication_name"].ToString();
medObject.medication_dose = Convert.ToInt32(rdr["medication_dose"]);
medsList[i].Add(medObject);
}
}
conn.Close();
MedicationTimelineClass medObjectx = medsList[i][0] as MedicationTimelineClass;
MessageBox.Show(medObjectx.medication_name);
}
}
but then, when I take the message box code out of the loop, meaning that the array of Lists is supposed to be populated, I always get the same value: the last value entered. the same medication name, no matter what number I put between those brackets. It's like if the whole array of Lists is populated with the same data.
for (int i = 0; i < numberOfMeds; i++)
{
queryStr = "select * from biological where medication_name = '" + med_names[i] + "' and patient_id = " + patientID.patient_id;
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(queryStr, conn))
{
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
medObject.medication_date = (DateTime)rdr["patient_history_date_bio"];
medObject.medication_name = rdr["medication_name"].ToString();
medObject.medication_dose = Convert.ToInt32(rdr["medication_dose"]);
medsList[i].Add(medObject);
}
}
conn.Close();
}
}
MedicationTimelineClass medObjectx = medsList[0][0] as MedicationTimelineClass;
MessageBox.Show(medObjectx.medication_name);
what's going on here?
It looks like you are reusing the same MedicationTimelineClass object inside your loop. Remember that your class is a reference type. You are basically adding the same reference to your list and updating the values of the properties stored in the object at that reference. Ultimately, all of the "items" in your list refer to the same object.
Instantiate a new MedicationTimelineClass object with each iteration and then add that new object to your list.
In the "while (rdr.Read())" loop, you're just adding the same object (medObject) to the list each time. The list is being populated with the same object, over and over again.