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");
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);
}
}
}
}
}
}
How can I generate an array of string that will contain all the column info.
this query will return a single row with multiple columns
var rowLines = new List<string>();
try
{
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
string query = "SELECT I1,I2,I3,I4,I5,I6,I7,I8,I9,I10,I11,I12,I13,I14,I15 FROM LABEL_OUT WHERE LABEL_NAME='" + labelName + "'";
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
rowLines.Add(reader[0].ToString());
}
}
}
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
here rowLines will Contain all the column value such as I1,I2,.....I15
Probably the easiest way to do this is to use DbDataReader.GetValues(object[]), which populates a pre-existing array with the values from each column:
var vals = new object[reader.FieldCount];
while (reader.Read())
{
reader.GetValues(vals);
// ... do something with the values
}
If you are sure that you will take a single line you could loop on the reader using the FieldCount and add each element on a List<string>. Finally, you could just return it as an array.
var rowLines = new List<string>();
if (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
rowLines.Add(reader.IsDBNull(i) ? string.Empty : reader[i].ToString());
}
}
return rowLines.ToArray();
I'm using an SqlDataReader to read to a collection of custom type , but all I'm getting is the final row of the DataTable repeated, rather than a full table of information. Help would be gratefully received.
using (connection)
{
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
lineData.Column1 = reader.GetValue(0).ToString();
lineData.Column2 = reader.GetValue(1).ToString();
lineData.Column3 = reader.GetValue(2).ToString();
lineData.Column4 = reader.GetValue(3).ToString();
lineData.Column5 = reader.GetValue(4).ToString();
lineData.Column6 = reader.GetValue(5).ToString();
lineData.Column7 = reader.GetValue(6).ToString();
lineData.Column8 = reader.GetValue(7).ToString();
columnData.Add(lineData);
}
}
}
}
foreach (var item in columnData)
{
Label.Text += item.Column1.ToString() + item.Column2.ToString() + item.Column3.ToString() + item.Column7.ToString();
}
lineData should be declared within while loop. If it was declared before the code you uploaded, then you're referencing the same instance for every data row.
Try change code to following;
while (reader.Read())
{
lineData = new LineData();//like that
lineData must be declared during the cycle at that time. If it is declared before the code you uploaded, you to the same instance for each row of data. Try to change the code on the following;
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();
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.