windows service integration with sql using ado .net - c#

**public static void göster()
{
SqlConnection connection =GetConnection.GetConnectionObject();
//TODO parametreleri command.parameters yoluyla alsın
SqlCommand command = new SqlCommand();
command.CommandText= "select * from windowsserv";
command.Connection = connection;
if (connection.State != ConnectionState.Open)
connection.Open();
Console.WriteLine("Connection opened");
SqlDataReader rdr = command.ExecuteReader();
while(rdr.Read())
{
------------------> Console.WriteLine(rdr[0].ToString()+"--"+rdr[1].ToString());
}
if (connection.State != ConnectionState.Closed)
connection.Close();
Console.WriteLine("Connection Closed.");
Console.ReadLine();
}
Hi all, This is my code and also there are more that ı didn't show,I recorded data to sql server. This code block(pointed with arrow) shows all sql server data and ı want to see only last data (recorded to sql server) in console. But ı could't find any answer. Please help.**

In this line
command.CommandText= "select * from windowsserv";
you can use some SQL Filters and Ordering, like: (This will return last 10 register based on a date filter.. now you need to know what range your (last data) has been recorded to get exactly what you need.
Replace (date_column) with a column in your table who have this kind of data.
select top 10 * from windowsserv where (date_column) between '2017-09-12 00:00:00' and '2017-09-13 00:00:00' order by (date_column) DESC
Then in your code you will have something like this:
SqlCommand command = new SqlCommand();
command.CommandText = "select * from select top 10 * from windowsserv where (date_column) between \'2017-09-12 00:00:00\' and \'2017-09-13 00:00:00\' order by (date_column) DESC";
You can improve your code as well doing this:
using (SqlConnection connection = GetConnection.GetConnectionObject())
{
//TODO parametreleri command.parameters yoluyla alsın
var command = new SqlCommand
{
CommandText = "select * from windowsserv",
Connection = connection
};
if (connection.State != ConnectionState.Open)
connection.Open();
Console.WriteLine("Connection opened");
var rdr = command.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr[0] + "--" + rdr[1]);
}
}

try changing your while loop to.
bool isLast = rdr.Read();
while(isLast)
{
string firstCol = rdr[0].ToString();
string secondCol = rdr[1].ToString();
isLast = rdr.Read();
if(!isLast)
{
Console.WriteLine(firstCol+"--"+secondCol);
break;
}
}

Related

AVG QUERY in c#

Good morning, I'm developing a code that can get me out of my database in sql, the AVG of a certain column.
The problem is that I'm not getting it, I think the problem is the query but I do not know how to solve it.
I need help, thank you.
Here is the code:
String connectionString =
"Data Source=localhost;" +
"Initial Catalog=DB_SACC;" +
"User id=sa;" +
"Password=1234;";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
string textt = " USE [DB_SACC] SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
if (textt == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = textt;
}
use ExecuteScalar if you request a single value from your database - ExecuteNonQuery returns just the number of affected rows which is used in update / insert statements
USE [DB_SACC] is not required in your query since you define the "Initial Catalog=DB_SACC;"
add using to avoid open connections
Code:
string connectionString = "Data Source=localhost;Initial Catalog=DB_SACC;User id=sa;Password=1234;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
using (SqlCommand cmd = new SqlCommand(textt, connection))
{
connection.Open();
var result = cmd.ExecuteScalar(); //write the result into a variable
if (result == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = result.ToString();
}
}
}
Use cmd.ExecuteScalar() method instead:
decimal average = (decimal) cmd.ExecuteScalar();
cmd.ExecuteNonQuery(); only returns the number of rows effected where as what you want is to read the result set of SELECT statement.
I would also get rid of USE [DB_SACC] from your SELECT statement since you are defining the database name in your connection string.
EDIT
Your code should look like this:
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
decimal average = (decimal) cmd.ExecuteScalar();
if (textt == null)
{
MessageBox.Show("nothing");
}
else
{
TextBox3.Text = average.ToString();
}
EDIT 2:
try
{
string textt = "SELECT AVG (Total_Divida) FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
decimal average = (decimal)cmd.ExecuteScalar();
TextBox3.Text = average.ToString();
}
catch(Exception ex)
{
// log your exception here...
MessageBox.Show("nothing");
}
EDIT 3:
In the light of your recent comments try this
string connectionString = "Data Source=localhost; Initial Catalog=DB_SACC; User id=sa Password=1234;";
decimal? average;
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
string textt = "SELECT AVG (Total_Divida) AS 'AVG_DIVIDA' FROM t_pagamentos";
cmd.CommandText = textt;
connection.Open();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
using (DataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
average = decimal.parse(reader["AVG_DIVIDA"].ToString());
break;
}
}
}
}
TextBox3.Text = average.HasValue ? average.ToString() : "Unknown error occurred";
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrieve the average, reason: " + ex.Message);
}
Note: Using DataReader to get just single value from database is not preferred. I am proposing this because of the error you mentioned in the comments.
If you are getting any SQL Exception then try to run this statement on SQL Server as stand alone test.
USE DB_SACC
GO
SELECT AVG (Total_Divida) AS 'AVG_DIVIDA' FROM t_pagamentos
GO
If you still encounter any error while executing T-SQL Statement then please post that as another question.

