How to avoid duplication in sql connection and execute command - c#

I can use this loop to give me list of names:
string commandText = #"SELECT ....;";
string connectionString = ConfigurationSettings.AppSettings["connectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
try
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(reader);
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = command.ExecuteReader();
string address = addressreader.GetString(0);
}
}
}
catch (Exception ex)
{
}
}
so the dt.Rows[i][0].ToString() is the name I need to add to all my different sql commands. So inside that for loop I will get each value from executing each sql command, one by one:
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = addresscommand.ExecuteReader();
string comaddress = addressreader.GetString(0);
SqlCommand keyProcessescommand = new SqlCommand(keyProcesses, connection);
keyProcessescommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader keyProcessesreader = keyProcessescommand.ExecuteReader();
string comkeyProcesses = keyProcessesreader.GetString(0);
SqlCommand standardscommand = new SqlCommand(standards, connection);
standardscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader standardsreader = standardscommand.ExecuteReader();
string comstandards = standardsreader.GetString(0);
Where the command string determined by:
string address = #"SELECT address FROM Companies where companyName = #companyName";
string keyProcesses = #" SELECT distinct STUFF((SELECT ', '+ cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN KeyProcesses u ON u.categorySetId = uc.setId
INNER JOIN Companies c ON c.companyId = u.companyId
WHERE c.companyName = #companyName
ORDER BY cn.name
FOR XML PATH('')), 1, 1, '') AS listStr
FROM WMCCMCategories cnn Group by cnn.name";
string standards = #" SELECT cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN Companies c ON c.standards = uc.setId
WHERE c.companyName = #companyName";
Can I execute multiple sql commands like above? How is the best way to do that ?

One way you can solve this through JOIN in SQL. However, it may not be right thing to do if it is not representing same columns.
Now in terms of using multiple select in one command. Yes, you can use SqlDataReader with NextResult()
Please see this link:
http://csharp.net-informations.com/data-providers/csharp-multiple-resultsets.htm

Related

Asynchronous calls in ASP.net webforms stored procedures

Stored procedures
CREATE PROCEDURE Contributor_Search
#fullname VARCHAR(60)
AS
SELECT
C.id, years_of_experience, portfolio_link, specialization,
notified_id, email, first_name, middle_name, last_name,
birth_date, age
FROM
Contributor C
INNER JOIN
[User] U ON C.id = U.id
WHERE
U.first_name + ' ' + U.middle_name + ' ' + U.last_name = #fullname
CREATE PROCEDURE Show_Original_Content
#contributor_id INT
AS
IF #contributor_id IS NULL
SELECT *
FROM Original_Content OC
INNER JOIN Content C ON OC.id = C.id
INNER JOIN Contributor CO ON C.contributor_id = CO.id
WHERE OC.filter_status = 1
ELSE
SELECT *
FROM Original_Content OC
INNER JOIN Content C ON OC.id = C.id
INNER JOIN Contributor CO ON C.contributor_id = CO.id
WHERE OC.filter_status = 1 AND CO.id = #contributor_id
I want to run the first stored procedure if input is provided, and if not just jump into the second with null; if input is provided and it's ran however, I would like to get an ID using the first procedure and then use it in the second procedure, this is my current approach which unfortunately does not work.
protected void btnSearch_Click(object sender, EventArgs e)
{
string connectionStr = #"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=iEgypt;";
if(inputName.Value.Trim() != "")
{
using (SqlConnection con = new SqlConnection(connectionStr))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "Contributor_Search";
cmd.CommandType = CommandType.StoredProcedure;
if (inputName.Value.Trim() != "")
{
SqlParameter param = new SqlParameter("#fullname", inputName.Value);
cmd.Parameters.Add(param);
}
else
{
SqlParameter param = new SqlParameter("#fullname", DBNull.Value);
cmd.Parameters.Add(param);
}
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
id = rdr[0].ToString();
con.Close();
}
}
using (SqlConnection con = new SqlConnection(connectionStr))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "Show_Original_Content";
cmd.CommandType = CommandType.StoredProcedure;
if (id != "")
{
SqlParameter param = new SqlParameter("#contributor_id", inputName.Value);
cmd.Parameters.Add(param);
}
else
{
SqlParameter param = new SqlParameter("#contributor_id", DBNull.Value);
cmd.Parameters.Add(param);
}
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
gvSearchResults.DataSource = rdr;
gvSearchResults.DataBind();
}
}
Any help is much appreciated.
In the comments, #vjgn suggests calling the Read method before accessing the rows in the SqlDataReader. For example:
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.Read())
{
id = rdr[0].ToString();
}
That should work... Or alternatively you could use the ExecuteScalar method and not have to worry about opening the reader:
id = cmd.ExecuteScalar()?.ToString() ?? "";
The problem with that is now you are having to check for null, then converting it into an empty string. It is probably better to avoid converting to empty string and just check for both in your if statement.
id = cmd.ExecuteScalar()?.ToString();
...
if (!String.IsNullOrEmpty(id))
Another potential point of error is if the record has a null value in first_name, middle_name, or last_name then your search won't find any results because when you concatenate a null value with a non-null value, you get null. Try changing the where clause to the following:
isnull(U.first_name,'') + ' ' + isnull(U.middle_name,'') + ' ' + isnull(U.last_name,'') = #fullname
This looks like it does an exact search...

