I want to find how many rows affected when I fire a select query from C#. without insert data into dataset or datatable.
string constr = ConfigurationManager.ConnectionStrings["testConnectionString"].ConnectionString; //get connection string Web.config
SqlConnection con = new SqlConnection(constr);
//define Select Query
SqlCommand slct = new SqlCommand("select * From [dbo].[userdetail] where 1=1", con);
int noRows;
//open connection and execute query
con.Open();
noRows = slct.ExecuteNonQuery();
con.Close();
//define Select Query
SqlCommand select = new SqlCommand("select * From [dbo].[userdetail] where 1=0", con);
//open connection and execute query
con.Open();
noRows = select.ExecuteNonQuery();
con.Close();
First of all for your current query use ExecuteReader() and while reading the loop saying below keep a counter
int count = 0;
while(rdr.Read())
{
count++;
}
Else, use a scalar query like below and use ExecuteScalar() function
select count(*) From [dbo].[userdetail]
SqlCommand cmd = new SqlCommand("select count(*) From [dbo].[userdetail]", con);
// open connection and execute query
con.Open();
int noRows = (int)cmd.ExecuteScalar();
Related
I tried to return a row by executing following SQL query in C#:
SqlCommand cmd = new SqlCommand();
string selectquery = "SELECT TOP (1) [ZVNr] ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
cmd.CommandText = selectquery;
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
try
{
sqlConnection.Open();
int recordsAffected = cmd.ExecuteNonQuery();
if(recordsAffected != -1)
{
return 0;
}
else
{
return 1;
}
And the "ZVNR_TABLE" looks like this:
ZVNR | varchar (50)
20170530-01
The result is always --> recordsAffected = -1
Although when I'm executing the same SQL query in Microsoft SQL Server Management Studio, it works.
You're using a SELECT statement in your code with cmd.ExecuteNonQuery which is used for INSERT or UPDATE statements.
You have to use a SQLDataReader (more than 1 row and(!) column) or Scalar (1 row/1col = one "item").
MSDN Example for SQLDataReader:
//SELECT col1, col2, ..., coln FROM tbl;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
MSDN Example for ExecuteScalar:
//SELECT COUNT(*) FROM region; or any other single value SELECT statement
int count = (int)cmd.ExecuteScalar(); //cast the type as needed
If you want the affected count after you change items in your database, you can get it by using cmd.ExecuteNonQuery which returns that count:
MSDN Example for ExecuteNonQuery:
//INSERT INTO tbl (...) VALUES (...) or any other non-query statement
int rowsAffected = (Int32)cmd.ExecuteNonQuery();
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
Because you are Selecting the data from the datatable not inserting or updating the records that's why recordsAffected is always -1
Answers given above are ok but if you want just to see if it exist you can do a count instead
using (SqlConnection connection = new SqlConnection(connectionstring))
{
string query = "SELECT Count([ZVNr]) ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
try
{
connection.Open();
int result = (int)cmd.ExecuteScalar();
}
}
}
ExecuteNonQuery() is used for INSERT or UPDATE statements and returns the number of rows affected.
If you want to return a single field of a row, you have to use ExecuteScalar()
using (SqlConnection connection = new SqlConnection(connectionstring))
{
string query = "SELECT TOP (1) [ZVNr] ZVNR_TABLE WHERE [ZVNr] = #zvnr order by [ZVNr] DESC";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("#zvnr", "20170530-01");
connection.Open();
object result = cmd.ExecuteScalar();
}
}
private void fillProduct() {
SqlConnection conn = new SqlConnection("Data Source=STATION21\\SQLEXPRESS;Initial Catalog=mydb;Integrated Security=true");
conn.Open();
string query = "Select prodID from product";
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0) {
cmbPCode.DataSource = dt;
cmbPCode.DisplayMember = "prodID";
cmbPCode.ValueMember = "prodID";
}
private void cmbPCode_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=STATION21\\SQLEXPRESS;Initial Catalog=mydb;Integrated Security=true");
con.Open();
string query = "Select * from product where prodID = '"+cmbPCode.Text+"'".ToString();
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
tbdc.Text = dr["prodDescription"].ToString();
}
}
i am having trouble with getting my items from the database according to the selected index i get this error
Conversion failed when converting the varchar value
'System.Data.DataRowView' to data type int
can someone please help me how to convert SqlDataReader to String. because i notice that when i retrieve a column with varchar/string datatype i am not having this kind error but if i retrieve a column with int datatype i get this error.
Replace This:
string query = "Select * from product where prodID = '"+cmbPCode.Text+
"'".ToString();
With This:
string query = "Select * from product where prodID = "+cmbPCode.Text;
Suggestion: Your query is open to SQL Injection i would suggest you to use parameterised queries to avoid them.
Using Parameterised Queries:
string query = "Select * from product where prodID = #ID";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#ID",cmbPCode.Text);
I knew this is simple but I am not able to think. Displaying the count of a record from table and display it on textbox.
private void gMapControl1_Load_1(object sender, EventArgs e)
{
SqlConnection conDatabase = new SqlConnection(constring);
conDatabase.Open();
DataTable db = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) from [ICPS].[dbo].[excel GPS postcode]",
conDatabase);
sda.Fill(db);
textBox29.Text = ;
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) from [ICPS].[dbo].[excel GPS postcode] "
+ "where Region = '1'",
conDatabase);
sda.Fill(db);
textBox30.Text = ;
}
You just need to use SqlCommand.ExecuteScalar instead of SqlDataAdapter like this:
SqlCommand com = new SqlCommand("select count(site) from [ICPS].[dbo].[excel GPS postcode]", conDatabase);
object count = com.ExecuteScalar();
if(count != null) textBox29.Text = count.ToString();
//The same for textBox30
More info on ExecuteScalar
Note that the code I posted is just for the idea of using ExecuteScalar, it depends on your code style when working with ADO.NET, you may want to use some using statement, or reuse your command, ... in your own way you like.
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
cmd.CommandText = "select count(site) from [ICPS].[dbo].[excel GPS postcode]";
Int32 count = (Int32) cmd.ExecuteScalar();
textBox29.Text = count.ToString();
}
When you expect just one value returned by your sql command, then use ExecuteScalar from the command object
string cmdText1 = "select count(site) from [ICPS].[dbo].[excel GPS postcode]";
using(SqlConnection conDatabase = new SqlConnection(constring))
using(SqlCommand cmd = new SqlCommand(cmdText, conDatabase))
{
conDatabase.Open();
int numRec = Convert.ToInt32(cmd.ExecuteScalar());
textBox29.Text = numRec.ToString();
}
MSDN says
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored
However I have noticed that you try to read the record count from two different queries.
So your code could also be written in this way to avoid a roundtrip to the database
string cmdText = "select count(site) from [ICPS].[dbo].[excel GPS postcode];" +
"select count(site) from [ICPS].[dbo].[excel GPS postcode] " +
"where Region = '1'", ;
using(SqlConnection conDatabase = new SqlConnection(constring))
using(SqlCommand cmd = new SqlCommand(cmdText, conDatabase))
{
conDatabase.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
int numRec1 = Convert.ToInt32(reader[0]);
reader.NextResult();
reader.Read();
int numRec2 = Convert.ToInt32(reader[0]);
textBox29.Text = numRec1.ToString();
textBox30.Text = numRec2.ToString();
}
}
In this way I have taken advantage of the ability of SQL Server to execute two or more commands separated by a semicolon.
To fetch a value from datatable use row[columnName]
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) As siteCount from [ICPS].[dbo].[excel GPS postcode]",
conDatabase);
sda.Fill(db);
if(db !=null && db.Rows.Count > 0)
textBox29.Text =db["siteCount"].tostring();
else
textBox29.Text ="0";
However as King King suggested here why use datatable if you have to fetch just a single row and single column use ExecuteScalar method .
Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. -MSDN
SqlCommand com = new SqlCommand("select count(site) from [ICPS].[dbo].[excel GPS postcode]", conDatabase);
object siteCount = com.ExecuteScalar();
if(siteCount != null) textBox29.Text = siteCount.ToString();
string constr = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Users\yogi\Documents\mydb.mdb";
string cmdstr = "select * from quant_level1";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand com = new OleDbCommand(cmdstr, con);
con.Open();
OleDbDataReader reader = com.ExecuteReader();
reader.Read();
DataSet data = new DataSet();
int i = data.Tables["quant_level1"].Rows.Count;
Label2.Text = i.ToString();
use
string cmdstr = "SELECT COUNT(*) FROM quant_level1";
With com.ExecuteScalar()
using(OleDbConnection conn = new OleDbConnection(constr))
using(OleDbCommand command = new OleDbCommand(cmdstr, conn))
{
conn.Open();
int count = (int)command.ExecuteScalar();
}
ExecuteScalar returns the first column of the first row in the result set returned by the query, here it give you row count.
you can use OleDbDataReader as you try in your code sample. but need to change the logic bit.
using (OleDbConnection con = new OleDbConnection(constr))
using (OleDbCommand com = new OleDbCommand("select * from quant_level1", con))
{
con.Open();
using (OleDbDataReader myReader = com.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(myReader);
int count = dt.Rows.Count;
}
}
Why you fail!
You have created data set but you haven't load data to dataset using your DataReader. So you will get zero row count at the end.
Looks like that you want to fill your DataSet and count the rows later:
DataSet data = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(com);
da.Fill(data);
int i = data.Tables[0].Rows.Count;
Label2.Text = i.ToString();
If you just want to count the rows, you can change the query to SELECT COUNT(*) FROM quant_level1 and get the return value like this:
int i = (int) com.ExecuteScalar();
Label2.Text = i.ToString();
You should do something like this:
Select count(*) from quant_level1
Change the command syntax executescalar to retrieve a single value
CommandText = "SELECT COUNT(*) FROM region";
Int32 count = (int32) ExecuteScalar();
Hope this can enlighten you a bit
I'm using this video to try and populate results from a DataGridView, and am receiving the above error. The below code pertains to this error - I pass values into a stored procedure, then the final SELECT returns the values in the table in the DataGridView.
SqlConnection con = new SqlConnection();
con.ConnectionString = "integrated security=SSPI;data source=SERV;" + "persist security info=False;initial catalog=DB";
con.Open();
SqlCommand select = new SqlCommand("SELECT * FROM Table");
SqlCommand enter = new SqlCommand("sp_Proc", con);
// Stored Procedure
enter.CommandType = CommandType.StoredProcedure;
enter.Parameters.Add(new SqlParameter("#vvalue", SqlDbType.VarChar)).Value = Convert.ToString(txt1.Text);
enter.Parameters.Add(new SqlParameter("#dvalue", SqlDbType.Decimal)).Value = Convert.ToDecimal(txt2.Text);
enter.ExecuteNonQuery();
// DataGrid returns the SELECT
SqlDataAdapter sadapt = new SqlDataAdapter(select);
sadapt.SelectCommand = select;
DataTable dtab = new DataTable();
sadapt.Fill(dtab); // generates the error
BindingSource b = new BindingSource();
b.DataSource = dtab;
dGrid.DataSource = b;
sadapt.Update(dtab);
con.Close();
You did not pass connection object on the command. Try this instead,
SqlCommand select = new SqlCommand("SELECT * FROM Table", con);
You are passing connection object to your enter command but didnt pass the connection object to your select command
SqlCommand select = new SqlCommand("SELECT * FROM Table");
SqlCommand enter = new SqlCommand("sp_Proc", con);
Use this
SqlCommand select = new SqlCommand("SELECT * FROM Table",con);
SqlCommand cmd = new SqlCommand("sp_StockAnalysis2") // connection missing in sqlcommand
SqlCommand cmd = new SqlCommand("sp_StockAnalysis2",Connection())// pass connection