How to make 2 select statements in one query? - c#

i got a database table that contains:
Name,X,Y,Z
here's the part i'm selecting some values from the database :
MySqlConnection myConn = new MySqlConnection(myConnection);
MySqlCommand command = myConn.CreateCommand();
command.CommandText = "SELECT Name , X, Y, Z FROM gestures ";
MySqlDataReader myReader;
try
{
myConn.Open();
myReader = command.ExecuteReader();
while (myReader.Read())
{
FromDB.Name = myReader[0].ToString();
MPoint asdd = new MPoint((double)myReader[1], (double)myReader[2], (double)myReader[3]);
FromDB.FDB.Add(asdd);
}
files.Add(FromDB);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
myConn.Close();
what i'm asking for is how to select distinct name instead of selecting the repeated names and selecting all the X,Y,Z points even the repeated ones
i hope i clarified my question

To select all records on a unique column from a MySQL database using C#:
using MySql.Data.MySqlClient;
...
var connectionString = "<insert connection string here>";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
var query = "select * from gestures group by name";
var command = new MySqlCommand(query, connection);
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var name = reader.GetString(0);
var pointX = reader.GetInt32(1);
var pointY = reader.GetInt32(2);
var pointZ = reader.GetInt32(3);
Console.WriteLine($"{name}: {x},{y},{z}");
}
}
}
Edit: Link to MySQL C# documentation.

Related

Sql query not returning all results

