Problems using Select query in sql server & asp.net - asp.net

SELECT *
FROM [productDetail]
WHERE
Price BETWEEN 0 AND 2000
OR Price BETWEEN 2000 AND 12000
AND CategoryID = 2
AND caravanOffline = 0
ORDER BY
price
The query doesn't produce the desired output, it also shows the products whose categoryID is 3,1 etc.
Can any one spot the problem in the query.
Updated code:
static public DataTable GetSelectedFilterMotorhomes(ArrayList caravans)
{
string sqldefault = "Select * from productDetail Where";
string sqlBuilder = "";
int starter = 0;
int count = caravans.Count;
string sqlOperator = "OR";
if (caravans.Count > 0)
{
while (count > starter) //build the query depending on the number of caravans.selected.count
{
sqlBuilder += "((Price between " + caravans[count - 1] + "))" + sqlOperator;
count--;
}
string addQuery = sqldefault + sqlBuilder;
string removeOR = addQuery.Substring(0, addQuery.Length - 2); //remove OR
string finalQuery = removeOR + "AND (CategoryID = 2) AND (caravanOffline = 0) order by Price"; //Display caravans in ascending order
SqlDataAdapter da = new SqlDataAdapter(finalQuery, ConnectionString);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
else
{
string returnAllCaravans = "Select * from productDetail WHERE CategoryID = 2 AND caravanOffline = 0";
SqlDataAdapter da = new SqlDataAdapter(returnAllCaravans, ConnectionString);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}

You may need some parenthesis? I'd need to know exactly what you were trying to pull back with your query but likely you need a parenthesis after the OR and then again either after the CategoryID = 2 or after the caravanOffline = 0. See if either of the following queries returns what you're looking for.
Select
*
from [productDetail]
WHERE
Price between 0 AND 2000
OR (Price between 2000 AND 12000 AND CategoryID = 2) AND caravanOffline = 0
order by price
Select
*
from [productDetail]
WHERE
Price between 0 AND 2000
OR (Price between 2000 AND 12000 AND CategoryID = 2 AND caravanOffline = 0)
order by price

What do you really want to do with your WHERE clause?? Without any parenthesis, it's not clear at all what you're trying to select
DO you really mean:
WHERE
(Price BETWEEN 0 AND 2000 OR Price BETWEEN 2000 AND 12000)
AND CategoryID = 2
AND caravanOffline = 0
Price is between 0 and 2000, or between 2000 and 12000 (doesn't really make sense), AND in any case, the CategoryID is 2 ?
Or do you mean:
WHERE
Price BETWEEN 0 AND 2000
OR
(Price BETWEEN 2000 AND 12000 AND CategoryID = 2 AND caravanOffline = 0)
The price is either between 0 and 2000 (with no other restriction) OR the price is between 2000 and 12000, but only if the CategoryID = 2 and CaravanOffline = 0 are true at the same time) ??
Or are you looking for something else than these two options??

I think it might need some brackets...
SELECT * FROM productDetail
WHERE Price BETWEEN 0 AND 2000
OR (Price BETWEEN 2000 AND 12000
AND CategoryId = 2
AND caravanOffline = 0)
ORDER BY price
Assuming that's the logic you want! Your question is rather vague, I'm assuming that you want caravans under 2000 regardless of category and caravanOffline, or caravans between 2000 and 12000 with a categoryid of 2 and caravanOffline of 0.

Related

How to select the correct rows in a gridview after sort

I have been working on this gridview project for a few days and have been able to make some progress. Where I am having difficulty is after sorting the gridview which works fine, I want to take the selected rows from my gridview and place those selected rows into a repeater control. I have been looking here for people with the same issue and have tried using viewstate but I continue to only get the default sort order into the repeater control. Example row 0 is selected with the name john smith after sort I have jane doe at row 0 but when selecting row 0 and jane doe I get john smith in the repeater control. I know that this has to be something simple but I have tried many things with not luck.
This is my sort code which works.
protected void GridView1_Sorting1(object sender, GridViewSortEventArgs e)
{
DataTable dtrslt = (DataTable)ViewState["dirState"];
if (dtrslt.Rows.Count > 0)
{
if (Convert.ToString(ViewState["sortdr"]) == "Asc")
{
dtrslt.DefaultView.Sort = e.SortExpression + " Desc";
ViewState["sortdr"] = "Desc";
}
else
{
dtrslt.DefaultView.Sort = e.SortExpression + " Asc";
ViewState["sortdr"] = "Asc";
}
ViewState["sortexp"] = e.SortExpression; //resort and store.
ViewState["dirState"] = dtrslt;
GridView1.DataSource = dtrslt;
GridView1.DataBind();
}
}
Now I have a button that will copy the data from the first datatable to a new datatable which only contains the selected rows. I am sure that I am having the computer do more work than it should but I was trying everything.
This code below is copying the data into the new datatable and binding to the repeater control. Works fine if I don't sort the gridview. Please let me know your thoughts or if I need to provide additional information.
protected void CopyToDataTable(object sender, EventArgs e)
{
//Create a new DataTable.
DataTable dtNotary = new DataTable();
DataTable dtrslt = (DataTable)ViewState["dirState"];
dtNotary = dtrslt.Clone();
DataRow dr = dtrslt.Rows[0];
//Loop through the GridView and copy rows.
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox ckBox = (CheckBox)gRow.FindControl("notaryselect");
if (ckBox.Checked)
{
dr = dtrslt.Rows[gRow.RowIndex];
dtNotary.ImportRow(dr);
}
}
RepeaterNotary.DataSource = dtNotary
RepeaterNotary.DataBind();
}
Ok, keep in mind that you using the "default" view.
that means the table (and hence row index INTO that table will not match) after you sort.
So, when you use a "data view", it does NOT effect nor change the order of hte base table.
So, this:
DataTable rstData = new DataTable();
rstData = General.MyRst("SELECT ID, HotelName FROM tblHotelsA");
for (int i = 0; i < rstData.Rows.Count; i++)
{
Debug.Print($"{rstData.Rows[i]["ID"].ToString()} H= {rstData.Rows[i]["HotelName"]}");
}
// now sort table by id REVERSE order!
rstData.DefaultView.Sort = "ID DESC";
for (int i = 0; i < rstData.Rows.Count; i++)
{
Debug.Print($"{rstData.Rows[i]["ID"].ToString()} H= {rstData.Rows[i]["HotelName"]}");
}
Debug.Print("---- sorted output");
foreach(DataRowView OneRow in rstData.DefaultView)
{
Debug.Print($"{OneRow["ID"].ToString()} H= {OneRow["HotelName"]}");
}
Output:
1 H = My Cool
2 H = Ramada Lodge
3 H = Sandman Inn
4 H = Super 8
5 H = Inns of Banff
6 H = Swiss Village
7 H = Mary's Motel
16 H = Batman's Cave
1 H = My Cool
2 H = Ramada Lodge
3 H = Sandman Inn
4 H = Super 8
5 H = Inns of Banff
6 H = Swiss Village
7 H = Mary's Motel
16 H = Batman's Cave
---- sorted output
16 H = Batman's Cave
7 H = Mary's Motel
6 H = Swiss Village
5 H = Inns of Banff
4 H = Super 8
3 H = Sandman Inn
2 H = Ramada Lodge
1 H = My Cool
NOTE VERY close - after I sorted the "data view", the table order DOES not change when I reference the rows!!!!
Only the 3rd run shows the data sorted. And you could do say this:
Debug.Print("---- sorted output example 2");
DataTable dt2 = rstData.DefaultView.ToTable();
for (int i = 0; i < dt2.Rows.Count; i++)
{
Debug.Print($"{dt2.Rows[i]["ID"].ToString()} H= {dt2.Rows[i]["HotelName"]}");
}
So, in above, I used the "totable()" to get a real sorted view!
Now, lets check the results of that table in the grid view.
this will show this even better:
DataTable rstData = new DataTable();
rstData = General.MyRst("SELECT ID, HotelName FROM tblHotelsA");
// now sort table by id REVERSE order!
rstData.DefaultView.Sort = "ID DESC";
GridView1.DataSource = rstData;
GridView1.DataBind();
foreach (GridViewRow gRow in GridView1.Rows)
{
Debug.Print($"Grid row {gRow.RowIndex} First GV ID = {gRow.Cells[0].Text} First Table row ID = {rstData.Rows[gRow.RowIndex]["ID"]}");
}
Output:
Grid row 0 First GV ID = 16 First Table row ID = 1
Grid row 1 First GV ID = 7 First Table row ID = 2
Grid row 2 First GV ID = 6 First Table row ID = 3
Grid row 3 First GV ID = 5 First Table row ID = 4
Grid row 4 First GV ID = 4 First Table row ID = 5
Grid row 5 First GV ID = 3 First Table row ID = 6
Grid row 6 First GV ID = 2 First Table row ID = 7
Grid row 7 First GV ID = 1 First Table row ID = 16
So, once again, you can see the "default" view is used by the GV, but the base table is still not sorted.
I tend to NOT use the built in "default" data view, since you can wind up with the above confusing. thus, a lot of my code feeds the "data view" to the table, and not the "default view". I do this "only" to reduce confusing.
eg this code is common:
Dim rstGridData As DataTable
rstGridData = MyrstP(cmdSQL)
Dim dView As DataView = rstGridData.DefaultView
dView.RowFilter = strWhere
dView.Sort = "QuoteDate DESC, ID DESC"
Me.ListView1.DataSource = rstBlank
Note HOW I send the data view to the gridview/lv in above.
Ok, I (probably spent too much time on above - my sorry!!).
So, next up:
I would actually re-pull the data based on the PK settings. both GV, and LV have what is called "data keys", and it is a great collection of the PK row "id", and even better is NEVER exposed to the client side browser (good for security - people can't mess with your pk's in the markup!!!).
And also, keep in mind for most cases, re-pulling the data will cost LESS then persisting the data table in viewstate!!!
So, I would say suggest using this:
string MyIdList = "";
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox ckBox = (CheckBox)gRow.FindControl("chkActive");
if (ckBox.Checked)
{
if (MyIdList != "")
MyIdList += ",";
MyIdList += GridView1.DataKeys[gRow.RowIndex]["ID"].ToString();
}
}
DataView MyView = rstData.DefaultView;
MyView.RowFilter = $"ID IN({MyIdList})";
Repeater1.DataSource = MyView;
Repeater1.DataBind();
In other words, operate by PK database ID (assuming you have one).
So, in the gv define, you need to set the datakeys "ID" (column name) of the PK value.
eg:
<asp:GridView ID="GridView1" runat="server" CssClass="table"
DataKeyNames="ID" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
etc.
So, datakeys is nice, since then based on GV row, you can always get/have use of the database PK row id, we don't care about order, and even better is the PK row idea does not have to be exposed nor included in the markup.

