C# multiple SQL select statements single method - c#

I have a task to develop a console application that is a recon of values from a few tables in the DB. I have all the queries that I need for each value that is required and understand the logic on how the values will interact. The challenge I have is the best method to retrieve and store these values.
I have researched and successfully been able to create the static method to retrieve a single value from a single SQL query but I'm curious about the best method:
Create multiple methods to retrieve each value (upwards of 15 different select statements) summarised below (not complete code)
static double total1(int arg)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command1 = new SqlCommand(commandText1, connection));
return(response);
}
}
static double total2(int arg)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command2 = new SqlCommand(commandText2, connection));
return(response);
}
}
Try to combine all select statements in a single method (I've been unsuccessful here) summarised below (not complete code)
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(commandText1, connection))
{
}
using (SqlCommand command2 = new SqlCommand(commandText2, connection))
{
}
// etc
}
Create stored procedures in SQL and execute them and pass the parameters via the c# console app
I think method 1 is going to be taxing on the server as it would require the connection to open and close multiple times (although I don't know if that's as big a issue as I think it is). Method 2 seems more reasonable although I've followed the concepts here and I get stuck when trying to get the output of the commands (I'm using return). Method 3 seems smarter to me although I'd still be in a position where I need to choose between methods 1 & 2 to execute the SP's.
I would really appreciate advice and guidance here, I'm new to C# so this is a steep learning curve when tutorials don't cover the sort of thing (or at least I can't define my problem properly)

string query = "SELECT * FROM table1;";
query += "SELECT * FROM table2";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
}
}
}
}

I've recently seen that this question is still being viewed so I'll post the solution for anyone who is just starting off developing and encounters a similar challenge.
The most suitable solution was to create a stored procedure, pass each unique argument to it and return all the relevant data in a single response to the application. A custom model was defined for this output and the application logic adapted accordingly. The result is a longer running single call to the database as opposed to multiple individual ones.
Using the format from the question, the solution was:
C# code
static NewModel AllTotals(int arg1, int arg2)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
var commandText = "TheStoredProcName";
SqlCommand command = new SqlCommand(commandText, connection));
command.CommandType = System.Data.CommandType.StoredProcedure;
Cmd.Parameters.AddWithValue("#arg1", arg1);
Cmd.Parameters.AddWithValue("#arg1", arg2);
using (SqlDataReader dr = Cmd.ExecuteReader())
{
while (dr.Read())
{
var response = new NewModel(){
Value1 = Convert.ToDecimal(dr["value1"]),
Value2 = Convert.ToDecimal(dr["value2"]),
};
return(response);
}
}
}
return null;
}
SQL Stored Proc
CREATE PROCEDURE [dbo].[TheStoredProcName]
#arg1 int,
#arg2 int
AS
DECLARE #value1 decimal(18,6) = ISNULL((--QUERY TO GET VALUE1),0)
DECLARE #value2 decimal(18,6) = ISNULL((--QUERY TO GET VALUE2),0)
-- select the variables into a result set for the application
SELECT #value1 as [value1], #value2 as [value2]

Related

Take user input and use that value as the filter for a query

I have a C# application (was built using Visual Studio 2015 Professional) that is used to interface with a Microsoft Access (2010) database (.mdb). First of all...I am not normally a C# Developer, so please excuse the ignorance. What I want to do seems simple enough...but I cannot figure out how to actually accomplish it. I am looking to create a search portal that would take the users input, query the database, and return the record that matches the desired Serial Number.
My first thought was to create a query in Visual Studio and use the users input as a filter for the query, but I could not figure out how to set it to look at the inputTB for the value.
My second thought was to nest a SQL query within my C# code...but I do not know they syntax or structure required to do something like that.
The only bit of code I do have is the SQL Query I wanted to use, but it's essentially pseudocode and I'm sure there are gaps in it.
SELECT ID, UnitType, UnitSN, StatusCode, Priority
FROM Units
WHERE UnitSN = inputTB;
Edit
With the help of a couple members of the StackOverflow Community, I have pieced together a bit of code, but I am having trouble displaying the results in the datagrid. The code that has been generated so far:
public void Main()
{
string unitSN = inputTB.Text;
string connectionString = Properties.Settings.Default.ZeusConnectionString;
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * FROM Units WHERE UnitSN LIKE #Name", connection))
{
command.Parameters.Add(new OleDbParameter("Name", unitSN));
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
int ID = reader.GetInt32(0);
string Unit = reader.GetString(1);
string SerialNumber = reader.GetString(2);
//Console.WriteLine("ID = {0}, Unit = {1}, SerialNumber = {2}", ID, Unit, SerialNumber);
MessageBox.Show(SerialNumber);
}
}
}
}
Please feel free to make any edits to the code as I realize it is a mess and I have little more than a cursory knowledge of the C# language.
You can try something like this.
public DataTable Test(string connectionString)
{
DataTable table = null;
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandText = #"SELECT ID, UnitType, UnitSN, StatusCode, Priority
FROM Units
WHERE UnitSN = #inputTB;";
cmd.Parameters.Add(new SqlParameter(#"inputTB", inputTB.Text));
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
table = new DataTable();
adapter.Fill(table);
}
}
}
catch(Exception ex)
{
//handle the caught exception
}
return table;
}
Hope it helps you.