how two get data from 2 different table c#

I have two table.I need to get calorificValue from the food table and daily_gained from the calorie_tracker table to then make some calculations.I've written this code, I know it not efficent. It retrieves daily_gained but failed to get calorificValue.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
MySqlCommand cmd2 = new MySqlCommand("SELECT sportsman_id,daily_gained FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
cmd2.Connection.Open();
MySqlDataReader rd = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
int burned = 0;
if (rd.HasRows) // if entered username and password have the data
{
while (rd.Read()) // while the reader can read
{
if (rd["sportsman_id"].ToString() == Login.userID) // True for admin
{
burned += int.Parse(rd["daily_gained"].ToString());
}
}
}
cmd2.Connection.Close();
cmd.Connection.Open();
MySqlDataReader rd2 = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (rd2.HasRows) // if entered username and password have data
{
while (rd2.Read()) // while the reader can read
{
if (rd2["name"].ToString() == s)
{
burned += int.Parse(rd2["calorificValue"].ToString());
}
}
}
MessageBox.Show(burned+"");
DataTable tablo = new DataTable();
string showTable = "SELECT * from myfitsecret.calorie_tracker where sportsman_id=#sportsman_id";
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand showCommand = new MySqlCommand();
showCommand.Connection = cnn;
showCommand.CommandText = showTable;
showCommand.CommandType = CommandType.Text;
showCommand.Parameters.AddWithValue("#sportsman_id", Login.userID);
adapter.SelectCommand = showCommand;
adapter.Fill(tablo);
dataGridView1.DataSource = tablo;
cnn.Close();
Why don't you just use the scalar function SUM and let the database do its job instead of writing a lot of code?
int burned = 0;
string s = comboBox1.SelectedItem.ToString();
cnn.Open();
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
cmdText = #"SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
Not visible from your code, but also the connection should be created inside a using statement (very important with MySql that is very restrictive with simultaneous open connections)
We could also use a different approach putting the two commands together and separating them with a semicolon. This is called batch commands and they are both executed with just one trip to the database. Of course we need to fallback using the MySqlDataReader to get the two results passing from the first one to the second one using the NextResult() method (see here MSDN for Sql Server)
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name;
SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
// Add both parameters to the same command
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
cnn.Open();
using(MySqlDataReader reader = cmd.ExecuteReader())
{
// get sum from the first result
if(reader.Read()) burned += Convert.ToInt32(reader[0]);
// if there is a second resultset, go there
if(reader.NextResult())
if(reader.Read())
burned += Convert.ToInt32(reader[0]);
}
}
Your issues could be around closing a connection and then trying to open it again. Either way it's fairly inefficient to be closing and opening connections.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
MySqlCommand cmd2 = new MySqlCommand("SELECT SUM(daily_gained) FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
cnn.Open();
MySqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows) // if entered username and password have data
{
while (rd.Read()) // while the reader can read
{
burned += int.Parse(rd["calorificValue"].ToString());
}
}
burned = cmd2.ExecuteScalar();
MessageBox.Show(burned+"");
cnn.Close();

SQL Performance Issue ASP.Net App

