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
Related
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]
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.
i'm fetching values from a table with datareader like this:
string query = #"SELECT XMLConfig, Enable FROM TableCfg";
using (SqlConnection cnction = new SqlConnection(cnnstr))
{
cnction.Open();
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
while (dtRead.Read())
{
xmlConf = dtRead.GetString(0);
enabl = dtRead.GetString(1);
}
dtRead.Close();
}
}
The Enable field is a boolean(True/False). Is there a way to fetch only the rows, where field enable="True"?
I tried using LINQ, but i'm new to this and i must be doing something wrong.
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
var ob =(from IDataRecord r in sqlCmd.ExecuteReader()
where r.GetString(3).ToString() == "True"
select "Enable");
}
Help me please.
Best Regards.
You should really do as much filtering as possible at the database side rather than client-side:
string query = "SELECT XMLConfig FROM TableCfg WHERE Enable = True";
Notice how now you don't even need to fetch Enable, as you already know it will be True for all the matching rows.
You should also consider using LINQ to SQL or Entity Framework rather than the rather low-level stack you're currently using. It's not always appropriate, but it does make things cleaner where it's suitable.
I am quit busy turning a old classic asp website to a .NET site. also i am now using SQL Server.
Now I have some old code
strsql = "select * FROM tabel WHERE ID = " & strID & " AND userid = " & struserid
rs1.open strsql, strCon, 2, 3
if rs1.eof THEN
rs1.addnew
end if
if straantal <> 0 THEN
rs1("userid") = struserid
rs1("verlangid") = strID
rs1("aantal") = straantal
end if
rs1.update
rs1.close
I want to use this in SQL Server. The update way. How can I do this?
How can I check if the datareader is EOF/EOL
How can I insert a row id it is EOF/EOL
How can I update a row or delete a row with one function?
If you want to use raw SQL commands you can try something like this
using (SqlConnection cnn = new SqlConnection(_connectionString))
using (SqlCommand cmd = new SqlCommand())
{
cnn.Open();
cmd.Connection = cnn;
// Example of reading with SqlDataReader
cmd.CommandText = "select sql query here";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
myList.Add((int)reader[0]);
}
}
// Example of updating row
cmd.CommandText = "update sql query here";
cmd.ExecuteNonQuery();
}
It depends on the method you use... Are you going to use Entity Framework and LINQ? Are you going to use a straight SQL Connection? I would highly recommend going down the EF route but a simple straight SQL snippet would look something like:
using (var connection = new SqlConnection("Your connection string here"))
{
connection.Open();
using (var command = new SqlCommand("SELECT * FROM xyz ETC", connection))
{
// Process results
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int userId = (int)reader["UserID"];
string somethingElse = (string)reader["AnotherField"];
// Etc, etc...
}
}
}
// To execute a query (INSERT, UPDATE, DELETE etc)
using (var commandExec = new SqlCommand("DELETE * FROM xyz ETC", connection))
{
commandExec.ExecuteNonQuery();
}
}
You will note the various elements wrapped in using, that is because you need to release the memory / connection when you have finished. This should answer your question quickly but as others have suggested (including me) I would investigate Entity Framework as it is much more powerful but has a learning curve attached to it!
You can use SQL store procedure for Update. And call this store procedure through C#.
Create procedure [dbo].[xyz_Update]
(
#para1
#para2
)
AS
BEGIN
Update tablename
Set Fieldname1=#para1,
Set Feildname2=#para2
end
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.