SQL query to scalar result in C# - c#

In some programming contexts getting a scalar value from a sql query is easy:
RowCount = Connection.Execute("SELECT Count(*) FROM TableA").Fields(0).Value
In C#, given a SqlConnection variable conn that is already open, is there a simpler way to do this same thing without laboriously creating a SqlCommand, a DataReader, and all in all taking about 5 lines to do the job?

SqlCommand has an ExecuteScalar method that does what you want.
cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
Int32 count = (Int32) cmd.ExecuteScalar();

If you can use LINQ2SQL (or EntityFramework) you can simplify the actual query asking to
using (var context = new MyDbContext("connectionString"))
{
var rowCount = context.TableAs.Count();
}
If LINQ2SQL is an option that has lots of other benefits too compared to manually creating all SqlCommands, etc.

There is ExecuteScalar which saves you at least from the DataReader:
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;
}
(Example taken from this MSDN documentation article)

You do not need a DataReader. This example pulls back the scalar value:
Object result;
using (SqlConnection con = new SqlConnection(ConnectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand(SQLStoredProcName, con)) {
result = cmd.ExecuteScalar();
}
}

Investigate Command.ExecuteScalar:
using(var connection = new SqlConnection(myConnectionString))
{
connection.Open();
using(var command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = mySql;
var result = (int)command.ExecuteScalar();
}
}
If you're feeling really lazy, encapsulate it all in an extension method, like we do.
EDIT: As requested, an extension method:
public static T ExecuteScalar<T> (this SqlConnection connection, string sql)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (string.IsNullOrEmpty(sql))
{
throw new ArgumentNullException("sql");
}
using(var command = connection.CreateCommand())
{
command.CommandText = sql;
command.CommandType = CommandType.Text;
return (T)command.ExecuteScalar();
}
}
Note, this version assumes you've properly built the SQL beforehand. I'd probably create a separate overload of this extension method that took two parameters: the stored procedure name and a List. That way, you could protect yourself against unwanted SQL injection attacks.

Related

Display into textbox using if sentence

I'm displaying some data from the database into textboxes on my windows form and I have to add something else but it depends on the account type (that information is saved on my Databse). Meaning it is either DM (domestic) or CM(comercial). I want for it to charge an extra amount if it's CM.
I would appreciate any help, thank you.
OracleDataReader myReader = null;
OracleCommand myCommand = new OracleCommand("SELECT SUM(IMPORTE) AS corriente FROM MOVIMIENTOS WHERE CUENTA='"+txtIngreseCuenta3.Text + "'AND CONCEPTO=10", connectionString);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
txtCorriente.Text = (myReader["corriente"].ToString());
}
I'm using this code to display into the textbox but I want it to get the account type from another table and IF it's CM then add a certain amount into a textbox.
In your case I suggest that you use Execute Scalar instead of reader since you are returning only one value from the database. but in your case if you want this code to work you need to Cast the returned value into the correct dot net type and then populate the TextBox.
Example Using ExecuteReader
//txtCorriente.Text = ((int)myReader["corriente"]).ToString();
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
txtCorriente.Text = ((int)reader["corriente"]).ToString();
txtAnother.Text = ((decimal)reader["another"]).ToString();
Console.WriteLine(String.Format("{0}", reader[0]));
}
}
}
Example Using ExecuteScalar
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;
}

How to actually execute a command?