Retrieve id with condition

I am trying to allocate academy for student with only one click. This allocation need to have condition before allocating a specific academy to the student.
Here are my database tables:
tblAcademy
Acad_id name seat_available
------------------------------
1 A 2
2 B 2
3 C 1
4 D 5
5 E 3
tblStudent
stud_Id name `stud_purcentage` `stud_result` acad_id
----------------------------------------------------------
1 Alex 100 `Pass`
2 Lee 80.5 `Pass`
3 Lea 40.3 `Fail`
4 Loane 10 `Fail`
5 john 50 `Pass`
tblAcademy_selection
stud_id Acad_id order_preference
--------------------------------
1 1 1
1 3 2
4 3 1
4 2 2
4 4 3
Acad_id is foreign key of tblAcademy. The acad_id can remain null if the condition is not respected a student may do not have academy.
In the tblAcademy selection it shows that a student can select many academy but only one has to be allocate to them.
The allocation must be based on the seat available by the academy, on those who pass and allocate those from best percentage to the worst.
Till now I have been able to retrieve from the best to worst student and those who passed. I have then join those student id to the tblAcademy_selection.
SqlConnection dbcon = new SqlConnection(_conString);
SqlCommand scmd = new SqlCommand();
scmd.CommandText = "SELECT stud_Id, stud_fname, stud_purcentage, stud_totalMarks FROM tblStudent WHERE stud_result = 'Pass' ORDER BY stud_purcentage DESC";
scmd.Connection = dbcon;
SqlDataAdapter da = new SqlDataAdapter(scmd);
DataTable dt = new DataTable();
dbcon.Open();
da.Fill(dt);
string[] array = new string[dt.Rows.Count];
// foreach (DataRow row in dt.Rows)
for (int a = 0; a < dt.Rows.Count; a++)
{
// studID = row["stud_Id"].ToString();
array[a] = dt.Rows[a]["stud_Id"].ToString();
SqlCommand scmd2 = new SqlCommand();
scmd2.CommandText = "SELECT * FROM tblAcademy ta JOIN tblAcademy_Selection tas ON ta.acad_Id = tas.acad_Id WHERE stud_Id IN ('" + array[a] + "')";
scmd2.Connection = dbcon;
SqlDataAdapter da2 = new SqlDataAdapter(scmd2);
DataTable dt2 = new DataTable();
da2.Fill(dt2);
string[] array2 = new string[dt2.Rows.Count];
for (int a2 = 0; a2 < dt2.Rows.Count; a2++)
{
array2[a2] = dt2.Rows[a2]["stud_Id"].ToString();
SqlCommand scmd3 = new SqlCommand();
}
}
In my first SQL statement I have selected those who have best percentage and those whose who passed and stored in an array.
With the for loop I am retrieving the data table value
In the second SQL statement, I have made a join with tblAcademy and tblAcademy_selection where the tblAcademy_selection.stud_id is in the retrieve value that I have done in the first statement.
I am having difficulty to apply the condition in which if an student choice of academy seat is full it move to the second choice and if the second is full it move to the third and so on.
A student may not have academy if all his choice academy seat is full.
You have to apply a filter condition in your SQL statement to filter out records with tblAcademy.seat_available = 0.
Then generate a row_number or rank based on order preference and retrieve records with generated row_number =1.
Something like this:
SELECT * FROM
(
SELECT tas.*, DENSE_RANK() OVER (PARTITION BY stud_id ORDER BY order_preference) AS row_id
FROM tblAcademy ta
JOIN tblAcademy_Selection tas ON ta.acad_Id = tas.acad_Id
WHERE ta.seat_available >0 and stud_Id IN ('" + array[a] + "')"
) DTL
WHERE row_id = 1