Fill Datagrid with Sql Query using Date " 'Operand type clash: date is incompatible with int''

I am new to Programming and I started with C# (Visual Studio 2017 CE);
I am writing an application and using a DataGrid. I am trying to fill the DataGrid using a query to a C# service based DB (mdf file).
When I run the app and try the query statement I get this error:
Operand type clash: date is incompatible with int
at the SqlDataReader Line.
I have tested the SQL Select statement in the SQL Server and it works there. I have read multiple questions related to the error, but since I am a rookie to programming almost all answers are difficult to understand, Thanks in advance for your understanding
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago = " + Dtp_fecha_cuadre.Text;
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string Nombres = dr["Nombres"].ToString();
string Apellidos = dr["Apellidos"].ToString();
string num_prestamo = dr["prestamo_id"].ToString();
DateTime fecha = Convert.ToDateTime(dr["fecha"].ToString());
double Monto_prestamo = Convert.ToDouble(dr["Monto_prestamo"].ToString());
string Codigo_ruta = dr["Ruta"].ToString();
string Quotas = dr["Quotas"].ToString();
double Balance = Convert.ToDouble(dr["Balance"].ToString());
double Monto_pago = Convert.ToDouble(dr["Monto_pago"].ToString());
double Mora = Convert.ToDouble(dr["Mora"].ToString());
Dgv_cuadre_rutas.Rows.Add(Nombres, Apellidos, num_prestamo, fecha,Monto_prestamo , Codigo_ruta, Quotas, Balance, Monto_pago, Mora);
}
conn.Close();
}
Uses SQL DataAdapter instead which is much easier and will get rid of error
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago = " + Dtp_fecha_cuadre.Text;
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter(strsql, conn);
DataTable dt = new DataTable();
adapter.Fill(dt);
Dgv_cuadre_rutas.DataSource = dt;
conn.Close();
}
I was able to fix the error! the error occurs first because in my original query I was using " = " + Dtp_fecha_cuadre.Text;" the equal sends the data in an int format, so I had to change it to "--like '" + Dtp_fecha_cuadre.Value.ToString() +"'";,-- but at this point it was not filling up the datagrid, then I came up with the idea that, date string being send was not in the correct format, and adjusted the query to "like '" + Dtp_fecha_cuadre.Value.ToString("yyyy-MM-dd") +"'"; and this solve my problem, thanks all that helped me here – engel 1 min ago edit
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago like '" + Dtp_fecha_cuadre.Value.ToString("yyyy-MM-dd") +"'";
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string Nombres = dr["Nombres"].ToString();
string Apellidos = dr["Apellidos"].ToString();
string num_prestamo = dr["prestamo_id"].ToString();
DateTime fecha = Convert.ToDateTime(dr["fecha"].ToString());
double Monto_prestamo = Convert.ToDouble(dr["Monto_prestamo"].ToString());
string Codigo_ruta = dr["Ruta"].ToString();
string Quotas = dr["Quotas"].ToString();
double Balance = Convert.ToDouble(dr["Balance"].ToString());
double Monto_pago = Convert.ToDouble(dr["Monto_pago"].ToString());
double Mora = Convert.ToDouble(dr["Mora"].ToString());
Dgv_cuadre_rutas.Rows.Add(Nombres, Apellidos, num_prestamo, fecha, Monto_prestamo, Codigo_ruta, Quotas, Balance, Monto_pago, Mora);
}
conn.Close();

Select from multiple tables?