I'm playing around making a POC and I've created the following call.
public string DoStuff()
{
try
{
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
SqlConnection connection = new SqlConnection("Server...");
string command = "insert into Records values (...)";
adapter.InsertCommand = new SqlCommand(command, connection);
}
}
catch (Exception exception)
{
return exception.Message + " " + exception.InnerException;
}
return "WeeHee!";
}
The text I'm seeing returned is the happy one, so I conclude there's no exceptions. Hence, I conclude that the call to the DB is performed as supposed to. However, there's no new lines in the DB being created.
I'm using the same connection string as I have in my config file and the command in pasted in from SQL Manager, where it works.
So my suspicion was that although I create an insert command, I never actually execute it but according to MSDN that's how it's supposed to work.
What stupid thing do I miss here?
You are missing connection.Open(); and adapter.InsertCommand.ExecuteNonQuery();
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
SqlConnection connection = new SqlConnection("Server...");
connection.Open();
string command = "insert into Records values (...)";
adapter.InsertCommand = new SqlCommand(command, connection);
adapter.InsertCommand.ExecuteNonQuery();
}
You should use ExecuteNonQuery instead. Using an SqlDataAdapter for an INSERT query does not make sense.
Also you should Open your connection just before you execute it.
You can:
using(SqlConnection connection = new SqlConnection("Server..."))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = "insert into Records values (...)";
connection.Open();
int craeted = command.ExecuteNonQuery();
}
The example you linked to returned a SQLAdapter for later use.
You don't need one at all:
using (SqlConnection connection = new SqlConnection("Server..."))
{
string command = "insert into Records values (...)";
connection.Open();
var command = new SqlCommand(command, connection);
command.ExecuteNonQuery();
}
Note that there are other execution methods, depending on expected return values and whether you want asynchronous operation: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand(v=vs.110).aspx

Getting MAX value returned SQL command c#

