I have a SQL table which stores the different rates charged to clients.
The table also includes a list of 'default' rates to be used if the client has none specific to them.
What I need, is once the user selects a client from a combo box, to create a table of rates for that client, consisting of the defaults, or the rates specific to that client, or a mix of both, as follows:
Client Type of Work Rate
ABC Ltd Type A 100
XYZ & Co Type B 150
Default Type A 125
Default Type B 175
So the rates returned would look as follows:
ABC Ltd Type A 100
Type B 175 (default)
XYZ & Co Type A 125 (default)
Type B 150
Anyone else Type A 125 (default)
Type B 175 (default)
The information in the database is structured as follows
Table for clients
Table for Types of Work
Table for Rates (foreign keys linking to clients and types of work)
Can anyone explain how best to obtain the above result using either a SQL statement, a C# routine in the winforms application or a combination of both.
PS. I apologise but I'm unsure how to set my data out in tables on this website.
WHAT I HAVE TRIED SO FAR
public static DataTable TableOfRates(string pIPName = "Default")
{
try
{
string sqlText1 = "SELECT RateID, IPName, RateName, Rate, DateFrom, DateTo, Active, " +
"(RateName + ': £' + CONVERT(VARCHAR, Rate) + CONVERT(VARCHAR, " +
"(CASE WHEN Active = '1' THEN ' (Active)' ELSE ' (Inactive)' END))) AS ListRate " +
"FROM tblRates WHERE IPName IS NULL AND Active = 'true';";
aSqlQuery cQ1 = new aSqlQuery(sqlText1, "table");
DataTable defaultRates = cQ1.TableResult;
string sqlText2 = "SELECT RateID, IPName, RateName, Rate, DateFrom, DateTo, Active, " +
"(RateName + ': £' + CONVERT(VARCHAR, Rate) + CONVERT(VARCHAR, " +
"(CASE WHEN Active = '1' THEN ' (Active)' ELSE ' (Inactive)' END))) AS ListRate " +
"FROM tblRates WHERE IPName = '" + pIPName + "' " +
"AND Active = 'true';";
aSqlQuery cQ2 = new aSqlQuery(sqlText2, "table");
DataTable clientRates = cQ2.TableResult;
foreach(DataRow defaultRow in defaultRates.Rows)
{
string defaultType = defaultRow["RateName"].ToString();
foreach (DataRow clientRow in clientRates.Rows)
{
string clientType = clientRow["RateName"].ToString();
if (defaultType == clientType)
{
clientRates.Rows.Add(defaultRow.ItemArray);
}
}
}
return clientRates;
}
catch (Exception eX)
{
throw new Exception("cRate: Error compiling Table Of Rates (mode = '" + pIPName + "')" + Environment.NewLine + eX.Message);
}
}
However, whether I use Add Row, Import Row, or Add Item Array I get errors. It doesnt seem to like using datarows from more than one table.
You must have a table that lists clients and jobs - with that in mind you might be doing something like the following
SELECT
CASE R1.RATE WHEN NULL THEN R2.RATE else r1.rate AS RATE END
FROM
CLIENTJOBS C LEFT JOIN RATES R1 ON
R1.CLIENT = C.CLIENT AND R1.WORKTYPE = C.WORKTYPE
JOIN RATES R2 ON
R2.WORKTYPE = C.WORKTYPE AND R2.CLIENT = 'DEFAULT'
bear in mind this is untested guess-code, but hopefully points you in the right direction
If you really need to load up a DataTable:
CREATE TABLE
#MyTempTable (myColumn1 DataType, myColumn2 DataType, myColumn3 DataType)
INSERT INTO
#MyTempTable(myColumn1, myColumn2, myColumn3)
SELECT
f.Bar1, o.Bar2, o.Bar3 FROM FooTable AS f
INNER JOIN
TableFoo o ON f.Bar1 = o.Bar1
With some tweaking this script would create a temporary table that persists as long as your connection is kept alive and contains the data from the other tables that you need.
Related
I have a gridview in which I have bind data from Database. The Problem is The data is approximately 12000+ rows and It is taking too much time to load the gridview. I don't want paging in my Grid. So NO pagination. It is possible to make it fast retrieval? I am getting data through Stored Procedure from Database and I have uploaded my database in Cloud.
This is my Stored Procedure
SELECT
A.ItemCode as 'Item Code'
,rtrim(A.PartItemNo) as 'Item No'
,rtrim(A.ItemDesc) as 'Item Description'
,rtrim(IsNull(isnull(Sum(B.INQty),0) + Sum(B.RecQty) + Sum(B.PurRetQty) + Sum(B.RetQty) - ((Sum(B.IssQty) + Sum(B.ChargeOutQty)) ), 0)) As Quantity
,A.ProdCode
,A.PurchaseRate
,A.SaleRate
,A.Source
from Item A
Left outer Join ItemStock B
On A.ItemCode=B.ItemCode
And A.DealerCode=B.DealerCode
Where (A.DealerCode=#DealerCode and #Category = '')
or (A.DealerCode=#DealerCode and #Category = 'P' and A.LubeFlag = 'N')
or (A.DealerCode=#DealerCode and #Category = 'L' and A.LubeFlag = 'Y')
or (A.DealerCode=#DealerCode and #Category = 'PL' AND Source not in ('C.K.D.' , 'LOCAL'))
Group by A.ItemCode,A.ItemDesc,A.PartItemNo,A.ProdCode,A.PurchaseRate,A.SaleRate,A.Source Order by A.ItemCode asc
This is the Code in C# Asp.Net
sQuery = "test '" + Session["DealerCode"].ToString() + "', 'P'";
if (myFunc.ExecuteQuery(sQuery, ref ds))
{
Session["Parts"] = ds;
if (ds.Tables[0].Rows.Count > 0)
{
gvParts.DataSource = ds.Tables[0]; gvParts.DataBind();
gvParts.HeaderRow.TableSection = TableRowSection.TableHeader;
}
}
I have to take the data from MS Access DB to another.
This was insert statement used
cmd.CommandText = #"Insert Into [MS Access;PWD=pw;DATABASE=" + currentDBPath + #"].[Orders] Select * FROM [Orders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";
This statement works fine. But some one started to enter the data directly to target database and also in the source. This created duplicated records. Now I want to copy those orders from source which are not in the target DB's table.
Assuming Orders table has a primary key named IDOrers, you must bring both tables to one DB, so you can compare data.
Easy option: have in Sours DB a link to [Orders] on Destination DB, named OrdersDest. In that case you create on destination a query of missing orders, named MissingOrders :
SELECT Orders.* FROM Orders LEFT JOIN OrdersDest ON OrdersDest.IDOrders = Orders.IDOrders WHERE OrdersDest.IDOrders Is Null
Your Command will now look like this:
cmd.CommandText = #"Insert Into [MS Access;PWD=pw;DATABASE=" + currentDBPath + #"].[Orders] Select * FROM [MissingOrders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";
You could also pass the data through this linked table:
cmd.CommandText = #"Insert Into [OrdersDest] Select * FROM [MissingOrders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";
I didn't find any solution to what I was looking for in my question , So I decided to just delete the duplicated data in destination database.
I used the below statement to delete the data ,
Delete * from Orders where AutoOrderID in (SELECT Orders.AutoOrderID FROM Orders Inner JOIN OrdersSource ON OrdersSource .OrderId = Orders.OrderId and OrdersSource .OrderDate=Orders.OrderDate);
I am trying to insert data in my table which have 3 feild
(1) sendReqID type int(PK)
(2) RequestID type int (FK from table Request)
(3) DonorID type int (FK table Donor)
I know how to copy data from one table and insert into another table but I want to know how to insert data in table, when we have to extract values from two different tables. Following is my code which I am trying and unable to insert data into my table.
public void Req_SendID()
{
SqlConnection MySQL = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ToString());
string copy = "insert into Send_Request(RequestID,DonorID) Select RequestID,DonorID from RequestID and DonorID from Donor where R_City='" + Session["BGroup"] + "' and" + "D_City='" + Session["city"] + "'";
SqlCommand com = new SqlCommand(copy, MySQL);
MySQL.Open();
com.ExecuteNonQuery();
MySQL.Close();
}
Please Help thanks in advance.
You need to join on the two tables...
insert into Send_Request(RequestID,DonorID)
Select r.RequestID, d.DonorID
from RequestID r inner join Donor d ON r.R_City = d.D_City
where R_City='" + Session["BGroup"] + "' and " + "D_City='" + Session["city"] + "'"
I'm assuming the relationship is as above. However, consider SQL Injection attacks and look to parametrize your query.
EDIT: Using Parameterized Query
var requestCity = Session["BGroup"].ToString();
var donorCity = Session["city"].ToString();
"insert into Send_Request(RequestID,DonorID)
Select r.RequestID, d.DonorID
from RequestID r inner join Donor d ON r.R_City = d.D_City
where R_City=#RequestCity and D_City=#DonorCity"
SqlCommand com = new SqlCommand(copy, MySQL);
com.Parameters.Add("#RequestCity", requestCity);
com.Parameters.Add("#DonorCity", donorCity);
....
However, I just saw your comment that there is no relationship between the tables, so the actual query above would be incorrect.
Question is related to a question I asked before, but I need a little help...
I have an interest table, which stores interests for Seekers and Employers...
Interest table is like:
int_id FK_is_ID FK_ie_ID FK_ic_ID
-------------------------------------
1 2 null 3
2 2 null 5
3 null 1 3
4 null 3 1
5 null 2 5
6 4 null 1
6 3 1 2
FK_is_id = Seeker ID
FK_ie_id = Employer ID
FK_ic_id = Category ID
So when a seeker logs in, I am trying to retrieve EMPLOYER names who have similar interests to the logged in seeker...
I have a code which works fine, gives OUTPUT I want..
SqlConnection myConn2;
SqlCommand myCommand2;
SqlDataReader myReader2;
String SQL2, divjobs;
myConn2 = new SqlConnection(WebConfigurationManager.ConnectionStrings["ApplicationServices"].ToString());
divjobs = "<ul>";
myConn2.Open();
SQL2 = "SELECT ins.int_id, ins.FK_is_ID, ine.FK_ie_ID,emp.e_name,ine.int_id FROM Interests ins INNER JOIN Interests ine ON ins.FK_ic_ID = ine.FK_ic_ID FULL OUTER JOIN employers emp ON emp.e_id=ine.FK_ie_id WHERE ins.FK_is_ID = #sid AND ine.FK_ie_ID IS NOT null order by emp.e_name ASC";
myCommand2 = new SqlCommand(SQL2, myConn2);
myCommand2.Parameters.AddWithValue("#sid", ssid);
myReader2 = myCommand2.ExecuteReader();
if (myReader2.HasRows)
{
while (myReader2.Read())
{
divjobs = divjobs + "<li>" + "<a href='../employers/viewemployer.aspx?EID=" + myReader2["FK_ie_id"] + "'>" + "<div class='jtitle'>" + myReader2["e_name"] + "</div>" + "</li>";
}
divjobs = divjobs + "</ul>";
joblist.InnerHtml = divjobs;
}
else
{
joblist.InnerHtml = "<div style='font-weight:bold;padding:20px;font-size:1.2em;background-color:white;'>"+ "Looks like there is nothing to load!" + "</div>";
}
myConn2.Close();
The only problem is if an employer has 2 interests, the output gives same employer name twice! I want it to come only once... !
Is there anyway to do it, any help would be appreciated... ?
Currently, your results are at the "interest" level, but you really want it at the employer level - the following would return a distinct list of the employers with matching interests - I also threw an aggregation (count) of the matching interests for each:
SELECT
ins.FK_ie_ID,
emp.e_name,
COUNT(ins.int_id) AS InterestCount
FROM
Interests ins
INNER JOIN
Interests ine
ON ins.FK_ic_ID = ine.FK_ic_ID
INNER JOIN
employers emp
ON emp.e_id = ine.FK_ie_id
WHERE
ins.FK_is_ID = #sid
GROUP BY
ins.FK_ie_ID,
emp.e_name
order by emp.e_name ASC
I hope I interpreted what your wanted correctly.
Also, I found your column naming to be extremely awkward to work with. There very well may be typos in the query because of this. Is there a reason they are so cryptic...or, are they out of your control?
I've got an ASP.NET 4.0 C# web application that allows multiple users to update rows in the SQL Server DB at the same time. I'm trying to come up with a quick system that will stop USER1 from updating a row that USER2 updated since USER1's last page refresh.
The problem I'm having is that my web application always updates the row, even when I think it shouldn't. But when I manually run the query it only updates when I think it should.
This is my SQL query in C#:
SQLString = "update statuses set stat = '" + UpdaterDD.SelectedValue +
"', tester = '" + Session["Username"].ToString() +
"', timestamp_m = '" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") +
"' where id IN (" + IDs + ") and timestamp_m < '" + PageLoadTime + "';";
And here's a 'real world' example:
SQLString = "update statuses set stat = 'PASS', tester = 'tester007',
timestamp_m = '2013-01-23 14:20:07.221' where id IN (122645) and
timestamp_m < '2013-01-23 14:20:06.164';"
My idea was that this will only update if no other user has changed this row since the user last loaded the page. I have formatted PageLoadTime to the same formatting as my SQL Server DB, as you can see with DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), but something still isn't right.
Does anyone know why I get two different results? Is what I want to do even possible?
I really think the problem is that the page load time is not being set correctly, or is being set immediately before the DB call. For debugging, you may try hardcoding values into it that you know will allow or disallow the insert.
Here's a parameterized version of what you have. I also am letting the DB server set the timestamp to its current time instead of passing a value. If your DB server and your Web server may not have their time of day in synch, then set it yourself.
Using parameterization, you don't have to worry about whether the date/time format is correct or not. I don't know what the DB types are of stat, tester, and timestamp_m so adding the parameter DB type may need adjusting.
string sql = "update statuses set stat = #stat, tester = #tester" +
", timestamp_m = getdate()" +
" where id IN (" + IDs + ") and timestamp_m < #pageLoadTime";
SQLConnection conn = getMeASqlConnection();
SQLCommand cmd = new SQLCommand(sql, conn);
cmd.Parameters.Add("#stat", System.Data.SqlDbType.NVarChar).Value = UpdaterDD.SelectedValue;
cmd.Parameters.Add("#tester", System.Data.SqlDbType.NVarChar).Value = Session["Username"].ToString();
// Here, pageLoadTime is a DateTime object, not a string
cmd.Parameters.Add("#pageLoadTime", System.Data.SqlDbType.DateTime).Value = pageLoadTime;