I have two tables one table's name is (memberform) and it has columns id,name,mobile example 1,dimitris,69xxxxxxx, and a second table (groups) with columns name,groupname,memberid example dimitris,dancegroup,1 (memberid is the same with id)
I want to extract into a richtextbox where groupname from groups = combobox1 and where memberid from row which groupname exists is same with memberform.id
i'm trying something like this
using (var command = new SqlCommand("select mobile from memberform where memberform.id=groups.memberid and groups.groupname='" + comboBox1.Text + "'", con)) //
using (var reader = command.ExecuteReader())
The raw SQL query is
SELECT M.mobile
FROM memberform M
JOIN groups G ON G.memberid = M.id
WHERE G.groupname = 'dancegroup'
the same can be written in your sqlcommand is
using (var command = new SqlCommand("SELECT M.mobile FROM memberform M JOIN groups G ON G.memberid = M.id WHERE G.groupname = '" + comboBox1.Text + "'", con))
UPDATE:
The above approach can be possible for SQL injection attack, so explicitly pass the parameter by SqlParameter
using (var command = new SqlCommand("SELECT M.mobile FROM memberform M JOIN groups G ON G.memberid = M.id WHERE G.groupname = #GroupName", con))
{
command.Parameters.Add(new SqlParameter("GroupName", comboBox1.Text);
using (var reader = command.ExecuteReader())
....
Why not select from the first table, get the number then use it to select from the second table?
#Edit:
private void GetData()
{
// Get the ID using the name
string id, yourData;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("SELECT * FROM Table1 WHERE name=#name", con);
cmd.Parameters.Add("#name", "dimitris");
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
id = reader["Id"].ToString();
con.Close();
// Get whatever you want using that ID
cmd.CommandText = "SELECT * FROM Table2 WHERE Id=#id";
cmd.Parameters.Add("#id", id);
con.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
yourData = reader["ColumnName"].ToString();
con.Close();
}

ASP.NET , C# how to write this sql command

How can I write this code in asp.net c# code behinds?
Wwhat I'm trying to do is to select all rows in invoicetable with orderno that is equal to current session and deduct the inventory of my inventorytable from `invoicetable qty that matches their itemid's.
SqlCommand cmd =
new SqlCommand("UPDATE inventorytable
JOIN invoicetable ON inventorytable.ItemID = invoicetable.ItemID
SET inventorytable.inventory = inventorytable.inventory-invoice.QTY
WHERE invoicetable.No='" + Convert.ToInt32(Session["invoiceno"]) + "'"
, con);
InsertUpdateData(cmd);
Your update query is not formed correctly, and you should be using parameterized SQL. Try using something like this
var sqlQuery =
#"UPDATE inventorytable
SET inventorytable.inventory = inventorytable.inventory-invoice.QTY
FROM inventorytable
INNER JOIN invoicetable ON inventorytable.ItemID = invoicetable.ItemID
WHERE invoicetable.No=#invNo";
using (var conn = new SqlConnection(CONN_STR))
{
var sqlCmd = new SqlCommand(sqlQuery, conn);
sqlCmd.Parameters.AddWithValue("#invNo", Session["invoiceno"].ToString());
sqlCmd.ExecuteNonQuery();
}
I typed this without VS in front of me, so let me know if there are any syntax issues
var n = Session["invoiceno"] != null ? Convert.ToInt32(Session["invoiceno"]) : 0;
using (var conn = new SqlConnection(CONN_STR))
{
conn.Open();
var sql = "SELECT * FROM invoicetable WHERE orderno = #n";
var cmd = new SqlCommand(sql);
cmd.Connection = conn ;
cmd.Parameters.AddWithValue("#n", n);
using(var dr = cmd.ExecuteReader())
{
while(dr.Read())
{
//loop through DataReader
}
dr.Close();
}
}

C# use a reader in another reader solution?

I need to get some mysql data into another mysql reader request anyway to workaround that I apparently can't have 2 readers open at the same time it will all end up in a datagrid
public void DBSelectPraktikanter(object sender)
{
string Command = "SELECT * FROM forlob WHERE firmaid = N'" + firmaid + "'";
MySqlConnection sqlConnection1 = new MySqlConnection(connectionString);
MySqlCommand command = new MySqlCommand(Command, sqlConnection1);
sqlConnection1.Open();
MySqlDataReader reader = command.ExecuteReader();
var items = new List<praktikanter>();
if (reader.HasRows)
{
while (reader.Read())
{
string praktikantid = String.Format("{0}", reader["praktikantid"]);
string Command2 = "SELECT * FROM praktikanter WHERE id = N'" + praktikantid + "'";
MySqlCommand command2 = new MySqlCommand(Command, sqlConnection1);
MySqlDataReader reader2 = command.ExecuteReader();
if (reader.HasRows)
{
while (reader2.Read())
{
Praktikant = String.Format("{0}", reader["Navn"]);
}
}
string Fra = String.Format("{0}", reader["fra"]);
string Til = String.Format("{0}", reader["til"]);
items.Add(new praktikanter(Praktikant, Fra, Til));
}
}
sqlConnection1.Close();
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
Instead of nesting MySqlCommands and looping the first resultset to query again the database to collect all of your data you should really use one query. Also use the using-statement to ensure that the connection gets closed even on error and use sql-parameters to avoid sql-injection issues:
var items = new List<praktikanter>();
string sql = #"SELECT p.*, f. Navn
FROM praktikanter p INNER JOIN forlob f ON p.id = f.praktikantid
WHERE f.firmaid = #firmaid";
using (var con = new MySqlConnection(connectionString))
using (var command = new MySqlCommand(sql, con))
{
command.Parameters.Add(new MySqlParameter("#firmaid", MySqlDbType.VarChar).Value = firmaid);
con.Open();
using (var rd = command.ExecuteReader())
{
while (rd.Read())
{
string praktikant = rd.GetString("Navn");
string fra = rd.GetString("Fra");
string til = rd.GetString("Til");
items.Add(new praktikanter(praktikant, fra, til));
}
}
}

Categories

Resources