I have a SQL statement where I want to filter out the year and the place. The problem is that when I type a year, all the data for this year is being displayed, which is fine but when I input the place it lists places from another year too.
I know that it is so because of the or but what do I have to write instead to get my desired result?
adapter = new SqlDataAdapter
(#"select a.FALL, m.CODE, m.ANZ, m.TDAT
from lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid
where year(m.TDAT) = #jahr or m.Einrichtung= #einricht
order by a.FALL",
"Server = sds; Database = dds;Trusted_Connection = True");
EDIT:
SqlDataAdapter adapter;
adapter = new SqlDataAdapter("select a.ISH_FALLZAHL, m.ML_CODE, m.ML_ANZ, m.ML_LSTDAT From lst_mdmel_lis_tab m with (nolock) inner join lst_absae_tab a with (nolock) on a.aid = m.aid where (#jahr IS NULL OR YEAR(m.ML_LSTDAT) = #jahr) and (#einricht IS NULL OR m.L_ANSTALT = #einricht) order by a.ISH_FALLZAHL", "Server = igvproli19; Database = ADM;Trusted_Connection = True");
adapter.SelectCommand.Parameters.AddWithValue("#jahr", textBox1.Text);
adapter.SelectCommand.Parameters.AddWithValue("#einricht", textBox2.Text);
ds = new DataTable(" ");
adapter.Fill(ds);
dataGridView1.DataSource = ds;
where
(#jahr IS NULL OR YEAR(m.TDAT) = #jahr)
and (#einricht IS NULL OR m.Einrichtung = #einricht)
Change these two lines:
adapter.SelectCommand.Parameters.AddWithValue("#jahr", textBox1.Text);
adapter.SelectCommand.Parameters.AddWithValue("#einricht", textBox2.Text);
to:
if (textBox1.Text == null || textBox1.Text == "")
{
adapter.SelectCommand.Parameters.AddWithValue("#jahr", DBNull.Value);
}
else
{
adapter.SelectCommand.Parameters.AddWithValue("#jahr", textBox1.Text);
}
if (textBox2.Text == null || textBox2.Text == "")
{
adapter.SelectCommand.Parameters.AddWithValue("#einricht", DBNull.Value);
}
else
{
adapter.SelectCommand.Parameters.AddWithValue("#einricht", textBox2.Text);
}
Assuming both arguments are provided, you can write as following:
adapter = new SqlDataAdapter
("select a.FALL, m.CODE, m.ANZ, m.TDAT From lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid
where year(m.TDAT) = #jahr or (m.Einrichtung= #einricht and year(m.TDAT)=#jahr)
order by a.FALL", "Server = sds; Database = dds;Trusted_Connection = True");
To search by more than one filter you have to use AND instead of OR but to filter by year if no place is provided I think something like this should work:
where (year(m.TDAT) = #jahr AND m.Einrichtung= #einricht) OR
(year(m.TDAT) = #jahr AND #einricht IS NULL) OR
(#jahr IS NULL AND m.Einrichtung= #einricht)
If you might have place, year or both, then the best way would be to have 3 separate where clauses for each of those cases, f. e.
var year = ""; // Set value.
var place = ""; // Set value.
var whereClause = "where " + year != null && place != null ?
"year(m.TDAT) = #jahr AND m.Einrichtung = #einricht" : year != null ?
"year(m.TDAT) = #jahr" :
"m.Einrichtung = #einricht";
adapter = new SqlDataAdapter(
"select a.FALL, m.CODE, m.ANZ, m.TDAT From lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid " + whereClause +
" order by a.FALL", "Server = sds; Database = dds;Trusted_Connection = True");
Also, depending on whether you want to accept empty strings or not you can change != null comparison with string.IsNullOrEmpty or string.IsNullOrWhiteSpace methods.
You should use AND rather than OR. By using AND means that it will show the results which have the YEAR and PLACE the same with your parameter. If you are using OR, it means that it will show you the results that having the year OR the place the same with your parameter.
adapter = new SqlDataAdapter
("select a.FALL, m.CODE, m.ANZ, m.TDAT From lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid
where year(m.TDAT) = #jahr AND m.Einrichtung= #einricht
order by a.FALL", "Server = sds; Database = dds;Trusted_Connection = True");
EDIT
If you are not sure which parameter is given, you could check whether that parameter is null or not, then proceed with the sql.
for example
public void ReadDataFromDB(string Year, string Place)
{
string sql = #"select a.FALL, m.CODE, m.ANZ, m.TDAT From lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid
where 1=1 ";
if (Year != null && Year.Length > 0)
{
sql += "AND year(m.TDAT) = #jahr ";
}
if (Place != null && Place.Length > 0)
{
sql += "AND m.Einrichtung= #einricht ";
}
sql += "order by a.FALL";
adapter = new SqlDataAdapter(sql, "Server = sds; Database = dds;Trusted_Connection = True");
}
If you are afraid of SQL injection detection system like #Dovydas Sopa said, then you have to check it 1 by 1 then decide which Where clause should be put.
public void ReadDataFromDB(string Year, string Place)
{
string sql = #"select a.FALL, m.CODE, m.ANZ, m.TDAT From lst_test m with (nolock)
inner join test2 a with (nolock) on a.aid = m.aid ";
if (Year != null && Place != null)
{
sql += "Where year(m.TDAT) = #jahr AND m.Einrichtung= #einricht ";
}
else if (Year != null && Place == null)
{
sql += "Where year(m.TDAT) = #jahr ";
}
else if (Place != null && Year == null)
{
sql += "Where m.Einrichtung= #einricht ";
}
sql += "order by a.FALL";
adapter = new SqlDataAdapter(sql, "Server = sds; Database = dds;Trusted_Connection = True");
}
Related
Hi when i trying to select the date I get also the time, but I need to do group by date without the time.
I also tried this: GROUP BY CAST(Orders.DatePlacing AS DATE), and I tried Convert , DATE(Orders.DatePlacing) and I tried this its not working for me.
Microsoft.ACE.OLEDB.12.0
public Product[] ProfitPrice(DateTime minDate, DateTime maxDate)
{
maxDate=maxDate.AddDays(1);
DataSet ds = new DataSet();
ArrayList products = new ArrayList();
string cmdStr = "SELECT Sum(((Products.PriceSell - Products.Price) * OrdersDetails.ProductCount)) AS Expr1,Orders.DatePlacing FROM Products " +
"INNER JOIN(Orders INNER JOIN OrdersDetails ON Orders.OrderId = OrdersDetails.OrderId) " +
"ON Products.ProductID = OrdersDetails.ProductId WHERE [Orders.DatePlacing] BETWEEN #" + minDate.ToString("yyyy-MM-dd") + "#" + "AND" +
" #" + maxDate.ToString("yyyy-MM-dd") + "# "+
"GROUP BY Orders.DatePlacing";
using (OleDbCommand command = new OleDbCommand(cmdStr))
{
ds = GetMultipleQuery(command);
}
DataTable dt = new DataTable();
try
{
dt = ds.Tables[0];
}
catch { }
foreach (DataRow tProduct in dt.Rows)
{
StatisticsFillArray(tProduct, products);
}
return (Product[])products.ToArray(typeof(Product));
}
private void StatisticsFillArray(DataRow tProduct, ArrayList products)
{
Product productsData = new Product();
productsData.PriceTotal = Convert.ToDouble(tProduct[0].ToString());
productsData.EntryDate = tProduct[1].ToString();
products.Add(productsData);
}
Accordingly to my comment to the question...
your code is sql injection vulnerable!
Do NOT use concatenated string, use parameterized queries instead.
Use table/column aliases!
To reject time part from datetime column, use DateSerial function
How? Take a look at below code:
string sql = #"SELECT Sum(((p.PriceSell - p.Price) * od.ProductCount)) AS Expr1, DateSerial(Year(o.DatePlacing), Month(o.DatePlacing), Day(o.DatePlacing)) DatePlacing
FROM Products p
INNER JOIN(Orders o INNER JOIN OrdersDetails od
ON o.OrderId = od.OrderId)
ON p.ProductID = od.ProductId
WHERE DateSerial(Year(o.DatePlacing), Month(o.DatePlacing), Day(o.DatePlacing)) BETWEEN #mindate AND #maxdate
GROUP BY DateSerial(Year(o.DatePlacing), Month(o.DatePlacing), Day(o.DatePlacing))";
DataTable dt = new DataTable();
using (OleDbConnection oConn = new OleDbConnection(yourConnectionStringHere))
{
oConn.Open();
using (OleDbCommand oComm = new OleDbCommand(yourCommandHere, oConn))
{
oComm.Parameters.Add(new OleDbParameter(){"#mindate", OleDbType = OleDbType.Date, Value = minDate},);
oComm.Parameters.Add(new OleDbParameter(){"#maxdate", OleDbType = OleDbType.Date, Value = maxDate},);
using (OleDbDataReader oRdr = oComm.ExecuteReader())
dt.Load(oRdr);
}
}
I currently have a query where I am getting data from 2 different databases which is getting appended to one list called "accountbuys".
My first table has three data entry(3 accounts which want to buy stocks
The next table with 17 data points(17 stocks to buy)
I am merging these tables and getting output
However,the output I want , should have 17 data points repeated each time for the 3 different accounts, so that the end user can drill down and buy whichever stock he wants
PS: If what I am trying to ask is not clear, please be polite and tell me so. Please try not to be rude, I am still learning and new to StackExchange!
This is my code :`
public List<BuySellModel> GetBuyDataWthAccount()
{
List<BuySellModel> accountbuys = new List<BuySellModel>();
using (SqlConnection connectionreit = new SqlConnection(HubConnection))
using (SqlConnection connection = new SqlConnection(PMConnection))
{
connectionhub.Open();
connection.Open();
SqlCommand command3 = new SqlCommand(#"SELECT distinct(table1.name) as 'Symbol' ,table2.Segment as 'Segment',table2.AllocationAmount as 'AllocationAmount',table2.PX_LAST as 'Price',
table1.CUR_MKT_CAP as 'CMC',table1.FCFY_WITH_CUR_MKT_CAP as 'FCMC',table1.ROIC as 'ROIC', table1.ROICDELTA as 'ROICD' FROM View_REIT_Model_And_Holdings as table1
INNER JOIN [MostRecentlyInModelSelected] as table2
ON table1.name = table2.Ticker
WHERE table1.AllocationAmount != -1 AND
NOT EXISTS (SELECT NULL FROM [ViewPCData] as table3 WHERE table1.name = table3.Symbol AND table2.Segment = table3.SubsectorDescription AND table3.Objective = 'REITS' AND table3.SectorDescription != 'NULL' AND table3.SubsectorDescription != 'NULL')",
connectionreit);
command3.CommandType = CommandType.Text;
SqlCommand command4 = new SqlCommand("SELECT PortfolioAccountNumber, PortfolioDescription, SUM(TotalValue) as 'TotalValue' FROM [ViewPCData] WHERE Objective = 'REITS' GROUP BY PortfolioAccountNumber,PortfolioDescription", connection);
command4.CommandType = CommandType.Text;
var reader = command3.ExecuteReader();
var reader1 = command4.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
BuySellModel accountb = new BuySellModel();
accountb.PortfolioAccount = reader1.GetString(reader1.GetOrdinal("PortfolioAccountNumber"));
accountb.PortfolioDescription = reader1.GetString(reader1.GetOrdinal("PortfolioDescription"));
accountb.AccountAmount = reader1.GetDecimal(reader1.GetOrdinal("TotalValue"));
accountbuys.Add(accountb);
if (reader.HasRows)
{
//foreach(var account in accountbuys)
//{
while (reader.Read())
{
BuySellModel buy = new BuySellModel();
buy.Symbol = reader.GetString(reader.GetOrdinal("Symbol"));
buy.Segment = reader.GetString(reader.GetOrdinal("Segment"));
//if (accountNumber == "soand os")
//{
// 1/3 of totalaccountvalue
buy.AllocationAmount = (reader.GetDouble(reader.GetOrdinal("AllocationAmount")));
//}
buy.Price = reader.GetDouble(reader.GetOrdinal("Price"));
buy.MarketValue = reader.GetDouble(reader.GetOrdinal("CMC"));
buy.FCFY = reader.GetDouble(reader.GetOrdinal("FCMC"));
buy.ROIC = reader.GetDouble(reader.GetOrdinal("ROIC"));
buy.ROICdelta = reader.GetDouble(reader.GetOrdinal("ROICD"));
buy.Buy = true;
//account1 = account.accountnumber;
accountbuys.Add(buy);
}
//} //for loop
}
} // accounts
} //reader1.hasrows
connectionhub.Close();
connection.Close();
}
return accountbuys;
}
EDIT:
Split the tables into two different lists and merged them later. This is working well now. Seems good for scaling too.
public List<BuySellModel> GetBuyDataWthAccount()
{
List<BuySellModel> accountbuys = new List<BuySellModel>();
List<Account> accounts = new List<Account>();
using (SqlConnection connection = new SqlConnection(PMConnection))
{
connection.Open();
SqlCommand command3 = new SqlCommand(#"SELECT distinct(table1.name) as 'Symbol' ,table2.Segment as 'Segment',table2.AllocationAmount as 'AllocationAmount',table2.PX_LAST as 'Price',
table1.CUR_MKT_CAP as 'CMC',table1.FCFY_WITH_CUR_MKT_CAP as 'FCMC',table1.ROIC as 'ROIC', table1.ROICDELTA as 'ROICD' FROM View_Model_And_Holdings as table1
INNER JOIN [MostRecentlyInModelSelected] as table2
ON table1.name = table2.Ticker
WHERE table1.AllocationAmount != -1 AND
NOT EXISTS (SELECT NULL FROM [ViewPCData] as table3 WHERE table1.name = table3.Symbol AND table2.Segment = table3.SubsectorDescription AND table3.Objective = 'STOCKS' AND table3.SectorDescription != 'NULL' AND table3.SubsectorDescription != 'NULL')",
connectionreit);
command3.CommandType = CommandType.Text;
SqlCommand command4 = new SqlCommand("SELECT PortfolioDetail , SUM(TotalValue) as 'TotalValue' FROM [ViewPCData] WHERE Objective = 'STOCKS' GROUP BY PortfolioAccountNumber,PortfolioDescription", connection);
command4.CommandType = CommandType.Text;
var reader = command3.ExecuteReader();
var reader1 = command4.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
Account accountb = new Account();
accountb.PortfolioDetail = reader1.GetString(reader1.GetOrdinal("PortfolioDetail"));
// accountb.PortfolioDescription = reader1.GetString(reader1.GetOrdinal("PortfolioDescription"));
accountb.AccountAmount = reader1.GetDecimal(reader1.GetOrdinal("TotalValue"));
accounts.Add(accountb);
}
}
//List<BuyReits> buys = new List<BuyReits>();
if (reader.HasRows && accounts.Count > 0)
{
while (reader.Read())
{
foreach (var acc in accounts)
{
BuySellModel buy = new BuySellModel();
buy.Symbol = reader.GetString(reader.GetOrdinal("Symbol"));
buy.Segment = reader.GetString(reader.GetOrdinal("Segment"));
buy.AllocationAmount = (reader.GetDouble(reader.GetOrdinal("AllocationAmount")));
buy.Price = reader.GetDouble(reader.GetOrdinal("Price"));
//buy.Quantity = reader.GetInt32((reader.GetOrdinal("AllocationAmount"))/(reader.GetOrdinal("Price")));
buy.MarketValue = reader.GetDouble(reader.GetOrdinal("CMC"));
buy.FCFY = reader.GetDouble(reader.GetOrdinal("FCMC"));
buy.ROIC = reader.GetDouble(reader.GetOrdinal("ROIC"));
buy.ROICdelta = reader.GetDouble(reader.GetOrdinal("ROICD"));
buy.Buy = true;
buy.PortfolioAccount = acc.PortfolioDetail;
buy.AccountAmount = acc.AccountAmount;
accountbuys.Add(buy);
}
}
}
connection.Close();
}
return accountbuys;
}
The following provides the cross join in the C# layer (not saying it is the best possible solution, but it gets you closer to ready):
using (SqlConnection connectionhub = new SqlConnection(HubConnection))
using (SqlConnection connection = new SqlConnection(PMConnection))
{
connectionhub.Open();
connection.Open();
SqlCommand command3 = new SqlCommand(#"
SELECT distinct(table1.name) as 'Symbol',
table2.Segment as 'Segment',
table2.AllocationAmount as 'AllocationAmount',
table2.PX_LAST as 'Price',
table1.CUR_MKT_CAP as 'CMC',
table1.FCFY_WITH_CUR_MKT_CAP as 'FCMC',
table1.ROIC as 'ROIC',
table1.ROICDELTA as 'ROICD'
FROM View_REIT_Model_And_Holdings as table1
INNER JOIN [MostRecentlyInModelSelected] as table2
ON table1.name = table2.Ticker
WHERE table1.AllocationAmount != -1
AND NOT EXISTS (SELECT NULL
FROM [ViewPCData] as table3
WHERE table1.name = table3.Symbol
AND table2.Segment = table3.SubsectorDescription
AND table3.Objective = 'REITS'
AND table3.SectorDescription != 'NULL'
AND table3.SubsectorDescription != 'NULL')",
connectionreit);
command3.CommandType = CommandType.Text;
SqlCommand command4 = new SqlCommand(#"
SELECT PortfolioAccountNumber,
PortfolioDescription,
SUM(TotalValue) as 'TotalValue'
FROM [ViewPCData]
WHERE Objective = 'REITS'
GROUP BY PortfolioAccountNumber, PortfolioDescription", connection);
command4.CommandType = CommandType.Text;
var stocksDS = new DataSet();
var stocksDA = new System.Data.SqlClient.SqlDataAdapter();
stocksDA.SelectCommand = command3
stocksDA.Fill(stocksDS, "stocks");
var acctsDS = new DataSet();
var acctsDA = new System.Data.SqlClient.SqlDataAdapter();
acctsDA.SelectCommand = command4
acctsDA.Fill(acctsDS, "accts");
var stocks = stocksDS.Tables["stocks"].AsEnumerable();
var accts = acctsDS.Tables["accts"].AsEnumerable();
var results = (from stocksDR in stocks
from acctsDR in accts
select new BuySellModel {
PortfolioAccount = acctsDR["PortfolioAccountNumber"],
PortfolioDescription = acctsDR["PortfolioAccountDescription"],
AccountAmount = acctsDR["TotalValue"],
Symbol = stocksDR["Symbol"],
Segment = stocksDR["Segment"],
AllocationAmount = stocksDR["AllocationAmount"],
Price = stocksDR["Price"],
MarketValue = stocksDR["CMC"],
FCFY = stocksDR["FCMC"],
ROIC = stocksDR["ROIC"],
ROICdelta = stocksDR["ROICD"],
Buy = true
});
foreach (BySellModel buy in results) {
accountBuys.Add(buy);
}
connectionhub.Close();
connection.Close();
}
Edit: removed offending parentheses.
Without changing any of your C# code, it may be possible to get what you want by changing the SQL query from an INNER JOIN query to a CROSS JOIN query.
Some caveats regarding this approach though:
If you include a WHERE clause, the query will act as an INNER JOIN.
Cross joins can be significantly slower, as the query is looking to make all possible combinations. With only 51 (3 * 17) combinations available that will not be a significant issue, but if you are looking to scale this to more clients and stocks, it will become increasingly worse performance wise
I have a winform in which user input values through a combobox. I am assigning combobox value to search db. If there is no selection then the SQL server query should not use that column to filter.
example -
if (string.IsNullOrEmpty(combobox1.text)) {
.....Select * from country
}
else if (combobox1.selectedindex > -1) {
....Select * from country where city_name = combobox.text
}
Is there a way to write a single query instead of using this multiple 'IF' conditions in case where user selects or doesn't select a value from combobox.
It is important to parameterize as well:
private const string _select = "select * from country";
void DoSomething()
{
string sql = string.Empty;
if (combobox1.SelectedIndex > -1)
{
command.Parameters.AddWithValue("#1", (string)combobox1.SelectedValue);
sql = " where city_name = #1";
}
sql = _select + sql;
command.CommandText = sql;
command.Execute...
}
#un-lucky asked me how would I deal with many conditions - here is one way
var conditions = new List<string>();
if (/* condition 1*/)
{
command.Parameters.AddWithValue("#2", (string)cboN.SelectedItem);
conditions.Add("col1 = #2");
}
if (/* condition 2*/)
{
command.Parameters.AddWithValue("#3", textBoxN.Text);
conditions.Add("col2 = #3");
}
if (conditions.Count > 0)
sql = _select + " where " + string.Join(" AND ", conditions.ToArray());
You can use the shorthand if only if you have two conditions:
string query = string.Format("Select * from country{0}", string.IsNullOrEmpty(combobox1.text) ? "" : " where city_name = " + combobox1.text);
Hope it helps!
I think you have to try something like this with parameterization:
StringBuilder queryBuilder = new StringBuilder("Select * from country Where 1=1 ");
SqlCommand cmdSql = new SqlCommand();
if (combobox1.selectedindex > -1)
{
queryBuilder.Append(" And city_name = #city_name ");
cmdSql.Parameters.Add("#city_name", SqlDbType.VarChar).Value = combobox.text;
}
else if(Condition 2)
{
queryBuilder.Append(" And column2 = #col2 ");
cmdSql.Parameters.Add("#col2", SqlDbType.VarChar).Value = "some Value here;
}
// Build the query like this
cmdSql.CommandText= = queryBuilder.ToString();
cmdSql.Connection = conObject;
// Here you can execute the command
I have a sample, try it
string select = this.combobox1.GetItemText(this.combobox1.SelectedItem); cm1 = new SqlCommand("Select * from country where city_name=#select or #select is null", con);
cm1.Parameters.Add("#select", SqlDbType.NVarChar, 50);
cm1.Parameters["#select"].Value = select;
dap = new SqlDataAdapter(cm1);
ds = new System.Data.DataSet();
dap.Fill(ds, "DATABASE");
//DataGridView1.DataSource = ds.Tables[0]; get data
I have a quite large SQL query that works as expected when i´m exceuting it in MS SQL. However when I run it from C# it does not fetch any rows (dataTable does not return any rows). If I instead use a simple query, for e.g. "SELECT * Accounts FROM TableX" from C#, dataTable returns all the rows it should do. I also tried to remove all the spaces from the SQL query so everything was on the same line, but without any change. Here is the code:
internal void GetData()
{
try
{
using (SqlConnection connection = new SqlConnection(connectionBuilder.ToString())) //1. Open connection
{
connection.Open();
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(GetSqlString(), connection))
{
DataTable dataTable = new DataTable();
dataAdapter.Fill(dataTable);
foreach (DataRow dataRow in dataTable.Rows)
{
var field1 = dataRow[0];
var field2 = dataRow[1];
Logger.Log(field1 + " " + field2);
}
}
}
}
catch (Exception ex)
{
utilityProvider.Log("Error" + ex.ToString());
}
}
private string GetSqlString()
{
return #"SELECT
Field1 = subscr.cind_recipient,
Field2 = COALESCE(
a.name, s.cind_name,
CASE WHEN c.cind_is_protected_identity = 0 THEN c.fullname
ELSE ISNULL(c.cind_protected_firstname, '') + ' ' + ISNULL(c.cind_protected_lastname, '') END ),
Field3 = COALESCE(CASE WHEN c.cind_is_protected_identity <> 1 THEN c.address1_line3
ELSE c.cind_protected_address1_line3 END,
s.cind_postal_line3),
Field4 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN c.address1_line1
ELSE c.cind_protected_address1_line1 END,
a.address2_line1, s.cind_postal_line1),
Field5 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN c.address1_line2
ELSE c.cind_protected_address1_line2 END,
a.address2_line2, s.cind_postal_line2),
Field6 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN mpc1.cind_postalcode
ELSE mpc.cind_postalcode END,
a.address1_postalcode, s.cind_postal_postalcode),
Field7 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN mpc1.cind_city
ELSE mpc.cind_city END,
a.address1_city, s.cind_postal_city),
Field8 = c.cind_member_number,
Field9 = ISNULL(COALESCE(c.cind_union_section_idname, a.cind_mml_mub_union_section_idname), a1.cind_mml_mub_union_section_idname),
Field10 = CASE WHEN c.cind_is_protected_identity <> 1 THEN c.cind_soc_sec_no
ELSE c.cind_protected_cind_soc_sec_no END,
Field11 = COALESCE(a.cind_organization_no, s.cind_organization_no),
Field12 = c.gendercodename,
Field13 = cind_count,
Field14 = k1.cind_name,
Field15 = k1.cind_number,
Field16 = k2.cind_name,
Field17 = k2.cind_number,
Field18 = 'sam',
Field19 = subscr.villa_free_exname
FROM dbo.Filteredcind_mml_mub_subscription subscr
INNER JOIN Filteredcind_mml_mub_service svc
ON subscr.cind_mml_mub_service_id = svc.cind_mml_mub_serviceid
AND svc.cind_code = 'PE002'
LEFT JOIN Filteredcind_mml_mub_site s
ON subscr.cind_mml_mub_site_id = s.cind_mml_mub_siteid
LEFT JOIN FilteredAccount a
ON subscr.cind_account_id = a.accountid
LEFT JOIN FilteredAccount a1
ON a1.accountid = s.cind_account_id
INNER JOIN FilteredContact c
ON subscr.cind_contact_id = c.contactid
AND c.statecode = 0
LEFT JOIN Filteredcind_mml_mub_postalcity mpc
ON c.cind_protected_cind_postalcity_id = mpc.cind_mml_mub_postalcityid
LEFT JOIN Filteredcind_mml_mub_postalcity mpc1
ON c.cind_postalcity_id = mpc1.cind_mml_mub_postalcityid
LEFT JOIN Filteredcind_mml_mub_county lan
ON c.cind_county_id = lan.cind_mml_mub_countyid
LEFT JOIN Filteredcind_mml_mub_country land
ON lan.cind_country_id = land.cind_mml_mub_countryid
LEFT JOIN (Filteredcind_mml_mub_membership m1
INNER JOIN (SELECT mt1.cind_mml_mub_membership_typeid
FROM Filteredcind_mml_mub_membership_type mt1
WHERE mt1.cind_code = 'PRDI-45') mtt1
ON mtt1.cind_mml_mub_membership_typeid = m1.cind_mml_mub_membership_type_id)
ON c.contactid = m1.cind_contact_id
AND (m1.statuscode = 1
OR m1.statuscode = 434578)
AND m1.statecode = 0
LEFT JOIN Filteredcind_mml_mub_local_union k1
ON m1.cind_mml_mub_local_union_id = k1.cind_mml_mub_local_unionid
LEFT JOIN (Filteredcind_mml_mub_membership m2
INNER JOIN (SELECT mt2.cind_mml_mub_membership_typeid
FROM Filteredcind_mml_mub_membership_type mt2
WHERE mt2.cind_code = 'EXTR-01') mtt2
ON mtt2.cind_mml_mub_membership_typeid = m2.cind_mml_mub_membership_type_id)
ON c.contactid = m2.cind_contact_id
AND (m2.statuscode = 1
OR m2.statuscode = 126670001)
AND m2.statecode = 0
LEFT JOIN Filteredcind_mml_mub_local_union k2
ON m2.cind_mml_mub_local_union_id = k2.cind_mml_mub_local_unionid
WHERE subscr.statuscode = 1
AND subscr.statecode = 0";
}
If SELECT * works then its likely to be a timeout issue. However you should be receiving an exception.
The default timeout is 30 seconds.
How long does it take your query to run in MSSQL?
change the timeout by setting
cmd.Timeout = 300; // Change the number of seconds.
Alternatively improve the efficiency of your query.
Reduce your SQL line by line then you'll find the problem. Start with dropping all column, use * instead (as CathalMF said), then drop the joins, one by one.
I am working on a Windows Forms C# Application in which I have a method which has nested for loop that is used to retrieve data from an SQL Table with different parameters (trademonth and paymentmonth that are passed from the row and column headers of a DataGridView and the function also stores the data retrieved from the table into the DataGridView.
As I have around 36 rows (trademonths) and 31 columns (paymentmonths), So the for loops run the same query with different parameters for 36*31 times.
I have the following lines of code in the function
public void CalculatePoolPayments(DataGridView datagridpool, string poolpayments, string poolpaymentadjustments)
{
sqlcon = GetConnectionString();
try
{
sqlcon.Open();
for (int i = 0; i < datagridpool.RowCount; i++)
{
int trademonth = Convert.ToInt32(datagridpool.Rows[i].HeaderCell.Value);
for (int j = 0; j < datagridpool.ColumnCount; j++)
{
int paymentmonth = Convert.ToInt32(datagridpool.Columns[j].HeaderCell.Value);
SqlCommand poolpaymentscmd = new SqlCommand(poolpayments, sqlcon);
poolpaymentscmd.Parameters.AddWithValue("#trademonth", trademonth);
poolpaymentscmd.Parameters.AddWithValue("#paymentmonth", paymentmonth);
DataTable dtExpectedAmount = new DataTable();
SqlDataAdapter daExpectedAmount = new SqlDataAdapter();
daExpectedAmount.SelectCommand = poolpaymentscmd;
daExpectedAmount.Fill(dtExpectedAmount);
SqlCommand poolpaymentsadjustmentcmd = new SqlCommand(poolpaymentadjustments, sqlcon);
poolpaymentsadjustmentcmd.Parameters.AddWithValue("#trademonth", trademonth);
poolpaymentsadjustmentcmd.Parameters.AddWithValue("#paymentmonth", paymentmonth);
DataTable dtAdjustment = new DataTable();
SqlDataAdapter daAdjustment = new SqlDataAdapter();
daAdjustment.SelectCommand = poolpaymentsadjustmentcmd;
daAdjustment.Fill(dtAdjustment);
if (dtExpectedAmount.Rows[0][0].ToString() != "")
{
datagridpool.Rows[i].Cells[j].Value = dtExpectedAmount.Rows[0][0].ToString();
if (dtAdjustment.Rows[0][0].ToString() != "")
{
datagridpool.Rows[i].Cells[j].Value = (Convert.ToDouble(dtAdjustment.Rows[0][0].ToString()) + Convert.ToDouble(dtExpectedAmount.Rows[0][0].ToString())).ToString();
}
}
else
datagridpool.Rows[i].Cells[j].Value = 0;
if (dtExpectedAmount.Rows[0][0].ToString() == "" && dtAdjustment.Rows[0][0].ToString() != "")
{
datagridpool.Rows[i].Cells[j].Value = dtAdjustment.Rows[0][0].ToString();
}
// MessageBox.Show(datagridpool.Rows[0].Cells[9].Value.ToString());
}
}
sqlcon.Close();
}
catch (SqlException se)
{
MessageBox.Show(se.Message);
sqlcon.Close();
}
}
SQL Queries
string poolpayments = #"SELECT SUM(a.ExpectedAmt) AS Payment
FROM PaymentReceivable AS a WITH (nolock) LEFT OUTER JOIN
Confirmations AS b WITH (nolock) ON a.ConfirmationID = b.ID LEFT OUTER JOIN
Users AS c WITH (nolock) ON b.BuyBroker = c.ID LEFT OUTER JOIN
Users AS d WITH (nolock) ON b.SellBroker = d.ID
WHERE (a.TradeDateMonth = #trademonth) AND (a.Payment = 'True') AND (a.PaymentDateMonth = #paymentmonth) AND (Adjustment=0 OR Adjustment IS NULL)";
string poolpaymentadjustments = #"SELECT SUM(a.Adjustment) AS Payment
FROM PaymentReceivable AS a WITH (nolock) LEFT OUTER JOIN
Confirmations AS b WITH (nolock) ON a.ConfirmationID = b.ID LEFT OUTER JOIN
Users AS c WITH (nolock) ON b.BuyBroker = c.ID LEFT OUTER JOIN
Users AS d WITH (nolock) ON b.SellBroker = d.ID
WHERE (a.TradeDateMonth = #trademonth) AND (a.Payment = 'True') AND (a.PaymentDateMonth = #paymentmonth) AND (Adjustment!=0 OR Adjustment IS NOT NULL)";
As you can see from the above code I am running two different queries poolpaymentscmd and poolpaymentsadjustmentcmd with parameters trademonth and paymentmonth.
The function is taking around 90 seconds to execute and I am using the same function two times as required by my application. So, the single function is taking up to 180 seconds which I feel is too high for the application.
Is there any better way I can reduce the execution time