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)
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'm trying to insert data into a database with an autonumber in MS Access as primary key. I get an error saying "Number of query values and destination fields are not the same. The data types in MS Access are Autonumber (I didn't include it in the INSERT statement), String (#OrderNo), String (#Product), Number (#Qty), and Date (#TDate). Here's the image:
Here's my code:
For Each row As DataGridViewRow In DataGridView1.Rows
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Daily Inventory.accdb;"
Using conn As New OleDbConnection(connString)
Using cmd As New OleDbCommand("Insert into Table1 Values(#OrderNo, #Product, #Qty, #TDate)", conn)
cmd.Parameters.AddWithValue("#OrderNo", TxtOrder.Text.ToString)
cmd.Parameters.AddWithValue("#Product", row.Cells("Product").Value)
cmd.Parameters.AddWithValue("#Qty", row.Cells("Qty").Value)
cmd.Parameters.AddWithValue("#TDate", Date.Now.ToString("MM/dd/yyyy"))
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
End Using
End Using
Next
You need to change your sql to "Insert into Table1 (OrderNo,Product,Qty,TDate) Values(#OrderNo, #Product, #Qty, #TDate)".
The following code works for me.
DataGridView1.AllowUserToAddRows = False
For Each row As DataGridViewRow In DataGridView1.Rows
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=...;"
Using conn As New OleDbConnection(connString)
Using cmd As New OleDbCommand("Insert into Table1 (OrderNo,Product,Qty,TDate) Values(#OrderNo, #Product, #Qty, #TDate)", conn)
cmd.Parameters.AddWithValue("#OrderNo", TxtOrder.Text.ToString)
cmd.Parameters.AddWithValue("#Product", row.Cells("Product").Value)
cmd.Parameters.AddWithValue("#Qty", row.Cells("Qty").Value)
cmd.Parameters.AddWithValue("#TDate", Date.Now.ToString("MM/dd/yyyy"))
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
End Using
End Using
Next
Well, I think we dealing with a bit of a chicken and a egg problem here?
I mean, how did the grid get created?
How and where did you setup the columns in the grid?
lets drop a data grid view into a form. Drop in a button.
We have this code to load up the grid:
Private Sub HotelGridEdit_Load(sender As Object, e As EventArgs) Handles Me.Load
LoadGrid()
End Sub
Sub LoadGrid()
Using conn As New OleDbConnection(My.Settings.AccessDB)
Dim strSQL As String =
"SELECT ID, FirstName, LastName, City, HotelName, Description, Active FROM tblHotelsA
ORDER BY HotelName"
Using cmdSQL As New OleDbCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
DataGridView1.DataSource = rstData
End Using
End Using
End Sub
So, now we have this:
Now, in a above, I can cursor around - make any edits I want.
I can also type in on the bottom blank row to add new rows.
I can click on the left side recordselector, and hit delete key.
Now, to save my edits, save my addtitions, and save my deletes?
I have the one button at the top, and this code works to do all updates, all addtitions, and all deletes.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' save all edits, and new rows, and deletes
Using conn As New OleDbConnection(My.Settings.AccessDB)
Dim strSQL As String =
"SELECT ID, FirstName, LastName, City, HotelName, Description, Active FROM tblHotelsA"
Using cmdSQL As New OleDbCommand(strSQL, conn)
conn.Open()
Dim da As New OleDbDataAdapter(cmdSQL)
Dim daC As New OleDbCommandBuilder(da)
da.Update(DataGridView1.DataSource)
End Using
End Using
End Sub
So, not a lot of code.
In fact, often using a data table is a lot less work, since you don't have to mess with all those parameters anyway - even if your data grid was somehow not feed from the database. But, if you feeding the "grid" from the database, then really, you can just add rows - and then write some code to send the changes back to the database with the above code. And if you want to start out with a blank grid - not show previous rows, then just add to your sql like this:
SELECT * from tblHotels WHERE ID = 0 Order by Hotelname
Use above to create a data table without any rows but STILL bind that to the grid, and thus once again, to add, or delete rows, you just edit and add them, and again the SAME code I had above will work to save edits, deletes and additions.
Here is my general understanding of database from what I read so far: Save / Update / Delete to pre-existing file made that binds to form thru SQL.
Here is what I am trying to do - I have a pre-made Data Table in Form with all columns defined. Once app is closed or certain functions ran, I need that data to be saved / updated in SQL (on local). Once app is open I need all that data to be preserved.
So far I have NOT found a single solution to it anywhere most refer to binding to an existing file. When I worked with Excel data transfer cells had to be defined and referenced in form for population.
My assumption is when a database from VB.NET is used, table with values can be created automatically saved/loaded/updated. However this is only my assumption since I never worked with SQL before. I am not sure if I need to manage an actual database file I created with all the values and then bind them to data table. For example DataTable cell XX to database column XX.
Here is what I done so far I have created database and added to my project. I tried few codes and I keep getting Dataset Empty even though there is Data in Table I tried to use DataTable as well but so far nothing has worked.
Please suggest on what I am doing wrong also additional information regards to databases will be great. As per previous I do know how binding works when actual file exist. But creating and managing is confusing to me since I keep thinking there should be a binding file.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "SELECT BN FROM DataTable" ' BN is my column name and DataTable is the name of my Table where data gets populated. This is also confusing to me How does it know which value is what? Is there are space/word/characters requirements?
' adapter.TableMappings.Add("DataTable", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds)
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
Code I use to Create /Save Database. As per previous all columns/formats are pre-made, loaded.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "Select BN FROM DataTable"
adapter.TableMappings.Add("BN", sql)
If DataTable.RowCount > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf DataTable.RowCount = 0 Then
MsgBox("Empty data")
End If
End Sub
Please see more info below:
Data Table columns/format are structured for visual representation.
When User start the App Database can be empty/Can contain Values.
When users Runs certain function Closes App values are save and only values.
If I would you an MS Access I would structure same table/values and cross reference it with form values. Form Values come from outside source and Format/Qty is always known.
Hope this helps to have a cleaner look at my issue. Perhaps SQL is not a right choice for me? Does SQL needs to be build before value manipulation.
UPDATE: I Got rid of the Invalid Object error. Table had to be created 1st as I originally thought. However, My DataSet always comes up as EMPTY when I try to save... Cells do contain BN data as" 1,2, ....) Even if I to remove "If" logic Save and Load table comes out as empty. Something does load because when I try to ADD BN it tells me binding bla bla bla(different issue)
CODE:
Private Sub SaveData()
Dim connetionString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Dim sql As String = "SELECT BN FROM DataTable_d"
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet()
adapter.TableMappings.Add("BN", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
UPDATE: I got all the things working but I can't save multiple rows..... Could really use some help
In your SQL query remove WHERE DataTable ='. This statement is looking for a column name DataTable which I assume does not exist. The WHERE clause is used to help filter your query. You only use WHERE on column names in your table.
For instance:
SELECT BN FROM DataTable
will return all values from the BN column from DataTable.
Note that if you have multiple columns, the above query will still only return values from BN.
SELECT * FROM DataTable
will return every value in DataTable.
A helpful site to look at documentation for SQL is w3schools.
Let's start with just displaying some data. Add a DataGridView to a Form. You can call LoadData() from a button. I am not very sure of you connection string but give it a try.
Private dt As DataTable
Private sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Private Sub LoadData()
'***EDIT*** Add instantiation line
dt = New DataTable()
'The Using...End Using blocks will close and dispose your database objects
'even if there is an error
Using cn As New SqlConnection(sql)
'You can pass the command text and the connection directly to the constructor
'In the select statement use the actual names of the field and table as they appear in the database.
Using cmd As New SqlCommand("Select BN From [Insert the name of the table in the database]", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
This is the simplest way I can think of to display data. We will proceed with changing the data once this works. If you get an error on cn.Open() We will have to work on the connection string.
****EDIT****
Private Sub TestConnection()
Dim sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Using cn As New SqlConnection(sql)
cn.Open()
End Using
End Sub
I am trying to execute a stored procedure that will take the start and end time from my DateTimePicker and check to see if a vehicle is available and return a dataset with those that are. The code does work when I run it in SQL Managment Studio, so I am trying to execute with VBA in Visual studio.
I will plan to post later on help with displaying the dataset as I am not sure how to do this in code and have had a hard time finding good examples but for now I am trying to get past this error message. I have gone back and changed the format to a custom format so it matches the date format in my SQL database. The custom format I am using on both datetimepickers is yyyy-MM-dd. I have tried several of the suggestions on the various websites but no luck so far getting past this message. Below is the code from my stored procedure as well as the visual basic code.
CREATE PROC spVehicleAvailable
#RequestedStartDate Date,--DateTime selectedDate = dateTimePicker1.Value.Date
#RequestedEndDate Date--DateTime selectedDate = dateTimePicker2.Value.Date
AS
BEGIN
Select Vehicle.*
FROM Vehicle
Where Vehicle.VehicleID NOT IN (
SELECT VehicleID FROM LoanRequest
WHERE #RequestedEndDate >= LoanRequest.StartDate
AND #RequestedStartDate <= LoanRequest.EndDate)
AND Available = 1 AND Scrap=0
END;
Private Sub btnAvailable_Click(sender As Object, e As EventArgs) Handles btnAvailable.Click
Try
Dim sqlConnection1 As New SqlConnection("Data Source=GALE-PC1\SQLEXPRESS2012;Initial Catalog=VehicleCheckout;Integrated Security=True")
Dim cmd As New SqlCommand
cmd.CommandText = "spVehicleAvailable"
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = sqlConnection1
cmd.Parameters.AddWithValue("#RequestedStartDate", Date.ParseExact(dtpStartDate.Text, "yyyy-MM-dd", CultureInfo.InvariantCulture))
cmd.Parameters.AddWithValue("#RequestedEndDate", Date.ParseExact(dtpEndDate.Text, "yyyy-MM-dd", CultureInfo.InvariantCulture))
'new code to try adding info into datagridview
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet("Vehicles") ' Not sure of this code
da.SelectCommand.Parameters(0).Value = "Not-Sure" 'Not sure of this code
da.Fill(ds)
If Not ds Is Nothing Then
MessageBox.Show("This Vehicle" & ds.Tables(0).Rows(0)("SomethngElse").ToString) 'Not sure of this code
End If
'end new code
sqlConnection1.Open()
cmd.ExecuteNonQuery()
sqlConnection1.Close()
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
End Sub
When you execute this : Date.ParseExact(dtpStartDate.Text, "yyyy-MM-dd", CultureInfo.InvariantCulture) in a imediate window, what's the result?
Thanks I used the MAX statement and it doesn't return an error but still don't understand why it isn't working. My code is shown below:
Protected Sub txtuserID_TextChanged(sender As Object, e As System.EventArgs) Handles txtuserID.TextChanged
Dim strConnection As String = "Data Source=.\SQLEXPRESS;AttachDbFilename=E:\LostPropertyProject\App_Data\LostPropertyDatabase.mdf;Integrated Security=True;User Instance=True"
'Establish SQL Connection
Dim con As New SqlConnection(strConnection)
'Open database connection to connect to SQL Server
con.Open()
'Data table is used to bind the resultant data
Dim dtusers As New DataTable()
'Create a new data adapter based on the specified query.
Dim comm As New SqlCommand
comm.CommandText = "SELECT MAX(UserID) FROM tblUser"
comm.Connection = con
Dim MaxUserID As Object = comm.ExecuteScalar()
con.Close()
End Sub
Also, I want the userID to be displayed in the textbox as soon as the page loads. How do I go about doing that? and thank you to everyone who replied to my question :) much appreciated
SELECT MAX(UserId) FROM User
This will give you the latest user id from the table.