I'm trying to get the MAX value returned but it keeps returning 0.
string stateValue = "CA";
SqlCommand cmd = new SqlCommand("SELECT MAX(Population) FROM TestData WHERE State=" + stateValue);
cmd.Parameters.Add("#Population", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
DBConnection.Instance.execNonQuery(cmd);
int population = (int)cmd.Parameters["#Population"].Value;
In DBConnection class this is the execNonQuery function:
public int execNonQuery(string sCmd, CommandType cmdType)
{
SqlCommand cmd = new SqlCommand(sCmd, m_sqlDataBase);
cmd.CommandType = cmdType;
try
{
m_sqlDataBase.Open();
}
catch { }
return cmd.ExecuteNonQuery();
}
Parameter direction is used with Stored Procedures. Here you are simply executing a single query. You need to use SqlCommand.ExecuteScalar method, since you will only get back one result. It returns an object so you have to convert it to int before using it.
Also your code is using string concatenation to create SQL Query and it is prone to SQL Injection. Also consider using using statement with your Command and Connection.
using (SqlCommand cmd = new SqlCommand("SELECT MAX(Popluation) FROM TestData WHERE State=#state"))
{
//Associate connection with your command an open it
cmd.Parameters.AddWithValue("#state", stateValue);
int populuation = (int)cmd.ExecuteScalar();
}
The ExecuteNonQuery call does not return the result of executing your query.
You can use ExecuteScalar or Execute to get the value back.
public int execQuery(string sCmd, CommandType cmdType)
{
SqlCommand cmd = new SqlCommand(sCmd, m_sqlDataBase);
cmd.CommandType = cmdType;
try
{
m_sqlDataBase.Open();
return Convert.ToInt32(cmd.ExecuteScalar());
}
catch {
// handle your error but don't trap it here..
throw;
}
}
ExecuteScalar is a short-circuit for getting the first value, or the first result set. You can use it to return a single value out of a query, such as yours.
Another option is to use the Execute method to obtain a result set and then use that to get the value you're after:
public int execQuery(string sCmd, CommandType cmdType)
{
SqlCommand cmd = new SqlCommand(sCmd, m_sqlDataBase);
cmd.CommandType = cmdType;
try
{
m_sqlDataBase.Open();
using(var dataReader = cmd.Execute())
{
if (dataReader.Read())
{
return Convert.ToInt32(dataReader[0]);
}
}
}
catch {
// handle your error but don't trap it here..
throw;
}
}
How 'bout
var sql = string.Format("SELECT MAX(Popluation) FROM TestData WHERE State='{0}'", stateValue);
SqlCommand cmd = new SqlCommand(sql);
(The important part was adding the single quotes. The string.Format was to make it look pretty)

Retrieve number of columns in SQL Table - C#

I'm very new to C#. I'm trying to retrieve the number of columns using:
SELECT count(*) FROM sys.columns
Could you please explain how to use the command and put it into a variable.
To connect to the database you can use the SqlConnection class and then to retrieve the Row Count you can use the Execute Scalar function. An example from MSDN:
cmd.CommandText = "SELECT count(*) FROM sys.columns;";
Int32 count = (Int32) cmd.ExecuteScalar();
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection
You will need to use ExecuteScalar as the others have said. Also, you will need to filter your SELECT on the object_id column to get the columns in a particular table.
SELECT count(*) FROM sys.columns WHERE object_id = OBJECT_ID(N'table_name')
Alternatively, you could do worse than familiarise yourself with the ANSI-standard INFORMATION_SCHEMA views to find the same information in a future-proof, cross-RDBMS way.
You have to use a command and retrieve back the scalar variable :
SqlCommand cmd = new SqlCommand(sql, conn);
Int32 count = (Int32)cmd.ExecuteScalar();
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
// Provide the query string with a parameter placeholder.
string queryString =
"SELECT Count(*) from sys.columns";
// Specify the parameter value.
int paramValue = 5;
// Create and open the connection in a using block. This
// ensures that all resources will be closed and disposed
// when the code exits.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}",
reader[0]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
use Executescalar() for getting a single element.
using (SqlConnection con = new SqlConnection(ConnectionString)) //for connecting to database
{
con.Open();
try
{
using (SqlCommand getchild = new SqlCommand("select count(*) from table1 ", con)) //SQL queries
{
Int32 count = (Int32)getchild.ExecuteScalar();
}
}
}
Use ExecuteScalar
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.
Int32 colnumber = 0;
string sql = "SELECT count(*) FROM sys.columns";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
colnumber = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
You'll want to use the ADO .NET functions in the System.Data.SqlClient namespace. ExecuteScalar is an easy-to-use method when you only want to get a single result. For multiple results, you can use a SqlDataReader.
using System.Data.SqlClient;
string resultVar = String.Empty;
string ServerName="localhost";
string DatabaseName="foo";
SqlConnection conn=new SqlConnection(String.Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI",ServerName,DatabaseName));
SqlCommand cmd=new SqlCommand(Query,conn);
try
{
conn.Open();
}
catch (SqlException se)
{
throw new InvalidOperationException(String.Format(
"Connection error: {0} Num:{1} State:{2}",
se.Message,se.Number, se.State));
}
resultVar = (string)cmd.ExecuteScalar().ToString();
conn.Close();

Simple SQL select in C#?

On my current project, to get a single value (select column from table where id=val), the previous programmer goes through using a datarow, datatable and an sqldatadapter (and of course sqlconnection) just to get that one value.
Is there an easier way to make a simple select query? In php, I can just use mysql_query and then mysql_result and I'm done.
It would be nice if I could just do:
SqlConnection conSql = new SqlConnection(ConnStr);
SomeSqlClass obj = new SomeSqlClass(sql_string, conSql);
conSql.Close();
return obj[0];
Thanks for any tips.
You can skip the DataReader and the DataAdapter and just call ExecuteScalar() on the sql command.
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand("SELECT * FROM whatever
WHERE id = 5", conn);
try
{
conn.Open();
newID = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
You are probably looking for SqlCommand and SqlDataReader
Dictionary<int, string> users = new Dictionary<int, string>();
using(SqlConnection connection = new SqlConnection("Your connection string"))
{
string query = "SELECT UserId, UserName FROM Users";
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
users.Add(reader.GetInt32(0), reader.GetString(1));
}
connection.Close();
}
Actually, there is a method SqlCommand.ExecuteScalar() that will simply return the first field from the first row of the returned results. Just for you.
.NET Framework Class Library
SqlCommand..::.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.
You can do something very similar:
using (SqlConnection conn = new SqlConnection(ConnStr))
using (SqlCommand cmd = new SqlCommand(sql_string, conn))
{
conn.Open();
return cmd.ExecuteScalar();
}
you can use SqlCommands executeScalar function. Please look at the following link
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx

Categories

Resources