Please I am typing from my phone as I am not with the laptop, don't decrease my reputation.
I have a column in my SQL server database named Total_Amount, I want to get the Sum(Total_Amount) for a specific day for a specific Cashier. I am able to get for specific cashier only but if I want to get using the WHERE clause for both cashier AND date, it returns nothing. The command works well in SQL server Management Studio but from the VB. nET, it does not.
The below is my code.
Dim conn As New SqlConnection("data.
source=PRECIOUSMUM\MSSQLSERVER_1; initial.
catalog=inventory; user id=mantics;
password=emudeji;")
Try
'Dim Total_Amountss As Double
conn.Open()
Dim cmd = New SqlCommand
With cmd
.Connection = conn
.CommandText = "SELECT SUM(Total_Amount)
AS Total_Amount FROM tblOrder WHERE.
(cashier=#cashier) AND (Order_date=#Order_date)"
.Parameters.AddWithValue("#cashier",
lbl_Cashier_Name.Text)
.Parameters.AddWithValue("#Order_date", Date.Today.ToString)
'.Parameters.AddWithValue("#enddate", dtpicker.Value.Date)
End With
Dim dr As SqlDataReader
dr = cmd.ExecuteReader
dr.Read()
If IsDBNull(dr("Total_Amount")) Then
lbl_cashier_Totalsales.Text = "N0.00"
Else
Dim str As Double
str = dr.Item("Total_Amount")
lbl_cashier_Totalsales.Text = FormatCurrency(dr.Item("Total_Amount"))
End If
The first thing that it is clearly wrong is the fact that you use a string to query a Date column. This is never correct because the string is something that you use to display the date to your end users. It is not how the database (or .NET) stores the date value. So, a Date column is not queried using a string but passing directly the C# DateTime value in the Add method and specifying the DataType of the parameter.
A second possible error is caused by the fact that if you have also stored the Time part then passing a Date like Today will never match any row but only the ones that have 00:00:00 as their time value.
You need to query for >= midnight of the starting date and < of the following day.
This considerations will give a query like this:
With cmd
.Connection = conn
.CommandText = "SELECT SUM(Total_Amount) AS Total_Amount
FROM tblOrder
WHERE (cashier=#cashier) AND
(Order_date >= #StartDate AND
Order_date < #EndDate)"
.Parameters.Add("#cashier", SqlDbType.NVarChar).Value = lbl_Cashier_Name.Text
.Parameters.Add("#StartDate", SqlDbType.DateTime).Value = Date.Today
.Parameters.Add("#EndDate", SqlDbType.DateTime).Value = Date.Today.AddDays(1)
End With
Related
I'm doing a windows form using Visual Basic.NET, SQL Server 2016, Visual Studio 2017.
I have been trying to fix this problem and already tried set dateformat mdy in SQL Server Management Studio query, but the dates on the table I have are still in this format: 2022-07-17 00:00:00.000. Does this have anything to do with this error when trying to insert something while running the project?
Everyone says stuff along the line "datetime doesn't work with yy/mm/dd or dd/mm/yy, use mm/dd/yy instead". But nobody says how you actually change/fix it in the database or Visual Studio.
I never found this error while using MySQL when I was studying and doing stuff on other languages, so this datetime thing is really getting desperate. Any insight on how to actually fix this error is greatly appreciated.
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim someid As Integer = TextCode.Text
Dim descri As String = TextDescription.Text
Dim somedate As DateTime = DateTimePickerinsert.Text
Dim value As String = TextValue.Text
Dim stock As String = TextStock.Text
Dim warehouse As String = ComboWarehouse.Text
con.Open()
Dim command As New SqlCommand("Insert into Item values('" & someid & "','" & descri & "','" & somedate & "','" & value & "','" & stock & "','" & warehouse & "')", con)
command.ExecuteNonQuery()
con.Close()
MessageBox.Show("Inserted succesfully")
LoadDataInGrid()
End Sub
I get
System.Data.SqlClient.SqlException: 'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.' error on the line: command.ExecuteNonQuery()
You should use proper parameterization, keeping your dates as actual DateTime values, rather than strings, likewise for numbers. Otherwise you will get SQL injection problems, this is not just a security issue but also about correctness.
The parameter values should be cast to the correct type before you send them, and the parameter objects should be declared with the correct SqlDbType and precision/length also.
You should also create and dispose your connection object, rather than keeping a global connection open, which is wasteful. Automatic connection pooling will ensure efficient usage of available connections.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim query As String = "
INSERT INTO Item (someid, descri, somedate, value, stock, warehouse)
VALUES (#id, #description, #date, #value, #stock, #warehouse)
"
Dim someid As Integer = Integer.Parse(TextCode.Text)
Dim somedate As DateTime = DateTimePickerinsert.Value
Dim value As Decimal = Decimal.Parse(TextValue.Text)
Dim stock As Integer = Integer.Parse(TextStock.Text)
Using con As new SqlConnection("YourConnectionString"),
command As New SqlCommand(query, con)
command.Parameters.Add("#id", SqlDbType.Int).Value = someid
command.Parameters.Add("#description", SqlDbType.VarChar, 100).Value = If(TextDescription.Text, DBNull.Value)
command.Parameters.Add("#date", SqlDbType.DateTime).Value = somedate
command.Parameters.Add("#value", SqlDbType.Decimal).Value = value
command.Parameters.Add("#stock", SqlDbType.Int).Value = stock
command.Parameters.Add("#warehouse", SqlDbType.VarChar, 50).Value = If(ComboWarehouse.Text, DBNull.Value)
con.Open()
command.ExecuteNonQuery()
End Using
MessageBox.Show("Inserted succesfully")
LoadDataInGrid()
End Sub
As far as viewing the results in SSMS: datetime values don't have an inherent format. SSMS will have a default way of displaying them, but you can show them any way you like by converting them using CONVERT, or in VB using ToString
You are seriously entertaining SQL Injection using that Code.
You don't directly insert data to SQL database from your Windows Controls.
Use SQL Connection Parameters to house the values.
That way, any text in the incoming data will not be evaluated as a SQL Script but a text literal.
Hackers could assign SQL Script to your TextDescription.Text
like "Exec 'Delete From XXX '"
and it will be executed.
Dim descri As String = TextDescription.Text
Use SQL Connection Parameters to house the values.
You may run into many issues while using strings as dates. If you are connecting to a stored procedure or just executing SQL via SqlClient or ODBC, one way to fix this error is to use Cast in your SQL string to convert the date string to something that the server will understand. ex:
Insert Into MyTable (MyID, MyDate) Values (#MyID, Cast(#MyDate as datetime));
or,
Insert Into MyTable (MyID, MyDate) Values (123, Cast('2022-03-14 14:12:00' as datetime));
It will be more forgiving on different formats that you might use.
I am reading a table from an access database in vb.net. I would like to know how many records are from a certain year. If the year does not exist in the array I like to add it and set the count to 1. When the year already exists in the array I want to increase the count to 2.
For example DOCUMENT1.2019 creates the year 2019 in the array with count 1, then DOCUMENT2.2019 sets the count to 2 for 2019, then DOCUMENT1.2018 creates the year 2018 and sets the count to 1.
and so on.
So I dont know how large the array will be when I start.
Dim sSQL As String
Dim sGetString As String
Dim sPartString As String
sSQL = "SELECT [Document Name] FROM Archief ORDER BY Id DESC"
Dim cmd As New OleDb.OleDbCommand(sSQL, con)
Dim read As OleDb.OleDbDataReader = cmd.ExecuteReader()
If read.HasRows Then
While read.Read()
sGetString = read.Item("Document Name").ToString()
sPartString = Mid(sGetString, Len(sGetString) - 11, 4) 'retrieve the year like 2019
End While
End If
The endstate will be an overview of the years and the amount of documents from that year.
h
A connection needs to remain open while a reader is active. You don't want to do a lot of processing while the connection is open.
Commands and DataReaders need to be disposed. Using `Using...End Using blocks takes care of this even if there is an error. Declare and dispose connections in the method where they are used.
Let the database do the work. Access offers some string manipulation functions that you can use in queries. You can also use Count with Group By to get the results you desire.
Private Sub GetYearCountData()
Dim sSQL = "SELECT Right([Document Name],4) As [Year], Count([Year]) FROM Archief Group By Right([Document Name],4) Order By Right([Document Name],4) ;"
Dim dt As New DataTable
Using cmd As New OleDbCommand(sSQL, New OleDbConnection(ConStr))
cmd.Connection.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
I am converting my Access query to SQL view. One of the Access query has where condition where a user can input values
where table1.id=[Enter the ID of the user]
Is there a way to convert a query like this to T-SQL. It is important for me to leave the prompt as it is.
Well, first, there is little reason to convert to a pass-though query.
However, SQL Server cannot prompt you in access (or say a web site that uses SQL Server). So the GUI part must be created by YOUR web site, or say access client in this case.
It is usually best to build some prompt form with a button, since those automatic prompts that Access creates are VERY poor from a UI point of view.
As noted, it is VERY likely that you can just continue to use the access query.
However, if you need a pt query, then you use access code to ask/get the prompt value, and then add that to your query.
This will work:
Dim strSQL As String
Dim invoiceNum As String
strSQL = "select * from tblInvoices where invoiceNumber = "
invoiceNum = InputBox("enter Invoice Number")
If invoiceNum = "" Then Exit Sub
strSQL = strSQL & invoicenumber
With CurrentDb.QueryDefs("qryPassR")
.SQL = strSQL
End With
' now, docmd.OpenReport, or openform or
' whatever it is you wanted to do with the sql
However, as noted, for reports etc., I would build a nice form that allows the user to enter a value. The query prompts are pure torture to your users, and they are not user friendly at all.
Also, the above assumes that you going to open some report, or some such. If you need the data returned in a reocrdset, the use this:
Dim strSQL As String
Dim invoiceNum As String
dim rst As DAO.RecordSet
strSQL = "select * from tblInvoices where invoiceNumber = "
invoiceNum = InputBox("enter Invoice Number")
If invoiceNum = "" Then Exit Sub
strSQL = strSQL & invoicenumber
With CurrentDb.QueryDefs("qryPassR")
.SQL = strSQL
Set rst = .OpenRecordset
End With
And last but not least, as others suggested here, you should consider a stored procedure with parameters, as the above is subject to SQL injection.
I'm utilizing VB.Net to try and write to a database I created (the machine that needs to be writing to the database is the owner of the database, so there should be no permission issues). I'm getting no errors on when my subs for writing to the database are run, but no new records are created in my database. I'm successfully connected to the database, as my subs for returning records work perfectly.
The Sub for writing to the database:
Public Sub LogThisCard(a As Object)
Dim con As New OleDb.OleDbConnection
Dim da As New OleDb.OleDbDataAdapter
Dim sql As New OleDb.OleDbCommand
Dim inMachine As String = "Yes"
con.ConnectionString = Connection()
con.Open()
Try
sql.Connection = con
sql.CommandText = "INSERT INTO LogTable (MSA, Foo, Bar, Jack, Rabbit, Date_/_Time, Foxtrot) VALUES (#MSA, #Foo, #Bar, #Jack, #Rabbit, #DT, #Foxtrot)"
sql.Parameters.AddWithValue("MSA", a.MSA)
sql.Parameters.AddWithValue("Foo", a.Foo)
sql.Parameters.AddWithValue("Bar", a.Bar)
sql.Parameters.AddWithValue("Jack", a.Jack)
sql.Parameters.AddWithValue("Rabbit", a.Rabbit)
sql.Parameters.AddWithValue("DT", DateTime.Now())
sql.Parameters.AddWithValue("Foxtrot", a.FoxTrot)
da.InsertCommand = sql
da.InsertCommand.ExecuteNonQuery()
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
con.Close()
End Sub
The Database Design is as follows:
ID: AutoNumber (Primary Key)
MSA: Number
Foo: Number
Bar: Short Text
Jack: Short Text
Rabbit: Short Text
Date / Time:Date/Time
Foxtrot: Short Text
It could be an issue with Access and your DateTime Parameter. If DateTime allows null values, change your insert to do all except DateTime. If the Insert works then you know the issue.
I am not sure why access has issue with addwithvalue, but I see it often. I have found it better to declare a variable of parameter and set properties then add the param when it comes to date times.
Example:
Dim cmd As OleDb.OleDbCommand
Dim param As New OleDb.OleDbParameter
param.Direction = ParameterDirection.Input
param.DbType = DbType.Date
param.Value = Date.Now
cmd.Parameters.Add(param)
I am trying to retrieve Two Columns; App_ID & App_Slot from a table su_Appointments from an sql server database using vb, and I have two conditions the Date and Time; App_Date & App_Time for the query, now when I run the query it throws an error saying : Incorrect syntax near '2014'. The query is as follows
I am going to store App_ID into the variable AP_ID
CODE
Using Query As New SqlCommand("Select App_ID From su_Appointments Where (App_Date = ' and App_Time = ' )" & DT & TM, sqlcon)
sqlcon.Open()
Dim dr As SqlDataReader = Query.ExecuteReader()
While dr.Read()
AP_ID = dr(0)
End While
End Using
sqlcon.Close()
Well, your syntax is effectively wrong
A SELECT statement requires
SELECT <fieldA>, <FieldB>, ....
FROM <Table>
WHERE <FieldX> = <Condition1> AND <FieldZ> = <Condition2>
But, a part from this basic error, you need to start using a parameterized query approach
Using sqlcon = new SqlConnection(.....connectionstring...)
Dim cmdText = "Select App_ID From su_Appointments Where App_Date =#dt and App_Time = #tm"
Using Query = New SqlCommand(cmdText, sqlcon)
sqlcon.Open()
Query.Parameters.AddWithValue("#dt", DT)
Query.Parameters.AddWithValue("#tm", TM)
Using dr =Query.ExecuteReader()
While dr.Read()
AP_ID = dr(0)
End While
End Using
End Using
End Using
With a parameterized query, you get many benefits. There is no possibility of Sql Injection Attacks, the text of your command is more clear and understandable, the parameters are treated for correct quoting by the code itself so you don't need to check for single quotes inside your strings, or format correctly dates and decimal numbers.
Eventually, you could encounter a different problem. If your columns App_Date and App_Time are of type datetime then you need to pass parameters of the appropriate type, not simply strings. Instead if, these fields are of type nvarchar (or some other kind of text type) then you pass strings but you will have problems storing and querying correctly in these fields.