Database value in label asp.net c#

I am trying to get value from database to be display in label. First i have to get the value of the dropdownlist and retrieved from database based on it. After that, I need to get the titlePromo column into my Label.
Currently i have the code out but i am not sure if it is the right one. There is no error but it displayed the membershipType column instead of the titlePromo.
ID titlePromo membershipType defaults
-- ---------- -------------- ------
1 Promo 1 Membership Promotion Y
2 Promo 2 Membership Renewal Y
3 Promo 3 Membership Grad Y
4 Promo 4 Membership Promotion N
5 Promo 5 Membership Promotion N
6 Promo 6 Membership Grad N
My codes that i have done so far:
string strConnectionString = ConfigurationManager.ConnectionStrings["FYPDB"].ConnectionString;
SqlConnection myConnect = new SqlConnection(strConnectionString);
string strCommandText2 = "select * FROM FYPDB.dbo.Promotions where membershipType = '%' + #membership + '%' AND defaults = 'Y'";
string ddlmembership = ((DropDownList)dvInsertPromotion.FindControl("ddlAddMembershiplist")).SelectedItem.ToString();
cmd.Parameters.Add("#membership", SqlDbType.NVarChar);
cmd.Parameters["#membership"].Value = ddlmembership;
DataSet da2 = dal.retrieveTitle(ddlmembership);
SqlCommand cmd2 = new SqlCommand(strCommandText2, myConnect);
((Label)pnlDefaultPopup.FindControl("Label13")).Visible = true;
((Label)pnlDefaultPopup.FindControl("Label13")).Text = da2.Tables[0].Rows[0]["titlePromo"].ToString();
html:
.cs
public DataSet retrieveTitle(String membership)
{
SqlParameter[] parameters = new SqlParameter[]{
new SqlParameter("#membership", SqlDbType.NVarChar),
};
parameters[0].Value = membership;
DataSet ds = new DataSet();
ds = commons.ExecuteDataSet("Select * FROM Promotions WHERE (membershipType = '" + membership + "') AND defaults = 'Y' ");
return ds;
}
Before giving you my suggestion I would like to make some remarks to your existing code:
you should select only the titlePromo in your query, as you only need one field, and not the entire row (therefore you wouldn't need a dataset in the first place)
the naming of your function is not according to its scope, at it does not retrieve the title, but an entire entry in the promotions table.
in this structure "membershipType = '%' + #membership + '%'" the syntax is not correct. The wildcards are used together with the "like" keyword
Bellow, you can find my code sample of how would I implement it if I were you:
static void Main(string[] args)
{
using (SqlConnection PubsConn = new SqlConnection(yourConnectionString))
{
//code to retrieve membership
var membership = "Membership Promotion";
var title = retrieveTitle(PubsConn, membership);
//code to set up label
}
}
public static string retrieveTitle(SqlConnection conn, String membership)
{
conn.Open();
var title = string.Empty;
string strCommandText = "select top 1 titlePromo FROM Promotions where membershipType = #membership AND defaults = 'Y'";
SqlCommand commmand = new SqlCommand(strCommandText, conn);
commmand.Parameters.AddWithValue("#membership", membership);
try
{
using (SqlDataReader reader = commmand.ExecuteReader())
{
if (reader != null && reader.Read())
{
title = Convert.ToString(reader["titlePromo"]);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error while retrieving table: " + ex.Message);
}
conn.Close();
return title;
}
If you want to use wildcards and 'like', you can do it like this:
string strCommandText = "select top 1 titlePromo FROM membershipTest where membershipType like #membership AND defaults = 'Y'";
SqlCommand commmand = new SqlCommand(strCommandText, conn);
commmand.Parameters.AddWithValue("#membership", "%" + membership + "%");

Getting data according to last hours from sqlite

I want to get records out of sqlite database according to hours. following are my questions
1) I have to extract all data from sqlite for past one hour. I have tried following query but it provide me data for all the hours in present day
Query:
SELECT * FROM Table1 where Date >= datetime('now','-1 hours')
Where Table1 is my table name and Date is coloumn name of type DATETIME
Eg: there are following record in database
When I fire query in sqlite firefox browser tool it returns me
which I do not want.
What should be the query to get past 1 hour data from database
2) What should be query to get the value out of database according to every hours, like I have to get data for past 1 hour, then data of past 1-2 hour, the data of past 2-3 hour i.e an hour data between two hours?
Any Help will be appreciated.
Use this query for question 1 -
`select * from Table1 where(Date between '(Select Date from Table1 order by Date asc limit 1)' and 'date1');`
date1 should be in formate yyyy-MM-dd hh:mm:ss(for example 2015-10-21 08:00:00).
In date1 you can put before 1 hour datetime.
it is working in SQLite Manager.
For question 2 -
you have to get data for every hour separately using below query
select * from Table1 where(Date between 'date1' and 'date2');
Finally I found the solution to my own question
Following is the code which worked for me
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
Calendar calendar = Calendar.getInstance();
String startDate = dateFormat.format(date);
String endDate = "";
for (int i = 1; i <= 24; i++) {
System.out.println("Start Date:- " + startDate);
calendar.add(Calendar.HOUR_OF_DAY, -1);
date = calendar.getTime();
endDate = dateFormat.format(date);
System.out.println("End Date:- " + endDate);
String data = dbAdapter.getOutDoorHourlyData(startDate, endDate);
System.out.println("Hourly Average:- " + data);
startDate = endDate;
endDate = "";
}
public String getOutDoorHourlyData(String startDate, String endDate) {
double outdoorHourly = 0;
Cursor cursor = _sqliteDB.rawQuery("Select AVG("
+ COLOUMN_NAME + ") from (Select * FROM "
+ TABLE_NAME + " where " + COLOUMN_NAME + " >= '"
+ endDate + "' and " + COLOUMN_NAME + " < '" + startDate
+ "')", null);
try {
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
do {
outdoorHourly = cursor.getDouble(0);
} while (cursor.moveToNext());
}
cursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
String hourlyData = decimalFormat.format(outdoorHourly);
hourlyData = hourlyData.replace(",", ".");
return hourlyData;
}
}
I hope it will help someone in future

