I have the following SQL query in MS Access / VB.net:
Dim sql = "SELECT [Product Name], [Customer Name], [Group Associated], [Customer Address], [Product Price], [Current Stock], [Date Ordered], [Volume Purchased] FROM (torder INNER JOIN tproducts ON tproducts.Product_ID = torder.Product_ID) INNER JOIN tcustomer ON torder.Customer_ID = tcustomer.Customer_ID WHERE torder.[Date Ordered] Between #" & StartOfTimePeriod & "# And #" & Today & "#;"
conn.Open()
Dim dataAdapter As New OleDbDataAdapter(sql, conn)
Dim ds As New DataSet()
dataAdapter.Fill(ds, "torder")
conn.Close()
DataGridView.DataSource = ds
DataGridView.DataMember = "torder"
When the query is run it doesn't display the full dataset that it should. Instead, the results are almost random. What could be wrong?
http://prntscr.com/5eh4ge
http://prntscr.com/5eh4ai
Do not stringize your date and time values. Use a parameterized query.
Dim sql = "SELECT [Product Name], [Customer Name], [Group Associated], " & _
"[Customer Address], [Product Price], [Current Stock], [Date Ordered], " & _
"[Volume Purchased] " & _
"FROM (torder INNER JOIN tproducts ON tproducts.Product_ID = torder.Product_ID) " & _
"INNER JOIN tcustomer ON torder.Customer_ID = tcustomer.Customer_ID " & _
"WHERE torder.[Date Ordered] >= ? And torder.[Date Ordered] <= ?"
Dim dataAdapter As New OleDbDataAdapter(sql, conn)
Dim p1 = new OleDbParameter() With
{
.ParameterName = "#p1",
.OleDbType = OleDbType.Date,
.Value = StartOfTimePeriod
}
Dim p1 = new OleDbParameter() With
{
.ParameterName = "#p2",
.OleDbType = OleDbType.Date,
.Value = DateTime.Today.AddMinutes(1339)
}
dataAdapter.SelectCommand.Parameters.Add(p1)
dataAdapter.SelectCommand.Parameters.Add(p2)
....
In this way the correct interpretation of your DateTime values is a job passed to the database engine together with actual DateTime values (I assume that StartOfTimePeriod is a DateTime variable).
Instead, if you convert these values to string, the conversion follow the rules of your locale environment that could produce a string not compatible with the expected format of your database engine (for example the inversion of position of months and days values)
Related
I have a table with date column a query for the same table and a report, on my form I have a button which loads the report using vba code which is below, I have two text fields to filter date on the report, my issue is with the date it is not being filtered. my code is below
Public Function makeMWO_RPT(Optional excelMode As Boolean = False)
Dim ctlArr(3) As String
ctlArr(0) = "Combo79"
ctlArr(1) = "Combo82"
ctlArr(2) = "WOPRCO"
ctlArr(3) = "Combo165"
Dim fldArr(3) As String
fldArr(0) = "[Group]"
fldArr(1) = "[User status]"
fldArr(2) = "[Priority]"
fldArr(3) = "iif([orders].[User status] In (""Closed"",""Open""),""YES"",""NO"")"
'for date -- for date -- for date -- for date -- for date
Dim qDef, sqlStr, frm As Form
Set frm = Forms("Statusfrm")
Set qDef = CurrentDb.QueryDefs("OrderNewQry")
sqlStr = "SELECT orders.[Group], orders.Order, orders.Description,orders.Post_Form, orders.Attachment, orders.Video_link, orders.[Estimated costs], orders.[Total], orders.Location, orders.[System status], orders.Priority, orders.date, orders.[User status], " & _
"orders.Equipment, orders.Diff, orders.Remarks,[orders].[User status] In (""Closed *"",""Open *"") AS Completed
"FROM orders"
Dim filtrStr As String
If Not IsNull(frm("Text489")) Then
filtrStr = "[date] >= #" & frm("Text489") & "#"
End If
If Not IsNull(frm("Text491")) Then
filtrStr = filtrStr & " AND [date] <= #" & frm("Text491") & "#"
End If
If filtrStr <> "" Then
sqlStr = sqlStr & " WHERE " & filtrStr
End If
qDef.SQL = sqlStr
'for date -- for date -- for date -- for date -- for date
Dim baseSQL, qName, rName
baseSQL = "SELECT orders.[Group], orders.Order, orders.Description,orders.Post_Form, orders.Attachment, orders.Video_link, orders.[Estimated costs], orders.[Total], orders.Location, orders.[System status], orders.Priority, orders.date, orders.[User status], " & _
"orders.Equipment, orders.Diff, orders.Remarks,[orders].[User status] In (""Closed *"",""Open *"") AS Completed
"FROM orders"
qName = "OrderNewQry"
rName = "FUllOpenOrdersRpt"
makeGenericRPT ctlArr, fldArr, baseSQL, qName, rName, excelMode
End Function
I have 5 datatables which having each 3 columns (ID, Brand, Quanitiy) to derive the opening, purchase, sales and closing stock. The First 3 datatables should be merged and sum up to derive the opening stock as on given period. 4 th datatable is for Purchases done for the given period. The last one Datatable is for Sales done for the given period.
Here is my question:
How can i merge the 3 datatables and using the first 2 columns and summing the values?
How can i use the tables in crystal reports?
My code is :
Dim con As New ClassConnection
If con.Conn.State = ConnectionState.Closed Then con.Conn.Open()
'To get Opening Stock in Full Quantity
Dim sql As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblOp_Details.Net_Qty) AS Quantity FROM tblOp_Stock INNER JOIN (tblBrand INNER JOIN" & _
" tblOp_Details ON tblBrand.B_ID = tblOp_Details.B_ID) ON tblOp_Stock.Stk_ID = tblOp_Details.Stk_ID" & _
" WHERE tblOp_Stock.God_ID = #GID GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'To get Purchases < start date and adding to the opening stock
Dim sql1 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblPur_Details.Net_Qty) AS Quantity FROM tblPurchase INNER JOIN (tblBrand INNER JOIN" & _
" tblPur_Details ON tblBrand.B_ID = tblPur_Details.B_ID) ON tblPurchase.Pur_ID = tblPur_Details.Pur_ID" & _
" WHERE tblPurchase.God_ID = #GID AND tblPurchase.Rec_Date < #SDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'To get Sales < Start date and subtracting to the above
Dim sql2 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum (tblSales_Details.Net_Qty) AS Quantity FROM tblSales INNER JOIN (tblBrand INNER JOIN" & _
" tblSales_Details ON tblBrand.B_ID = tblSales_Details.B_ID) ON tblSales.Sale_ID = tblSales_Details.Sale_ID" & _
" WHERE tblSales.God_ID = #GID AND tblSales.Sale_Date < #SDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above 3 condition is for deriving opening stock as on given date
'To get Purchases >= Start Date and <= Start Date
Dim sql3 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum(tblPur_Details.Net_Qty) AS Quantity FROM tblBrand INNER JOIN (tblPurchase INNER JOIN" & _
" tblPur_Details ON tblPurchase.Pur_ID = tblPur_Details.Pur_ID) ON tblBrand.B_ID = tblPur_Details.B_ID" & _
" WHERE tblPurchase.God_ID = #GID And tblPurchase.Rec_Date >= #SDate And tblPurchase.Rec_Date" & _
" <= #EDate GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above condition is for deriving Purchases as on given date
'To get Sales >= Start Date and <= Start Date
Dim sql4 As String = "SELECT tblBrand.B_ID AS ID, tblBrand.B_Name AS Brand," & _
" Sum(tblSales_Details.Net_Qty) AS Quantity FROM tblBrand INNER JOIN (tblSales INNER JOIN" & _
" tblSales_Details ON tblSales.Sale_ID = tblSales_Details.Sale_ID) ON tblBrand.B_ID = tblSales_Details.B_ID" & _
" WHERE tblSales.God_ID = #GID And tblSales.Sale_Date >= #SDate And tblSales.Sale_Date <= #EDate" & _
" And tblSales_Details.S_Active = #SAct GROUP BY tblBrand.B_ID, tblBrand.B_Name"
'The above condition is for deriving Sales as on given date
Dim da As New OleDb.OleDbDataAdapter(sql, con.Conn)
Dim da1 As New OleDb.OleDbDataAdapter(sql1, con.Conn)
Dim da2 As New OleDb.OleDbDataAdapter(sql2, con.Conn)
Dim da3 As New OleDb.OleDbDataAdapter(sql3, con.Conn)
Dim da4 As New OleDb.OleDbDataAdapter(sql4, con.Conn)
da.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da1.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da1.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da2.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da2.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da3.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da3.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da3.SelectCommand.Parameters.AddWithValue("#EDate", Me.dtpEnd.ToString)
da4.SelectCommand.Parameters.AddWithValue("#GID", Me.stBar_G_ID.Text)
da4.SelectCommand.Parameters.AddWithValue("#SDate", Me.dtpStart.ToString)
da4.SelectCommand.Parameters.AddWithValue("#EDate", Me.dtpEnd.ToString)
da4.SelectCommand.Parameters.AddWithValue("#SAct", "Yes")
Dim dt As New DataTable
Dim dt1 As New DataTable
Dim dt2 As New DataTable
Dim dt3 As New DataTable
Dim dt4 As New DataTable
Ignoring the fact that such operations should be done in the database instead of memory, you can use Linq-To-DataSet which is a subset of Linq-To-Objects.
If you want to concatenate the three tables, group by ID + Brand to get the sum of Quantity:
Dim allRows = dt1.AsEnumerable().Concat(dt2.AsEnumerable()).Concat(dt3.AsEnumerable())
Dim query = From row In allRows
Let GroupColumns = New With {
.Id = row.Field(Of Int32)("Id"),
.Brand = row.Field(Of String)("Brand")
}
Group row By GroupColumns Into Group
Select New With {
.Id = GroupColumns.Id,
.Brand = GroupColumns.Brand,
.SumQuantity = Group.Sum(Function(row) row.Field(Of Int32)("Quantity"))
}
Fill the merged table from the query:
Dim dt As DataTable = dt1.Clone() ' empty, same columns
For Each x In query
Dim row = dt.Rows.Add()
row.SetField("Id", x.Id)
row.SetField("Brand", x.Brand)
row.SetField("Quantity", x.SumQuantity)
Next
This is the code where I am getting exception message. However this code worked perfect in sql server 2005 but generating error in access.
This code working fine in sql server project but in access its generating exception as I mentioned..
Public Function CalculateFeeReciept(ByVal monthid As Integer) As DataTable
Dim cmd1 As New OleDbCommand("Select * from mstFeeHead", sqlcon)
Dim dtmstFeeHead As New DataTable 'dtmstFeeHead contains all the fee heads id's
Dim adp1 As New OleDbDataAdapter(cmd1)
adp1.Fill(dtmstFeeHead)
cmd1.Dispose()
Dim selectedmonth As Integer
Dim feeheadid As Integer
Dim arr(25) As Integer 'arr contains Fee head id's that should be paid in the selected month
If monthid = 13 Then
monthid = 1
ElseIf monthid = 14 Then
monthid = 2
ElseIf monthid = 15 Then
monthid = 3
End If
selectedmonth = monthid + 3
Dim m As Integer = 0
For j As Integer = 0 To dtmstFeeHead.Rows.Count - 1
feeheadid = Convert.ToInt32(dtmstFeeHead.Rows(j)(0))
If dtmstFeeHead.Rows(j)(selectedmonth) Then
arr(m) = feeheadid
m = m + 1
End If
Next
Dim cmd2 As New OleDbCommand("SELECT txnStudentFeeHead.FeeHeadID, mstFeeHead.FeeHeadName, mstFeePlan.Amount " & _
"FROM " & _
"txnStudentFeeHead " & _
"INNER JOIN " & _
"mstFeeHead " & _
"ON " & _
"txnStudentFeeHead.FeeHeadID = mstFeeHead.FeeHeadID " & _
"INNER JOIN " & _
"mstFeePlan " & _
"ON " & _
"mstFeeHead.FeeHeadID = mstFeePlan.FeeHeadID " & _
"WHERE " & _
"txnStudentFeeHead.StudentID = #StudentID) " & _
"AND " & _
"(mstFeePlan.SessionID = #SessionID) " & _
"AND " & _
"(mstFeePlan.ClassID = #ClassID) ", sqlcon)
cmd2.CommandType = CommandType.Text
cmd2.Parameters.Add("#StudentID", OleDbType.Integer).Value = StudentID()
cmd2.Parameters.Add("#ClassID", OleDbType.Integer).Value = Convert.ToInt32(cmbClass.SelectedValue)
cmd2.Parameters.Add("#SessionID", OleDbType.Integer).Value = Convert.ToInt32(cmbSession.SelectedValue)
Dim dt As New DataTable 'dt contains all the fee head id's that are alloted to the students
Dim adp As New OleDbDataAdapter(cmd2)
adp.Fill(dt)
cmd2.Dispose()
Dim dt2 As New DataTable 'dt2 contains all the fee head id's that are alloted to the student and that should be paid in that particular month
' dt2 contains the filtrate of dt and arr
dt2 = dt.Clone()
For i As Integer = 0 To arr.Length - 1
For j As Integer = 0 To dt.Rows.Count - 1
Dim dtrow As DataRow = dt2.NewRow()
If arr(i) = dt.Rows(j)(0) Then
dtrow(0) = arr(i)
dtrow(1) = dt.Rows(j)(1)
dtrow(2) = dt.Rows(j)(2)
dt2.Rows.Add(dtrow)
End If
Next
Next
cmd2 = New OleDbCommand("Select Sum(TotalFees) as TotalFees, Sum(LateFees) as TotalLateFees, Sum(OldBalance) as TotalOldBalance, Sum(Discount) as TotalDiscount, Sum(Scholarship) as TotalScholarship, Sum(Concession) as TotalConcession, Sum(AmountReceived) as TotalAmountReceived from txnFeePayment where SessionID=#SessionID and StudentID=#studentid and MonthID=#monthid Group by StudentId,MonthID", sqlcon)
cmd2.CommandType = CommandType.Text
cmd2.Parameters.Add("#studentid", OleDbType.Integer).Value = StudentID()
cmd2.Parameters.Add("#SessionID", OleDbType.Integer).Value = cmbSession.SelectedValue
cmd2.Parameters.Add("#monthid", OleDbType.Integer).Value = monthid
Dim dtStudentReciept As New DataTable 'dt contains all the fee head id's that are alloted to the students
adp = New OleDbDataAdapter(cmd2)
adp.Fill(dtStudentReciept)
cmd2.Dispose()
Dim dtrow1 As DataRow = dt2.NewRow()
If (dtStudentReciept.Rows.Count > 0) Then
dtrow1(0) = 0
dtrow1(1) = "Total Late Fees"
dtrow1(2) = Convert.ToInt32(dtStudentReciept.Rows(0)(1))
dt2.Rows.Add(dtrow1)
dtrow1 = dt2.NewRow()
dtrow1(0) = 0
dtrow1(1) = "Total Discount"
dtrow1(2) = Convert.ToInt32(dtStudentReciept.Rows(0)(3)) * -1
dt2.Rows.Add(dtrow1)
dtrow1 = dt2.NewRow()
dtrow1(0) = 0
dtrow1(1) = "Total Scholarship"
dtrow1(2) = Convert.ToInt32(dtStudentReciept.Rows(0)(4)) * -1
dt2.Rows.Add(dtrow1)
dtrow1 = dt2.NewRow()
dtrow1(0) = 0
dtrow1(1) = "Total Concession"
dtrow1(2) = Convert.ToInt32(dtStudentReciept.Rows(0)(5)) * -1
dt2.Rows.Add(dtrow1)
dtrow1 = dt2.NewRow()
dtrow1(0) = 0
dtrow1(1) = "Total Amount Received"
dtrow1(2) = Convert.ToInt32(dtStudentReciept.Rows(0)(6)) * -1
dt2.Rows.Add(dtrow1)
Dim totalamount As Integer = 0
For k As Integer = 0 To dt2.Rows.Count - 1
totalamount = totalamount + dt2.Rows(k)(2)
Next
'dtrow1 = dt2.NewRow()
'dtrow1(0) = totalamount
'dtrow1(1) = "Current Month Fee"
'dtrow1(2) = totalamount
'dt2.Rows.Add(dtrow1)
Else
Dim totalamount As Integer = 0
For k As Integer = 0 To dt2.Rows.Count - 1
totalamount = totalamount + dt2.Rows(k)(2)
Next
'dtrow1 = dt2.NewRow()
'dtrow1(0) = totalamount
'dtrow1(1) = "Current Month Fee"
'dtrow1(2) = totalamount
'dt2.Rows.Add(dtrow1)
End If
dgvDisplay.DataSource = dt2
For i As Integer = 0 To dgvDisplay.Columns.Count - 1
dgvDisplay.Columns.Item(i).SortMode = DataGridViewColumnSortMode.NotSortable
dgvDisplay.Columns(2).Width = 65
dgvDisplay.Columns(1).Width = 132
Next
dgvDisplay.Columns.Item(0).Visible = False
'txtTotalFees.Text = dt2.Rows(dt2.Rows.Count - 1)(0)
Return dt2
End Function
There are a couple of things wrong with your query.
You havent left any spaces once a line in code is finished and whole query may look like they are separate lines but it is a one long string without any spaces.
I have added spaces in the following piece of code at the end of each line.
("SELECT [txnStudentFeeHead].[FeeHeadID],[mstFeeHead].[FeeHeadName]," & _
"[mstFeePlan].[Amount] " & _
"FROM " & _
"[txnStudentFeeHead] " & _
"INNER JOIN " & _
"[mstFeeHead] " & _
You have put your variables in sqaure brackets [] , which means SQL Server will treat them as SQL Server Object(table name, Column Name) names and not as Variables. Remove the Square brackets.
"WHERE " & _
"([txnStudentFeeHead].[StudentID] = #StudentID) " & _
"AND" & _
"([mstFeePlan].[SessionID] = #SessionID) " & _
"AND" & _
"([mstFeePlan].[ClassID] = #ClassID) ", sqlcon)
Solved it myself by long time of effort and headache
Dim cmd2 As New OleDbCommand("SELECT txnStudentFeeHead.FeeHeadID, mstFeeHead.FeeHeadName, mstFeePlan.Amount, txnStudentFeeHead.StudentID, mstFeePlan.ClassID, mstFeePlan.SessionID FROM (txnStudentFeeHead INNER JOIN mstFeeHead ON txnStudentFeeHead.FeeHeadID = mstFeeHead.FeeHeadID) INNER JOIN mstFeePlan ON mstFeeHead.FeeHeadID = mstFeePlan.FeeHeadID WHERE (((txnStudentFeeHead.StudentID)=#StudentID) AND ((mstFeePlan.ClassID)=#ClassID) AND ((mstFeePlan.SessionID)=#SessionID))", sqlcon)
cmd2.CommandType = CommandType.Text
cmd2.Parameters.Add("#StudentID", OleDbType.Integer).Value = StudentID()
cmd2.Parameters.Add("#ClassID", OleDbType.Integer).Value = Convert.ToInt32(cmbClass.SelectedValue)
cmd2.Parameters.Add("#SessionID", OleDbType.Integer).Value = Convert.ToInt32(cmbSession.SelectedValue)
Dim dt As New DataTable 'dt contains all the fee head id's that are alloted to the students
Dim adp As New OleDbDataAdapter(cmd2)
adp.Fill(dt)
cmd2.Dispose()
Problem: I have populated a datatable using a query on a sql server database. The query is:
Select ID, startDate, codeID, Param,
(select top 1 startDate from myTable
where ID='" & ID & "' and Param = mt.param and codeID = 82 and startDate >= '" & startDate & "' and startDate >=mt.startDate
ORDER BY startDate)endTime,
from myTable mt where ID = '" & ID & "'
AND (startDate between '" & startDate & "' AND '" & endDate & "' AND (codeID = 81))
I want a new column called duration that will be the difference between endTime and startDate in milliseconds. I can't just add another subquery to the above query since the endTime column didn't exist until the subquery was ran.
So, is there a way to maybe run the first query to populate the datatable, then run a query like:
Select DateDiff(ms,endTime,startDate)
On its own and add its results to a new column in my datatable?
You can always nest that in another query:
select *, datediff(ms, startDate, endTime)
from (
<your existing query here>
) t
And while I'm here, it seems you need a lesson in parameterized queries:
Dim result As New DataTable
Dim Sql As String = _
"SELECT *, datediff(ms, startDate, endTime) FROM (" & _
"SELECT ID, startDate, codeID, Param, " & _
"(select top 1 startDate from myTable " & _
"where ID= #ID and Param = mt.param and codeID = 82 and startDate >= #startDate and startDate >=mt.startDate " & _
"ORDER BY startDate) endTime " & _
" FROM myTable mt " & _
" WHERE ID = #ID AND startDate between #startDate AND #endDate AND codeID = 81" & _
") t"
Using cn As New SqlConnection("connection string"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("#ID", SqlDbType.VarChar, 10).Value = ID
cmd.Parameters.Add("#startDate", SqlDbType.DateTime).Value = Convert.ToDateTime(startDate)
cmd.Parameters.Add("#endDate", SqlDbType.DateTime).Value = Convert.ToDateTime(endDate)
cn.Open()
Using rdr = cmd.ExecuteReader()
result.Load(rdr)
rdr.Close()
End Using
End Using
Does anyone have a example of how to join 3 tables, I have the following statement but I'm getting a missing a (syntax error "operator error")
da = New OleDbDataAdapter("SELECT [S].[Scheduled Vege], [V].[Description],
[DS].[Task], [DS].[Task Date], [DS].[Completed] FROM [Scheduled] AS S
INNER JOIN [Date Schedules] AS DS ON [S].[SchedID] = [DS].[SchedID]
INNER JOIN [Vegetables Descriptions] AS V ON [V].[Task] = [DS].[Task]
WHERE [DS].[TaskNumber] >= " & aFromDate & " AND [DS].[TaskNumber] <= " & aToDate & "
AND [DS].[Completed] = '" & aCompleted & "' ", conn)
thanks
Found the problem, because it's an access database the fisrt from statement and INNER JOIN needs to be in brackets as shown below.
da = New OleDbDataAdapter("SELECT [S].[Scheduled Vege], [V].[Description],
[DS].[Task], [DS].[Task Date], [DS].[Completed] FROM ([Scheduled] AS S
INNER JOIN [Date Schedules] AS DS ON [S].[SchedID] = [DS].[SchedID])
INNER JOIN [Vegetables Descriptions] AS V ON [V].[Task] = [DS].[Task]
WHERE [DS].[TaskNumber] >= " & aFromDate & " AND [DS].[TaskNumber] <= " & aToDate & "
AND [DS].[Completed] = '" & aCompleted & "' ", conn)
Does your query execute if you remove your WHERE clause? The only thing that immediately jumped out at me was your dates are not necessarily going to be in a format that the OleDB provider is going to like.
My guess is that you need to encapsulate your dates like '1-Jan-2009' or something similar.
Your join looks okay, but I think your problem might be where you're comparing 'TaskNumber' to 'aFromDate'; numbers and dates are different types in SQL, and should cause a problem trying to compare them like this.