Connecting to a Server

Trying to improve my C# to SQL skills... Currently I am using this bit of code to pull data from our application server. I have two different DBA's telling me two other ways to write this, just trying to figure out if this should be improved on or changed. If so, I would really appreciate some kind of examples.
FYI: This code...
db.con(user.Authority)
...Is essentially a 'new sqlconnection' code.
DataTable dtInfo = new DataTable("SomeInfo");
using (SqlConnection con = db.con(user.Authority))
{
string command = "SOME SQL STATEMENT;";
using (SqlCommand cmd = new SqlCommand(command,con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Param", sqlDbType).Value = Param;
con.Open();
cmd.ExecuteNonQuery();
**********
*** OR ***
**********
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Param", sqlDbType).Value = Param;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dtInfo );
}
}
}
So, if I'm understanding the provided information, this is my best route?
using (SqlConnection con = db.con(user.Authority))
{
string command = "SELECT [TBL_EMPLOYEE].[ACTIVE_DIRECTORY] FROM [TBL_EMPLOYEE];";
using (SqlCommand cmd = new SqlCommand(command, con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
MessageBox.Show(reader["ACTIVE_DIRECTORY"].ToString());
}
}
}
And one last thing... This should prevent the need for
cmd.Dispose();
etc...
The code would depend on the specific query. If the query retrieves rows of data (as a SELECT does), then you would go the da.Fill() route. If it's a query that just makes a change to the database (such as INSERT, UPDATE, or DELETE), then you would use ExecuteNonQuery().
I would not use the SqlDataAdapter version. The version that uses the SqlCommand object and the SqlDataReader will perform better, and allows more insight into the actual data being returned.
// Assumes the following sql:
// SELECT foo, bar FROM baz
// error checking left out for simplicity
var list = new List<SomeClass>();
using(var reader = cmd.ExecuteReader()) {
while(reader.Read()) {
list.Add(new SomeClass {
// NOTE: you can see the columns that the c# is referencing
// and compare them to the sql statement being executed
Foo = (string)reader["foo"],
Bar = (string)reader["bar"]
});
}
}
Later as your level of experiance increases you will be able to use other features of the SqlCommand and SqlDataReader classes in order to ensure that the code executes as quickly as possible. If you start using the SqlDataAdapter route, you will eventually have to relearn how to do the exact same things you have already been doing because the SqlCommand and SqlDataReader have operations that do not exist elsewhere in .NET.
ExecuteNonQuery returns the number of rows effected.
A DataTable is not an efficient way to retrieve that number.
int rowsRet = cmd.ExecuteNonQuery();
SqlCommand.ExecuteNonQuery Method

Handle optional parameters when I call a stored procedure

Problem statement.
Basically I get 3 - 50 parameters that come back from a web service as a NVP array I then need to loop over them create the SQL command parameters for each and call the stored procedure. Is there a more efficient way to handle it than the approach below?
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cm = connection.CreateCommand())
{
cm.CommandText = "MySproc";
cm.CommandType = CommandType.StoredProcedure;
foreach (var field in row)
{
cm.Parameters.AddWithValue("#" + field.Key.ToString(), field.Value.ToString());
}
cm.ExecuteNonQuery();
}
}
I personally use the ISNULL or COALESCE in the WHERE clause of the stored procedure. Unless your looking to do it inside your c#...
http://blogs.x2line.com/al/archive/2004/03/01/189.aspx

What is C# equivalent of PHP's mysql_fetch_array function?