Reading multiple rows of data using sqldatareader

I've the below sql statement as follows:
SELECT * FROM ViewSectorInvestments WHERE AccountNumber = #AccountNumber
Fields in ViewSectorInvestments:
AccountNumber
SectorName
AmountInvested
I'm trying to compute the AmountInvested in each sector against the total investments.
So the formula will be: AmountInvested/TotalInvestments * 100
my code is as follows:
string DMConnectionString = ConfigurationManager.ConnectionStrings["DMConnectionString"].ConnectionString;
SqlConnection DMConnection = new SqlConnection(DMConnectionString);
DMConnection.ConnectionString = DMConnectionString;
string DMCommandText = "SELECT Name,RiskProfile,AccountNumber,TotalInvestments FROM ViewClientDetails WHERE AccountNumber = #AccountNumber; SELECT * FROM ViewSectorInvestments WHERE AccountNumber = #AccountNumber ;SELECT * FROM ViewStockTypeInvestments WHERE AccountNumber = #AccountNumber ";
SqlCommand DMCommand = new SqlCommand(DMCommandText, DMConnection);
DMCommand.Parameters.AddWithValue("#AccountNumber", lb_AcctNum.Text);
DMConnection.Open();
SqlDataReader DMReader = DMCommand.ExecuteReader();
ArrayList SectorArray = new ArrayList();
ArrayList StockTypeArray = new ArrayList();
while (DMReader.Read())
{
CustName.Text = DMReader["Name"].ToString();
lb_Risk.Text = DMReader["RiskProfile"].ToString();
T_Investment.Text = DMReader.GetDecimal(DMReader.GetOrdinal("TotalInvestments")).ToString("N2");
Client_RiskProfile.Text = DMReader["RiskProfile"].ToString();
//encounter error when i add the datas into arraylist.
//System.IndexOutOfRangeException: SectorName
SectorArray.Add(DMReader.GetOrdinal("SectorName").ToString());
StockTypeArray.Add(DMReader.GetOrdinal("BlueChipName").ToString());
foreach( Object objReader in SectorArray){
//compute the percentage of amount invested in each sector
//check if the percentage is more than 25%
//if it is more than 25% lbMsg (an label) shows the name of the sector.
}
}
DMReader.Close();
DMConnection.Close();
}
When i test out the sql statement :
SELECT * FROM ViewSectorInvestments WHERE AccountNumber = #AccountNumber
The result i got is :
AccountNumber SectorName AmountInvested
1001 Commerce 97230.00000
1001 Construction 389350.00000
1001 Finance 222830.00000
1001 Hotel 14910.00000
1001 Loans 105070.00000
1001 Manufacturing 1232210.00000
1001 Mining/Quarrying 32700.00000
I encountered System.IndexOutOfRangeException: SectorName.
What's wrong with my code?
Please advice me. Thanks in advance.
string DMCommandText = "SELECT Name,RiskProfile,AccountNumber,TotalInvestments FROM ViewClientDetails WHERE AccountNumber = #AccountNumber; SELECT * FROM ViewSectorInvestments WHERE AccountNumber = #AccountNumber ;SELECT * FROM ViewStockTypeInvestments WHERE AccountNumber = #AccountNumber ";
This CommandText contains multiple queries. Only the results from the last SELECT statement will be returned to the SqlDataReader.
SectorArray.Add(DMReader.GetOrdinal("SectorName").ToString());
You are trying to access the column ordinal of a field called "SectorName" in your SqlDataReader. The problem causing your exception is probably that the column doesn't exist, but it's hard to say since you are using SELECT * in your CommandText.

Resources