how to write sql statement in c# to join data - c#

Im trying to join data from different tables and displaying them in datagrid, but im getting an error.
I'm trying to get this info from those tables. Btw, the users needs to type in his id.
RESERVATIONS
UPDATE
" + this.UserID + " is an actual ID of user (int)
bookingID : 1 (int)
bookID : 3 (int)
userID : 1 (int)
USERS
Name : Jack (string)
LastName : Jones (string)
BOOKS
NameOfTheBook : Lord of the Rings (string)
END RESULT
1, 3, 1 Jack Jones, Lord of the Rings (in a data grid table)
string Query =
"SELECT bookingID, bookID, userID, Name, LastName, NameOfTheBook " +
"FROM Reservations, Users, Books "+
"WHERE userID = " + thisUserID.Text +
" AND Users.ID = " + thisUserID.Text +
" AND Books.ID = " + thisUserID.Text + "";
ERROR
The value of at least one of the required parameters has not been determined
How do I fix it?

Step through it and take a look at what Query evaluates to. I suspect it might be you're not linking on the correct fields.
Should it read like more this? :
string Query =
"SELECT bookingID, bookID, userID, Name, LastName, NameOfTheBook " +
"FROM Reservations, Users, Books "+
"WHERE userID = " + thisUserID.Text +
" AND Users.ID = Reservations.userID"
" AND Books.ID = Reservations.bookID";
If userID is a text field then you'd have to put triple quotes in instead of single to get the userID wrapped correctly.

Related

How to update only the highest id of the same Name in c#.net database

