I am trying to see if an ID exists in a database in this case it's vetID.
To see if the result of the SQL query is successfull I am trying to use rdata.FieldCount
FieldCount always seems to return 11 even if the input ID (variable i) is = -400 (an id number that cannot exist in the database). I have also tried with other numbers that are not possible such as 100 or 800 (the database has only 1 - 5 items in it)
var mySQLCommand = new SqlCeCommand("SELECT * FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
if (rdata.FieldCount >= 1)
{
MessageBox.Show(" HAS ROWS "); go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}
MessageBox.Show("rdata FieldCount " + rdata.FieldCount + " i has value " + i);
Is there a more elegant way to check an ID is still valid in the database and has not been deleted?
OK.. before you call me Stupid ... im guessing the FieldCount is just the exactly that the FieldCount and not the FieldCount of the returned Query ... doh...
But the question still stands is there an elegant way to know if the ID is still there in the database?
FieldCount always returns 11 because (I assume) there are 11 columns in the table.
A better way is:
var sql = new SqlCeCommand("select top 1 vetid from vets where vetid = #id", dbCon);
sql.Paramaters.AddWithValue("id", i);
if (null != mySqlCommand.ExecuteScalar())
{
// ID exists
}
If you are using a datareader you can't get a rowcount using fieldcount. But if you wanted to leave the query the same you'd do:
var mySQLCommand = new SqlCeCommand("SELECT * FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
if (rdata.read() )
{
MessageBox.Show(" HAS ROWS ");
go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}
MessageBox.Show("rdata FieldCount " + rdata.FieldCount + " i has value " + i);
Another way to check is to use a select count(*) to see if it's in the table and that would be 0 if it doesn't exist.
var mySQLCommand = new SqlCeCommand("SELECT count(*) FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
int rowCount = 0;
if ( rdata.read() ) {
rowCount = rdata[0];
}
An sql reader is a forward reader only - so you cannot get the number of rows form a property. FieldCount is the number of columns in the current record. The only way to the get the number of rows returned is to read them all in or to run a count query before hand (which might not be concurrency safe)
Try using the HasRows property instead:
if (rdata.HasRows)
{
MessageBox.Show(" HAS ROWS "); go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}
Related
Since yesterday I am trying to get this value (see image), I have tried to use "mysqlreader, executescalar and more", but I cannot get the number of lines.
What I want to do is this:
If the result is 0 it does nothing, if equal to 1 it must show an image, if greater than 1 it must show another image
ex code 1
private void patient()
{
if (OpenEventMissionData.Rows.Count != 0)
{
foreach (DataGridViewRow row in OpenEventMissionData.Rows)
{
string idevent = row.Cells[1].Value.ToString();
string sql = "SELECT COUNT(*) FROM patient INNER JOIN event WHERE patient.ID_EVENT = " + "'" + idevent + "'" + "AND evento.EVENT_OPEN = 1;";
MySqlConnection connection = new MySqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings["dbx"].ConnectionString;
MySqlCommand cmd = new MySqlCommand(sql, connection);
connection.Open();
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
DataGridViewButtonColumn patient = new DataGridViewButtonColumn();
OpenEventMissionData.Columns.Add(new PatientColumn());
}
}
}
}
I tried adding the code that told me #oldDog, but the result is always 6
ex code 3
NEW EDIT:
In fact 6 lines appear.
phpmyadmin
Your problem here is you are using HasRows. Since you are doing SELECT COUNT(*) you will always have one row which will contain the count, even if the count is zero. Instead you could use:
if (Convert.ToInt32(reader[0]) > 0)
Example: If I have ID column in 4 tables (candidate, exam, interview, final_list) and I want to know my status (i.e if I am enter id = 10) it displays only "you are in exam list". Even if id 10 also exists in other tables (e.g. interview and final_list). As soon as it gets to the first table containing id, display some message and end. 10q
here is my code
private void button1_Click(object sender, EventArgs e)
{
SqlCommand command;
SqlDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
int i = 0;
string fsql = null;
string ssql = null;
string tsql = null;
string fosql = null;
fsql = "select * from final_list where ID='" + txtcandidateno.Text + "'";
ssql = "select * from interview where ID='" + txtcandidateno.Text + "'";
tsql = "select * from interview where ID='" + txtcandidateno.Text + "'";
fosql = "select * from interview where ID='" + txtcandidateno.Text + "'";
try
{
sql.Open();
command = new SqlCommand(fsql, sql);
adapter.SelectCommand = command;
adapter.Fill(ds, "final_list");
adapter.SelectCommand.CommandText = ssql;
adapter.Fill(ds, "interview");
adapter.SelectCommand.CommandText =tsql;
adapter.Fill(ds, "exam");
adapter.SelectCommand.CommandText = fosql;
adapter.Fill(ds, "candidate");
adapter.Dispose();
command.Dispose();
sql.Close();
//retrieve first table data
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
MessageBox.Show("you are final list");
}
//retrieve second table data
for (i = 0; i <= ds.Tables[1].Rows.Count - 1; i++)
{
MessageBox.Show("you are interview list");
}
for (i = 0; i <= ds.Tables[2].Rows.Count - 1; i++)
{
MessageBox.Show("you are exam list");
}
for (i = 0; i <= ds.Tables[3].Rows.Count - 1; i++)
{
MessageBox.Show("you are normal cadidate list");
}
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection ! ");
}
}
in the above code what it happen it search from final_list to candidate sequentially but if the id is found in first loop it also search other but if the id is not found in first but exist in other table e.g candidate table it does not display. what i want is if the id e.g in second table only display "you are in interview list " and end. search from final_list to candidate until the first table exists that contains the id.
At this point it is impossible to guess what you've tried, or if you are looking for an answer in SQL or C# (as there are no code examples), but it seems that you need to check the tables incrementally? In pseudocode:
if (id is in candidate)
You are in "candidate"
else if (id is in exam)
You are in "exam"
If you are using Linq to SQL that might look like
if (db.Candidate.Any(x => x.Id == id)) {...}
else if (db.Exam.Any(x => x.Id == id)) {...}
I searched on the net something but nothing really helped me. I want to update, with a list of article, a database, but the way that I've found is really slow.
This is my code:
List<Article> costs = GetIdCosts(); //here there are 70.000 articles
conn = new OleDbConnection(string.Format(MDB_CONNECTION_STRING, PATH, PSW));
conn.Open();
transaction = conn.BeginTransaction();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = transaction;
cmd.CommandText = "UPDATE TABLE_RO SET TABLE_RO.COST = ? WHERE TABLE_RO.ID = ?;";
for (int i = 0; i < costs.Count; i++)
{
double cost = costs[i].Cost;
int id = costs[i].Id;
cmd.Parameters.AddWithValue("data", cost);
cmd.Parameters.AddWithValue("id", id);
if (cmd.ExecuteNonQuery() != 1) throw new Exception();
}
}
transaction.Commit();
But this way take a lot of minutes something like 10 minutes or more. There are another way to speed up this updating ? Thanks.
Try modifying your code to this:
List<Article> costs = GetIdCosts(); //here there are 70.000 articles
// Setup and open the database connection
conn = new OleDbConnection(string.Format(MDB_CONNECTION_STRING, PATH, PSW));
conn.Open();
// Setup a command
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE TABLE_RO SET TABLE_RO.COST = ? WHERE TABLE_RO.ID = ?;";
// Setup the paramaters and prepare the command to be executed
cmd.Parameters.Add("?", OleDbType.Currency, 255);
cmd.Parameters.Add("?", OleDbType.Integer, 8); // Assuming you ID is never longer than 8 digits
cmd.Prepare();
OleDbTransaction transaction = conn.BeginTransaction();
cmd.Transaction = transaction;
// Start the loop
for (int i = 0; i < costs.Count; i++)
{
cmd.Parameters[0].Value = costs[i].Cost;
cmd.Parameters[1].Value = costs[i].Id;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
// handle any exception here
}
}
transaction.Commit();
conn.Close();
The cmd.Prepare method will speed things up since it creates a compiled version of the command on the data source.
Small change option:
Using StringBuilder and string.Format construct one big command text.
var sb = new StringBuilder();
for(....){
sb.AppendLine(string.Format("UPDATE TABLE_RO SET TABLE_RO.COST = '{0}' WHERE TABLE_RO.ID = '{1}';",cost, id));
}
Even faster option:
As in first example construct a sql but this time make it look (in result) like:
-- declaring table variable
declare table #data (id int primary key, cost decimal(10,8))
-- insert union selected variables into the table
insert into #data
select 1121 as id, 10.23 as cost
union select 1122 as id, 58.43 as cost
union select ...
-- update TABLE_RO using update join syntax where inner join data
-- and copy value from column in #data to column in TABLE_RO
update dest
set dest.cost = source.cost
from TABLE_RO dest
inner join #data source on dest.id = source.id
This is the fastest you can get without using bulk inserts.
Performing mass-updates with Ado.net and OleDb is painfully slow. If possible, you could consider performing the update via DAO. Just add the reference to the DAO-Library (COM-Object) and use something like the following code (caution -> untested):
// Import Reference to "Microsoft DAO 3.6 Object Library" (COM)
string TargetDBPath = "insert Path to .mdb file here";
DAO.DBEngine dbEngine = new DAO.DBEngine();
DAO.Database daodb = dbEngine.OpenDatabase(TargetDBPath, false, false, "MS Access;pwd="+"insert your db password here (if you have any)");
DAO.Recordset rs = daodb.OpenRecordset("insert target Table name here", DAO.RecordsetTypeEnum.dbOpenDynaset);
if (rs.RecordCount > 0)
{
rs.MoveFirst();
while (!rs.EOF)
{
// Load id of row
int rowid = rs.Fields["Id"].Value;
// Iterate List to find entry with matching ID
for (int i = 0; i < costs.Count; i++)
{
double cost = costs[i].Cost;
int id = costs[i].Id;
if (rowid == id)
{
// Save changed values
rs.Edit();
rs.Fields["Id"].Value = cost;
rs.Update();
}
}
rs.MoveNext();
}
}
rs.Close();
Note the fact that we are doing a full table scan here. But, unless the total number of records in the table is many orders of magnitude bigger than the number of updated records, it should still outperform the Ado.net approach significantly...
I am currently working on an C# project and I am trying to get the number of rows returned from MySQL Data Reader.
I know there is no direct function so I am trying to write my own. In the function, I pass it the MySQLDataReader object and then loop through the MySQL Data Reader and increment a counter and return the value of the counter.
This then seems to lock up the program, I guess because I am Reader.read() after I've got the count I'm already at the end. Instead I have tried creating a copy of the reader and then loop through the temp version but I get the same result.
Below is my code where I am executing the query and calling the function.
string query = "SELECT * FROM reports, software, platforms, versions "
+ "WHERE EmailVerified = #verified AND reports.SoftwareID = software.id AND reports.PlatformID = platforms.id "
+ "AND reports.VersionID = versions.id AND BugReportAcceptedNotificationSent = #notificationSent";
using (MySqlCommand cmd = new MySqlCommand(query, db.conn))
{
cmd.Parameters.AddWithValue("#verified", "1");
cmd.Parameters.AddWithValue("#notificationSent", "0");
using (MySqlDataReader reader = cmd.ExecuteReader())
{
totalEmails = HelperClass.totalRowsInMySQLDataReader(reader);
while (reader.Read())
{
currentEmailCount++;
EmailNotifications emailNotification = new EmailNotifications(reader);
emailNotification.sendNewBugReportAfterVerificationEmail(currentEmailCount, totalEmails);
}
}
}
Below is my function that gets the row count
public static int totalRowsInMySQLDataReader(MySqlDataReader reader)
{
MySqlDataReader tempReader = reader;
ILibraryInterface library = GeneralTasks.returnBitsLibrary(Configuration.databaseSettings, Configuration.engineConfig.logFile);
string methodInfo = classDetails + MethodInfo.GetCurrentMethod().Name;
try
{
int count = 0;
while (tempReader.Read())
{
count++;
}
tempReader = null;
return count;
}
catch (Exception ex)
{
string error = string.Format("Failed to get total rows in MySQL Database. Exception: {0}", ex.Message);
library.logging(methodInfo, error);
library.setAlarm(error, CommonTasks.AlarmStatus.Medium, methodInfo);
return -1;
}
}
Make use of a DataTable to load your results, e.g.
DataTable dt = new DataTable();
dt.Load(reader);
int numberOfResults = dt.Rows.Count;
You can then also iterate over the rows to read the values, e.g.
foreach(DataRow dr in dt.Rows)
{
var value = dr["SomeResultingColumn"]
}
The other option is to issue two separate SQL statements, however you would need to ensure both statements were enclosed within a transaction with a Serializable isolation level, this is needed to make sure records aren't inserted between the execution of the two SQL statements.
To avoid multiple queries, how about including the total in the select itself?
SELECT COUNT(*) AS TotalNORows, * FROM reports, software, platforms, versions etc
i think without executing another command it's not possible...as there is no method available for count in reader class
you can try this... if it works..
string query = "SELECT * FROM reports, software, platforms, versions "
+ "WHERE EmailVerified=#verified AND reports.SoftwareID=software.id AND reports.PlatformID=platforms.id "
+ "AND reports.VersionID=versions.id AND BugReportAcceptedNotificationSent=#notificationSent";
using (MySqlCommand cmd = new MySqlCommand(query, db.conn))
{
cmd.Parameters.AddWithValue("#verified", "1");
cmd.Parameters.AddWithValue("#notificationSent", "0");
using (MySqlDataReader reader = cmd.ExecuteReader())
{
// create a new connection db.conn2 then
MySqlCommand cmd2 = new MySqlCommand(query, db.conn2))
cmd2.Parameters.AddWithValue("#verified", "1");
cmd2.Parameters.AddWithValue("#notificationSent", "0");
MySqlDataReader reader2 = cmd2.ExecuteReader();
int numberofrow=0;
while(reader2.Read())
numberofrow++;
//your codes......
}
Was working on the same problem. I hate having to iterate if a method is already available, but this is was the shortest bit I could come up with:
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader reader = cmd.ExecuteReader();
int rowcount = 0;
while(reader.Read()){
rowcount++;
}
First, create this class:
public static class Extensions
{
public static int Count(this MySqlDataReader dr)
{
int count = 0;
while(dr.Read())
count++;
return count;
}
}
This will implement .Count () on MySqlDataReader.
int count = reader.Count();
Exemple:
string sql= "SELECT * FROM TABLE";
MySqlCommand cmd = new MySqlCommand(sql, connection);
MySqlDataReader reader = cmd.ExecuteReader();
int count = reader.Count();
Maybe you could look things the other way around
You could just do a select count(*) and get the row count
or
use a data adapter to fill a container (like a DataTable) and count the rows
Unfortunatelly solution from Jan Van #Herck will return one row only, so in case you are interested in getting all rows and their number in one select, this isn't what you need.
In that case I suggest uou to try this:
select * , (select count(*) from my_table) AS numRow from my_table;
or read this:
Getting total mysql results returned from query with a limit: FOUND_ROWS error
You can use follwoing SQL Query to get the total rows Count.
SELECT COUNT(*) FROM [MYTABLE]
from the Code you can use ExecuteScalar() method to get the total number of rows returned by QUERY.
Try This:
int GetRowsCount(MySqlCommand command)
{
int rowsCount=Convert.ToIn32(command.ExecuteScalar());
return rowsCount;
}
Use above function as below:
MySqlCommand command=new MySlCommand("Select count(*) from MyTable",connectionObj);
int totalRows = GetRowsCount(command)
OleDbDataReader dbreader = new OleDbDataReader();
int intcount = 0;
if (dbreader.HasRows == true)
{
if (dbreader.Read())
{
intcount = dbreader.RecordsAffected;
}
}
"dbreader.RecordsAffected" will give you the number rows changed,inserted or deleted by the last statement of SQL
Im wondering how to make my checkboxes in column[3]in dtg_ksluzby checked when the value is in the DB.
klisluz(table where I get the data from) contains columns, id, subkey(which is = vyberradek), text, pocet
This is code for inserting into db.
foreach (DataGridViewRow row in dtg_ksluzby.Rows)
{
if (Convert.ToBoolean(row.Cells[3].Value) == true)
{
SqlCommand prikaz2 = new SqlCommand("INSERT INTO klisluz(text,pocet,akce,subkey) values(#val1,#val2,#val3,#val4) ", spojeni);
prikaz2.Parameters.AddWithValue("#val1", row.Cells["text"].Value);
prikaz2.Parameters.AddWithValue("#val2", row.Cells["pocet"].Value);
prikaz2.Parameters.AddWithValue("#val3", row.Cells["akce"].Value);
prikaz2.Parameters.AddWithValue("#val4", max + 1);
spojeni.Open();
prikaz2.ExecuteNonQuery();
spojeni.Close();
}
}
Now I would like to check the checkbox when the item is inserted in DB.
Would someone propose me a clue please?
I think I can algorithm this isssue, but I have no idea how can I turn it into the code I thought I can do it somehoe like this :
SqlCommand novyprikaz3 = new SqlCommand("SELECT * FROM klient WHERE ID_K=" + vyberradek, spojeni); //vyberradek selects row ID
spojeni.Open();
SqlDataReader precti = novyprikaz.ExecuteReader();
if (precti.Read())
{
If text in (row where ID_K=number which comes from vyberradek) is in dtg_ksluzby then check the checkbox in the same row
}
I would like to use this for USER to know which columns did he selected before when he is editing
Thank so much in advance.
for (int i = 0; i < dtg_ksluzby.Rows.Count; i++)
{
var row = dtg_ksluzby.Rows[i];
using(var novyprikaz2 = new SqlCommand("SELECT * FROM klient WHERE ID_K=" + vyberradek, spojeni))
{
spojeni.Open();
SqlDataReader precti2 = novyprikaz2.ExecuteReader();
if (precti2.HasRows)
{
row.Cells[3].Value = true;
}
}
}
You have to change vyberradek accordingly to row content.
Try to count it and use ExecuteScalar as below
SqlCommand novyprikaz3 = new SqlCommand("SELECT count(1) FROM klient WHERE ID_K=" + vyberradek, spojeni); //vyberradek selects row ID
spojeni.Open();
Int32 cnt = (Int32) novyprikaz.ExecuteScalar();
If cnt is more than 0 the items exists.