We have a performance Issue in our ASP.NET based web App and it's visible only once when we login in the morning. As per Log looks like below query takes more than 1 minute 20 secs. Next time onward when user login to the app and try to access same page doesn't find any issue. Can you please let me know how to optimize this query ? Any thoughts how we can fix this problem ?
Log -
"11/13/15","08:38:27","ExecuteSql - ---3---- ","8",""
"11/13/15","08:38:27","ExecuteSql - ---4---- : SQL : SELECT TOP 1 CONVERT(varchar(15), Period_End_Date, 107) as PDate FROM PBHISTORY..STATEMENT_OF_CHANGE
ORDER BY Period_End_Date DESC","8",""
"11/13/15","08:39:48","ExecuteSql - ---5---- ","8",""
SQL :
SELECT TOP 1
CONVERT(varchar(15), Period_End_Date, 107) as PDate
FROM
PBHISTORY..STATEMENT_OF_CHANGE
ORDER BY
Period_End_Date DESC
C# ASP.NET -
public string GetDateRangeReportingDate(int reportId)
{
var report = GetReportInfoById(reportId);
string sql = string.Format(#"SELECT TOP 1 CONVERT(varchar(15), Period_End_Date, 107) as PDate FROM {0}..{1} ORDER BY Period_End_Date DESC", _historyDatabase, report.SourceTableName);
var data = ExecuteSql(sql);
while (data.Read())
{
return data["PDate"].ToString();
}
return null;
}
private SqlDataReader ExecuteSql(string sql)
{
SqlDataReader reader;
SqlConnection conn;
var commandTimeOut = ConfigurationManager.AppSettings["PBReportCommandTimeout"].ToString();
string connString = ConfigurationManager.ConnectionStrings["PBReportCS"].ConnectionString;
conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandTimeout = int.Parse(commandTimeOut);
reader = cmd.ExecuteReader();
return reader;
}
I found solution of my performance issue I mentioned above. Issue was wrong indexing in table and I fixed this issue by changing the indexing of table where from we are fetching records in production.
Also, I fixed Framework level entity class by using SQL Data Adapter and using statements. App runs super fast in production. Thanks for your help.
private string ExecuteSqlNew(string sql)
{
string connectionString = ConfigurationManager.ConnectionStrings["PBReportCS"].ConnectionString;
string commandTimeOut = ConfigurationManager.AppSettings["PBReportCommandTimeout"].ToString();
DataSet result = new DataSet();
string pDate = "";
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.CommandTimeout = int.Parse(commandTimeOut);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
adapter.Fill(result);
adapter.Dispose();
conn.Close();
pDate = result.Tables[0].Rows[0]["PDate"].ToString();
}
}
}
catch(Exception ex)
{
throw ex;
}
return pDate;
}

Checking and creating a View within MySQL via C#

I need to be able to see if a View already exists within my MySQL database and if it doesn't create one - through c#. I really could do with a bit of help and a point in the right direction - if possible.
You can use information_schema to query if a sever object, view in your case, exists. My example code snippet in C# is as below.
String conn = #"Data Source=myserverName;
Initial Catalog=myCatalogName;Integrated Security=True";
string cmdStr = "select count(*) from
information_schema.views where table_schema = 'mySchemaName'
AND table_name = 'MyViewName'";
using (MySqlConnection conn = new MySqlConnection(conn))
{
MySqlCommand cmd = new MySqlCommand(cmdStr, conn);
conn.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int count = reader.GetInt32(0);
if (count == 0)
{
MessageBox.Show("View does not exists!");
MySqlCommand command = new MySqlCommand("Create View myView
as select
* from myTable;", conn)
command.ExecuteNonQuery();
}
else if (count == 1)
{
MessageBox.Show("View exists!");
}
conn.Close();
}
}
Can't you use create or replace view view_name as... ?

using the same instance of SQLCommand more than one time in the same code for more than one query?

I have question about using why i can not use the same instance of SQLCommand more than one time in the same code?
I tried the code down here and it runs good for the gridview but when i changed the query by using cmd.CommandText() method it keeps saying:
There is already an open DataReader associated with this Command which must be closed first.
This is the code:
string cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Select top 10 FirstName, LastName, Address, City, State from Customers";
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
finally
{
con.Close();
}
The problem is that you are using the SqlCommand object to generate a DataReader via the command.ExecuteReader() command. While that is open, you can't re-use the command.
This should work:
using (var reader = cmd.ExecuteReader())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
//now the DataReader is closed/disposed and can re-use command
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
There is already an open DataReader associated with this Command which must be closed first.
This is the very reason you don't share a command. Somewhere in your code you did this:
cmd.ExecuteReader();
but you didn't leverage the using statement around the command because you wanted to share it. You can't do that. See, ExecuteReader leaves a connection to the server open while you read one row at a time; however that command is locked now because it's stateful at this point. The proper approach, always, is this:
using (SqlConnection c = new SqlConnection(cString))
{
using (SqlCommand cmd = new SqlCommand(sql, c))
{
// inside of here you can use ExecuteReader
using (SqlDataReader rdr = cmd.ExecuteReader())
{
// use the reader
}
}
}
These are unmanaged resources and need to be handled with care. That's why wrapping them with the using is imperative.
Do not share these objects. Build them, open them, use them, and dispose them.
By leveraging the using you will never have to worry about getting these objects closed and disposed.
Your code, written a little differently:
var cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
var gridSql = "Select top 10 FirstName, LastName, Address, City, State from Customers";
var cntSql = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
try
{
using (SqlCommand cmd = new SqlCommand(gridSql, con))
{
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
}
using (SqlCommand cmd = new SqlCommand(cntSql, con))
{
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
}
Thank u quys but for the guys who where talking about using block !
why this code work fine which i seen it on example on a video ! It's the same thing using the same instance of SqlCommand and passing diffrent queries by using the method CommanText with the same instance of SqlCommand and it's execute just fine , this is the code :
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Delete from tbleProduct where ProductID= 4";
int TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "Insert into tbleProduct values (4, 'Calculator', 100, 230)";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "ypdate tbleProduct set QtyAvailbe = 234 where ProductID = 2";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
}

Categories

Resources