I have this Table Data for my FullSummary Database:
I want to update ONLY the "Name, Price, and Total" for the HIGHEST Id of a selected Name.
If I select "random" the "random" with Id 52 should be the only one that will have the updated data.
I tried:
con.Open();
cmd.CommandText = "UPDATE FullSummary SET Name='" + addRiceTextBox.Text + "', Price='" + addPriceTextBox.Text + "', Total='" + newTotalEdit.Text + "' WHERE(Id, Name) IN(SELECT MAX(Id), Name FROM FullSummary GROUP BY Name)";
cmd.ExecuteNonQuery();
con.Close();
But it gave me this error:
I found the code here: select only rowwith highest id value if there are identical column values
And this one: How can I select the row with the highest ID in MySQL? only selects an item and not update it.
SQL Server doesn't support tuple comparison. So this
WHERE(Id, Name) IN (SELECT MAX(Id), Name FROM FullSummary ...)
Won't work. So you should use a scalar subquery like this (with parameters):
UPDATE FullSummary f
SET Price=#price, Total=#total
WHERE Id = (select max(ID) from FullSummary where name = #name)

SQL statement that only fetches the newest department which has been allocated

In my database i have the following rows and columns: https://i.imgur.com/ktUZY9d.jpg
My problem is the same employee has 3 different departments, but he is currently only active in 1. How do I change this SQL statement to only include the latest department he is in, which started in 2018 and ends in 2100, as seen by the ALLOCATION_START and ALLOCATION_END?
Query
string agentIdSubQuery = "SELECT DISTINCT " +
"AGENT_ID " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION " +
"WHERE " +
"LENGTH(AGENT_INITIALS) < 5";
if(queryParams.SnapshotDate.HasValue)
agentIdSubQuery += " AND " + OracleConversion.ToOracleDate(queryParams.SnapshotDate) + " BETWEEN ALLOCATION_START AND ALLOCATION_END";
Update:
Tried alot of different solutions, but it crashes everytime, when i run through the debugger, further Down in this method this Query is causing me to crash:
string sql = "SELECT " +
"age1.* " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION age1 " +
"INNER JOIN " +
"(" + agentIdSubQuery + ") age2 ON age1.AGENT_ID = age2.AGENT_ID " +
"ORDER BY " +
"AGENT_INITIALS";
Error Message:
{"Error occured during execution of SQL query: SELECT age1.* FROM KS_DRIFT.V_AGENT_ALLOCATION age1 INNER JOIN (SELECT max(DISTINCT AGENT_ID FROM KS_DRIFT.V_AGENT_ALLOCATION WHERE LENGTH(AGENT_INITIALS) < 5 AND '2018-08-15' BETWEEN ALLOCATION_START AND ALLOCATION_END AND (UPPER(AGENT_INITIALS) = 'JKKA')) age2 ON age1.AGENT_ID = age2.AGENT_ID ORDER BY AGENT_INITIALS."}
Also giving me an inner exception:
{"ORA-00904: \"AGE2\".\"AGENT_ID\": ugyldig identifikator"}
Debugging error screeenshot
Order it by the newest start date (descending) and select Top 1!
string agentIdSubQuery = "AGENT_ID " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION " +
"WHERE " +
"LENGTH(AGENT_INITIALS) < 5 " +
" AND ROWNUM = 1 " +
" ORDER BY ALLOCATION_START DESC";
EDIT, changed Top 1 to Rownum = 1, for Oracle syntax
The table V_AGENT_ALLOCATION contains various departments per agent along with the dates the agent worked there. You want an agent's last department, which you get with Oracle's KEEP LAST. You haven't given us much information on your table, though. Let's say that the department is referenced by an allocation_id:
select
agent_id,
max(id_allocation) keep (dense_rank last order by allocation_start)
as id_current_allocation
from v_agent_allocation
group by agent_id
order by agent_id;
Your error message shows the final generated SQL:
{"Error occurred during execution of SQL query: SELECT age1.* FROM KS_DRIFT.V_AGENT_ALLOCATION age1 INNER JOIN (SELECT max(DISTINCT AGENT_ID FROM KS_DRIFT.V_AGENT_ALLOCATION WHERE LENGTH(AGENT_INITIALS) < 5 AND '2018-08-15' BETWEEN ALLOCATION_START AND ALLOCATION_END AND (UPPER(AGENT_INITIALS) = 'JKKA')) age2 ON age1.AGENT_ID = age2.AGENT_ID ORDER BY AGENT_INITIALS."}
If you format that so that it's readable, you get:
select age1.*
from ks_drift.v_agent_allocation age1
inner join
( select max(distinct agent_id
from ks_drift.v_agent_allocation
where length(agent_initials) < 5
and '2018-08-15' between allocation_start and allocation_end
and (upper(agent_initials) = 'JKKA') ) age2
on age1.agent_id = age2.agent_id
order by agent_initials
Two syntax issues should jump out:
There is a missing closing bracket after max(distinct agent_id (the distinct is also redundant)
The date literal is missing its date keyword - it should be date '2018-08-15' (or better still, a bind variable).
The brackets around (upper(agent_initials) = 'JKKA') are redundant but perhaps they arise from your generator logic and it's easiest to keep them.
I'm not sure how that relates to your 'newest allocated department' requirement, though. Some sample data (not a screenshot) would help.
If you're looking for the current department, you should compare the allocation dates with the current date.
Your query already has this WHERE clause, so it should work just fine for the example provided. But if you might want to specify that you need only ONE row using the ROWNUM special variable clause (assuming it's Oracle).
SELECT DISTINCT AGENT_ID
FROM KS_DRIFT.V_AGENT_ALLOCATION
WHERE LENGTH(AGENT_INITIALS) < 5
AND ALLOCATION_START < CURRENT_DATE AND CURRENT_DATE < ALLOCATION_END
AND ROWNUM = 1

How to perform UPDATE operation on two tables having two similar fields and one different field?

I have got two tables named "studentBio" and "subjects". Fields of both tables are being given below(with some values): On the form i have got something like this:
AND in checkedlistbox1 i am showing corresponding subjects in the form like A+B+C. Which after retrieving from user would be split on the basis of '+' and be added into subjects table all at once.
Fields of studentBio table are given as follows: WHERE (RollNo, RegYear,program, and faculty combine to make composite primary key):
RollNo RegYear stuName program faculty phoneNuber Address
1 2010 John Intermediate Pre-Engineering 343483834 London
2 2011 Leonard Intermediate Pre-Medical 454545445 NewYork
3 2012 Henry Graduation B.A 565656565 Oslo
Similary fields of subjects table are as follows: WHERE
(RollNo, RegYear,program, and faculty combine to make composite
primary key):
RollNo RegYear program faculty subjectName
1 2010 Intermediate Pre-Engineering A
1 2010 Intermediate Pre-Engineering B
1 2010 Intermediate Pre-Engineering C
2 2011 Intermediate Pre-Medical D
2 2011 Intermediate Pre-Medical E
2 2011 Intermediate Pre-Medical F
and so on. Now lets come to the problem. What i am doing is UPDATING (faculty and program) in both tables and subjectN in subjects table. What i have done so far is that i have updated only studentBio table which is quite easy but i can't figure-out as how could i structure my update query to update subjects table? Can somebody please help me structuring the query?
If I understood well, please try this restructured version of your query:
string update_Personal = "UPDATE studentBio INNER JOIN subjects ON studentBio.RollNo = subjects.RollNo AND studentBio.RegYear = subjects.RegYear AND studentBio.program = subjects.program AND studentBio.faculty = subjects.faculty SET studentBio.program = ProgramU, studentBio.faculty = FacultyU, subjects.subjectName = SubjectNameU WHERE studentBio.RollNo = " + Convert.ToInt32(this.rollNumber7_combo.SelectedItem.ToString()) + " AND studentBio.RegYear = " + Convert.ToInt32(this.comboBox3.SelectedItem.ToString()) + " AND studentBio.program = '" + this.comboBox1.SelectedItem.ToString() + "' AND studentBio.faculty = '" + this.comboBox2.SelectedItem.ToString() + "'";
I've added the following parts to make it update subjects table:
studentBio INNER JOIN subjects ON studentBio.RollNo = subjects.RollNo AND studentBio.RegYear = subjects.RegYear AND studentBio.program = subjects.program AND studentBio.faculty = subjects.faculty - this part joins the subjects table making it's update possible
, subjects.subjectName = SubjectNameU - fragment in the SET block updating subjectName column in subjects table
WHERE studentBio.RollNo = " + Convert.ToInt32(this.rollNumber7_combo.SelectedItem.ToString()) + " AND studentBio.RegYear = " + Convert.ToInt32(this.comboBox3.SelectedItem.ToString()) + " AND studentBio.program = '" + this.comboBox1.SelectedItem.ToString() + "' AND studentBio.faculty = '" + this.comboBox2.SelectedItem.ToString() + "'" - the last part is the WHERE block in which prefix studentBio. was added to each key column to precise to which table the filtering should be applied (because both tables ha the same key column names)
I hope it could help you in some way.

Make it appear in Not-Submitted list

I want to retrieve back Student names and Student ID that don't exist in the Submission table, but exist in the Students table, and bind it into the GridView. For example Class A has 40 students, but only 38 students submitted the project. I want the 2 students who don't submit to appear in the GridView where the Teacher can view it
SELECT *
FROM Students
LEFT JOIN dbo.Submission ON Students.Student_Id = Submission.Student_Id
AND Students.Subject_Id = Submission.Subject_Id
WHERE Students.Subject_Class='" + Session["Subject_Class"].ToString() + "'
AND Students.Subject_Id = '" + Session["Subject_Id"].ToString() + "'
AND Submission.Proj_Sub = '" + Session["Proj_Sub"].ToString() + "'
And Submission.Student_Id IS NULL
When I use the above-mentioned statement, the GridView appears to be empty.
You probably want something like this.
SELECT *
FROM Students
WHERE Students.Subject_Class='" + Session["Subject_Class"].ToString() + "'
AND Students.Subject_Id = '" + Session["Subject_Id"].ToString() + "'
AND NOT EXISTS (SELECT *
FROM Submissions
WHERE Submissions.Student_Id = Students.Student_Id
AND Submissions.Subject_Id = Students.Subject_Id
AND Submissions.Proj_Sub = '" + Session["Proj_Sub"].ToString() + "')
There are a number of approaches you could take, but this seems like the cleanest. Most importantly, though, you should place emphasis on moving away from your currently-SQL-injection prone approach. Please parameterize your queries.

SQL Returning rows with max value in column, within a specific range

I'm populating a DataTable in C# using an OleDbDataAdapter, and I am trying to get a query to work without much success.
The communication to/from the server works fine, as is evidenced by the simple query that returns all the records without any filter:
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, Revision " +
"FROM dbo.PDSIsometricSheets WHERE SchemaName='{0}'", projectNo);
This gives me a list of about 8000 entries, however there is some redundancy.
There are multiple rows with the same LineID, but each one has a separate Revision value. I'm trying to get only the rows with the highest revision for each LineID, from a range of 0 to 5.
Here are a few of the attempts I've tried so far:
var commandText = string.Format("SELECT * FROM
(SELECT max(Revision) as LatestRev
FROM dbo.PDSIsometricSheets)
WHERE Revision < 5" , projectNo);
var commandText = string.Format("SELECT T.IsoShtRevID, T.LineID, T.Filename, T.Revision
FROM dbo.PDSIsometricSheets T
WHERE Revision =
(SELECT MAX(T1.Revision)
FROM dbo.PDSIsometricSheets T1
WHERE T1.IsoShtRevID = T.IsoShtRevID
)", projectNo);
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, MAX(Revision) as LatestRevision
FROM dbo.PDSIsometricSheets WHERE SchemaName='{0}'
GROUP BY LineID, IsoShtRevID, Filename", projectNo);
Here are the questions I've visited so far trying to get this to work:
SQL Select only rows with Max Value on a Column
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
Fetch the row which has the Max value for a column
Select Rows with Maximum Column Value group by Another Column
Everything above either returns the same thing as my original query, or just errors out from bad syntax. SQL is the furthest thing from my forte, and I'm trying to figure out if I'm limited in functionality by using a DataAdapter.
UPDATE:
Here's the latest iteration, using some advice from below:
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, MAX(Revision) as MaxRevision " +
"FROM dbo.PDSIsometricSheets " +
"WHERE SchemaName='{0}' AND Revision <= 5 AND Revision >= 0" +
"GROUP BY IsoShtRevID, LineID, Filename", projectNo);
This filters out the revision to values between 0 and 5, however there are still multiple rows for LineID, each with different Revision numbers. It's like the Max command is being ignored...
Option 3 should work but if it doesn't is because FileName or IsoShtRevID change across Revisions. In that case, you can do this:
SELECT a.IsoShtRevID ,
a.LineID ,
a.Filename ,
a.Revision
FROM dbo.PDSIsometricSheets a
join (select max(Revision) as Revision, LineID
from dbo.PDSIsometricSheets where SchemaName ='{0}' ) x
join a on a.Revision = x.Revision and a.LineID=x.LineID
WHERE a.SchemaName = '{0}'
Finally got it thanks to the comments, reading more SQL, and viewing my commandstring diligently at runtime for typos.
var commandText = string.Format("SELECT T1.IsoShtRevID, T1.LineID, T1.FileName, T1.Revision " +
"FROM dbo.PDSIsometricSheets T1 " +
"INNER JOIN (" +
"SELECT LineID, MAX(Revision) as MaxRevision " +
"FROM dbo.PDSIsometricSheets " +
"WHERE SchemaName='{0}' AND Revision <= 5 AND Revision >= 0" +
"GROUP BY LineID" +
") T2 " +
"ON T1.LineID = T2.LineID AND T1.Revision = T2.MaxRevision ", projectNo);

Categories

Resources