I'm using an OLEDB Command to run a basic query on a .mdb file like so:
List<TPRItem> itemList = new List<TPRItem>();
string connStr = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dirPath;
string sql = "SELECT UPC, ItemDesc, TPRAllow, NetCost, UnitCost, Pack, TPREndDate FROM OrderGuide WHERE TPRAllow > 0";
using (OleDbConnection conn = new OleDbConnection(connStr))
{
OleDbCommand cmd = new OleDbCommand(sql, conn);
try
{
conn.Open();
using (OleDbDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
TPRItem thisTPRItem = new TPRItem();
thisTPRItem.UPC = rdr["UPC"].ToString();
thisTPRItem.VendorDescription = rdr["ItemDesc"].ToString();
thisTPRItem.CaseAllowance = decimal.Parse(rdr["TPRAllow"].ToString());
thisTPRItem.CaseCost = decimal.Parse(rdr["NetCost"].ToString());
thisTPRItem.UnitCost = decimal.Parse(rdr["UnitCost"].ToString());
thisTPRItem.CsPack = int.Parse(rdr["Pack"].ToString());
thisTPRItem.EndDate = DateTime.Parse(rdr["TPREndDate"].ToString());
thisTPRItem.CaseAllowanceCost = thisTPRItem.CaseCost - thisTPRItem.CaseAllowance;
thisTPRItem.UnitAllowanceCost = thisTPRItem.CaseAllowanceCost / thisTPRItem.CsPack;
itemList.Add(thisTPRItem);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Only 2365 items are added to my list. However when I run this exact same query in Access I get 10867 results.
I am accessing a .mdb file that changes from month to month (the data changes not the format) and previously we have not had issues with missing items.
Change your provider to a higher version.

Sql reader returning DBnull for every row

I am trying to display pictures from my SQLSEVER database on my website. My users have a picture field with a picture datatype. If the picture column is null, then I want the picture displayed to be a egg.jpg, but right now for every person their picture is egg.jpg, even if they have a picture in the database. Here is my method.
public string getImageUrl()
{
System.Data.SqlClient.SqlConnection sc = new System.Data.SqlClient.SqlConnection();
sc.ConnectionString = "Server =MRCOMPUTER2\\SQLEXPRESS; Database = WBL;Trusted_Connection=Yes;";
sc.Open();
System.Data.SqlClient.SqlCommand insert = new System.Data.SqlClient.SqlCommand();
insert.Connection = sc;
insert.CommandText = "SELECT profilePicture from SystemUser";
insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
string url = "";
while (reader.Read())
{
if ( !DBNull.Value.Equals(reader[0]))
{
url = "data:Image / png; base64," + Convert.ToBase64String((byte[])reader[0]);
}
else {
url = "images/egg.jpg";
}
}
return url;
}
Your code returns the image for the last user in your table.
Here:
insert.CommandText = "SELECT profilePicture from SystemUser";
you select all users from the table (not just the one you currently show). Then:
while (reader.Read())
{
...
url = ...
...
}
you re-assign url inside every iteration of your while loop. This is semantically equivalent to:
url = ... /* The value determined from the last record of the reader. */
Thus, all your users show the same image - the one of the last user in your table.
You SELECT statement is attached into a ExecuteNonQuery?
Take it off.
Just perform the READER statement...
Try this:
static void Main(string[] args)
{
string connectionString = "Server=.;Database=AA;Trusted_Connection=True;";
/*
CREATE TABLE [dbo].[SystemUser]
(
[ProfilePicture] [varbinary](max) NULL
)
*/
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (#ProfilePicture);
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (NULL);
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
byte[] bytes = File.ReadAllBytes(#"1.jpg");
command.Parameters.AddWithValue("#ProfilePicture", bytes);
connection.Open();
command.ExecuteNonQuery();
}
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
SELECT TOP 1000 [ProfilePicture] FROM [AA].[dbo].[SystemUser];
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds);
}
var rows = ds.Tables[0].Rows.Cast<DataRow>();
foreach (DataRow row in rows)
{
byte[] bytes = row.Field<byte[]>(0);
if (bytes != null)
{
string fileName = Guid.NewGuid().ToString("N") + ".jpg";
File.WriteAllBytes(fileName, bytes);
}
}
}
Can you try using the name of the column such as
var Val = (String)reader["column name"];
Also, try something like this to test:
while (reader.Read())
{
var testVal = reader.GetString(0);
Var testVal2 = reader.GetString(1);

C# MySqlConnector next query in the same connection

I have the following code:
string myConnection = "server=localhost;database=test;uid=test;password=test";
string query = "SELECT label_type, label, quantity FROM system_printserver WHERE print=0";
try
{
MySqlConnection myConn = new MySqlConnection(myConnection);
myConn.Open();
MySqlCommand command = new MySqlCommand(query, myConn);
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
MySqlDataReader myReader;
myReader = command.ExecuteReader();
while (myReader.Read()) {
orderNumber = myReader.GetString(1);
myReader.Close();
string queryOrder = "SELECT id_order, id_carrier FROM ps_orders WHERE id_order=28329";
MySqlCommand commandOrder = new MySqlCommand(queryOrder, myConn);
MySqlDataReader myReaderOrder;
myReaderOrder = commandOrder.ExecuteReader();
idCarrier = myReaderOrder.GetString(1);
printDocument1.Print();
}
I have a problem because the second query string queryOrder doesn't work. The query is Ok but variable "idCarrier" doesn't accept any value.
I don't believe you can attach another reader to a connection, when one is already open and processing records. You must retrieve all your records first, i.e. ToList() or Dataset, or use a secondary connection for the second reader.
To make your life easier, consider using Dapper or Linq2Db, two awesome micro-ORMs.
Try it like this:
using(var connection = new MySqlConnection("server=localhost;database=test;uid=test;password=test") {
connection.Open();
int orderNumber = 0;
using (var command = connection.CreateCommand()) {
command.CommandText = #"SELECT label_type, label, quantity FROM system_printserver WHERE print=0";
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
var reader = command.ExecuteReader();
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
if(reader.Read()) {
orderNumber = Convert.ToInt32(reader.GetString(1));
}
}
using(var command = connection.CreateCommand()) {
command.CommandText = string.format(#"SELECT id_order, id_carrier FROM ps_orders WHERE id_order={0}",orderNumber);
var reader = command.ExecuteReader();
if(reader.Read()){
printDocument1.Print();
return reader.GetString(1);
}
}
}

Populating an ArrayList with MySQL data

I'm trying to populate two ArrayLists (listOfAnswers and listOfAnswerIDs) with fields from a database ('answer' and 'answer_id').
The following code seems to work perfectly fine when question_id=1 in the string cmdText. However, if I change this to 2 or 3, the ArrayLists remain empty and I don't know why. Any ideas?
I think it's to do with the string cmdGetAnswersQuery as "SELECT * FROM answers WHERE question_id=2" works...
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
ArrayList listOfAnswerIDs = new ArrayList();
ArrayList listOfAnswers = new ArrayList();
try
{
conn.Open();
string cmdText = "SELECT * FROM questions_t WHERE question_id=2";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = ddlModules.SelectedValue;
reader = cmd.ExecuteReader();
if (reader.Read())
{
lblQuestion.Text = reader["question"].ToString();
ViewState["QuestionID"] = reader["question_id"].ToString();
ViewState["AnswerID"] = reader["correct_answer_id"].ToString();
reader.Close();
string cmdGetAnswersQuery = "SELECT * FROM answers WHERE question_id=#QuestionID";
MySqlCommand cmdGetAnswers = new MySqlCommand(cmdGetAnswersQuery, conn);
cmdGetAnswers.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmdGetAnswers.Parameters["#QuestionID"].Value = ViewState["AnswerID"];
reader = cmdGetAnswers.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answer_id"].ToString());
listOfAnswers.Add(reader["answer"].ToString());
}
reader.Close();
populateAnswers(listOfAnswers, listOfAnswerIDs);
}
else
{
reader.Close();
lblError.Text = "(no questions found)";
}
}
catch
{
lblError.Text = "Database connection error - failed to insert record.";
}
finally
{
conn.Close();
}
The actual database contents are shown here:
http://i.imgur.com/3S4lV60.png
http://i.imgur.com/8A913xF.png
I can't say for sure that this is the problem, but the first thing I'd look at is this line of code:
cmdGetAnswers.Parameters["#QuestionID"].Value = ViewState["AnswerID"];
I suspect you want that to be ViewState["QuestionID"].

Retrieving total count from database to c#

This query is been executed in database.
select COUNT(*) from Patient_Data where DummyValue = 'Y';
104
I have to retrieve this number (104) from database to asp.net with c# so that when the count becomes zero I have to disable a button, How to retrieve this number from database into the code. It should be stored as integer.
I have tried these line of code in c#
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("select COUNT(*) as PatientCount from Patient_Data where DummyValue = 'Y' ", cn))
{
try
{
cn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
int Patcount;
if (rdr.Read())
{
//Code Required
}
}
}
catch (Exception ex)
{
// handle errors here
}
}
}
use alias to get the count as below:
select COUNT(*) as PatientCount from Patient_Data where DummyValue = 'Y';
Read the PatientCount value in code.
you can use GetInt32() function to get the count as int.
Note: you are passing the parameter values in your query which leads to Sql Injection Attacks, so you could use Parameterized Sql Queries to avoid them.
sample code is asbelow:
private int readPatientData()
{
int PatientCount = 0;
String strCommand = "select COUNT(*) as PatientCount from Patient_Data where DummyValue = #MyDummyValue";
using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlcommand=new SqlCommand(strCommand,sqlConnection))
{
sqlcommand.Parameters.Add(new SqlParameter("MyDummyValue", 'Y'));
SqlDataReader sqlReader = sqlcommand.ExecuteReader();
if (sqlReader.Read())
PatientCount = sqlReader.GetInt32(0);
}
}
return PatientCount;
}
I solved my issue with these lines of code.
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("select COUNT(*) as PatientCount from Patient_Data where DummyValue = 'Y' ", cn))
{
try
{
cn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
//int Patcount;
if (rdr.Read())
{
int Patcount = int.Parse(rdr["PatientCount"].ToString());
if (Patcount != 0)
{
Label3.Visible = true;
Label3.Text = "You have already have "+Patcount+" dummy records,Please update those records by clicking Update Dummy Records Link.";
btnSkipSubmit.Visible = false;
}
//Code Required
}
}
}
catch (Exception ex)
{
// handle errors here
}
}
}
Update based on code change in question
You can write rdr.GetInt32(3); instead of code required in your code.
previous answer
You need to use ExecuteScalar method while executing your command. Here is the example from msdn:
static public int AddProductCategory(string newName, string connString)
{
Int32 newProdID = 0;
string sql =
"INSERT INTO Production.ProductCategory (Name) VALUES (#Name); "
+ "SELECT CAST(scope_identity() AS int)";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name", SqlDbType.VarChar);
cmd.Parameters["#name"].Value = newName;
try
{
conn.Open();
newProdID = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return (int)newProdID;
}
In this example they are returning newly added product Id.
ExecuteScalar returns object that you can check for null and cast to number as you know with int.parse method or the best one you know.
As Per my knowledge there are three ways to do this:
Using COUNT you can do this as below:
select COUNT(*) as RowCount from Patient_Data where DummyValue = 'Y';
Using ROW_NUMBER you can do this as below:
Select ROW_NUMBER() OVER (ORDER BY Patient_Data.ID DESC) AS RowNumber from Patient_Data where DummyValue = 'Y';
And there is another way but that way is only to get the row count and is the fastest way to get the row count in sql server according to me.
SELECT
Total_Rows= SUM(st.row_count)
FROM
sys.dm_db_partition_stats st
WHERE
object_name(object_id) = 'Patient_Data' AND (index_id < 2)
That's all

Categories