I am learning C#/ASP.NET and I am wondering what the C# equivalent of the following PHP code is?
I know the userid, and I want to fetch the rows from this table into the array of the variable "row", so I then can use it as "row['name']" and "row['email'].
$result = mysql_query("SELECT email, name FROM mytable WHERE id=7");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
printf("Email: %s Name: %s", $row["email"], $row["name"]);
}
Thanks.
I'm not sure if this is the same as mysql_fetch_array but i assume that.
You can use IDBCommmand.ExecuteReader to create an IDataReader and use that to fill an Object[] with all fields of the row.
For example (using SQL-Server):
// use using statements to ensure that connections are disposed/closed (all implementing IDisposable)
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
using (var cmd = new SqlCommand("SELECT email, name FROM mytable WHERE id=#id", con))
{
cmd.Parameters.AddWithValue("#id", ID); // use parameters to avoid sql-injection
con.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var fields = new object[reader.FieldCount];
// following fills an object[] with all fields of the current line,
// is this similar to mysql_fetch_array?
int count = reader.GetValues(fields);
}
}
}
Edit:
I don't mean to make it as similar as possible, but how would I go about getting the same end result (a variable with the results) in C#
That's a matter of taste. You could use some kind of ORM like Enity-Framework, NHibernate, LINQ-To-SQL or Stackoverflow's Micro-ORM Dapper.NET(what i'm using currently) or plain ADO.NET (as shown above).
You can use a custom class that you fill manually with a DataReader or a DataTable which schema is loaded automatically.
For example (here using MySQL):
DataTable tblEmail = new DataTable();
using (var con = new MySqlConnection(Properties.Settings.Default.MySQL))
using (var da = new MySqlDataAdapter("SELECT Email, Name FROM Email WHERE id=#id", con))
{
da.SelectCommand.Parameters.AddWithValue("#id", ID);
da.Fill(tblEmail);
}
if (tblEmail.Rows.Count == 1)
{
DataRow row = tblEmail.Rows[0];
String email = row.Field<String>("Email");
String name = row.Field<String>("Name");
}
As you can see, there are many ways in .NET. I have shown just two with ADO.NET.
There's no true equivalent. Having been a PHP developer in the past, I'd say the closest thing is to use a data adapter and fill a data table. Here's a reference to DbDataAdapter.Fill.
I'm not sure about the MySql driver but if you're using Sql Server here's some code to get you started:
using (var connection = new SqlConnection(connectionString))
{
var table = new DataTable("tbl_objects");
var adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("SELECT * FROM tbl_name", connection);
adapter.Fill(table);
}
Then, you can iterate over the rows in the table:
foreach(var row in table)
{
Console.WriteLine("{0}", row["ColumnName"]);
}
You could loop through your result with a foreach loop as follows:
foreach(var row in result)
{
console.writeline("Email:" + row.Email, "Name:", row.Name);
}
Is that the sort of thing you were looking for?
EDIT
In fact i have just seen you only have one result.
Then you can skip the foreach loop altogether
You need a connection to a database.
Assuming you are using mysql and an odbc connection.
var connectionString = "DRIVER={MySQL ODBC 3.51 Driver};" +
"SERVER=localhost;" +
"DATABASE=test;" +
"UID=venu;" +
"PASSWORD=venu;" +
"OPTION=3");
using (OdbcConnection connection = new OdbcConnection(connectionString))
{
OdbcCommand command = new OdbcCommand("SELECT email, name FROM mytable WHERE id=7", connection);
connection.Open();
// Execute the DataReader and access the data.
OdbcDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//do stuff with the data here row by row the reader is a cursor
}
// Call Close when done reading.
reader.Close();
alternately you could use an odbcdataadapter and a datatable if you wanted all the results in a table you could use like an array.
The closest equivalent in .net would be something like this...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
var foo = MySqlHelper.ExecuteDataRow("Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;", "select * from foo");
Console.WriteLine(foo["Column"]);
}
}
}
I assume you are using the MySql Data Connector http://dev.mysql.com/downloads/connector/net/
Do note there are better ways available in .net to connect to databases, but I think for a line by line, this is about as close to the PHP as you can get.

C# and SQL Batch Update

Is there any API available similar to JDBC batch update [PreparedStatement.addBatch() and PreparedStatement.executeBatch() ]?
I have seen the DataAdapter. However I think it is using DataTable; is it similar to JDBC PreparedStatement?
PreparedStatements in JDBC are directly analogous to SqlCommand, right down to supplying the statement and parameters. Here's an example:
var cmd = "UPDATE SomeTable SET Value = #Param1 WHERE ID = #ID";
using (var connection = new SqlConnection("Connection String Here"))
using (var command = new SqlCommand(cmd, connection))
{
command.Parameters.AddWithValue("#Param1", "NewValue");
command.Parameters.AddWithValue("#ID", 1);
connection.Open();
command.ExecuteNonQuery();
}
From what I've read, all the above should see very familiar for someone who uses PreparedStatement.

Categories