Unable to insert string into Access database - vb.net

I am using a WPF application to insert a student into my MS Access database.
I wanted to use a parameter with this code:
Dim sql As String = _
"INSERT INTO exams " & _
"VALUES (#student)"
Dim opdracht As OleDbCommand = New OleDbCommand(sql, connectie)
opdracht.Parameters.Add(New OleDbParameter("#student", 5))
but this doesn't work.
The only way i get it to work is this one:
Dim sql As String = _
"INSERT INTO exams " & _
"VALUES (" & student & ")"
' opdracht initialiseren
Dim opdracht As OleDbCommand = New OleDbCommand(sql, connectie)
To use this query I use the command, this is the point where I get my error.
opdracht.executeNonQuerry()
The table layout in MS Access looks like this:
And my application inserts the other values corectly but i left them out to keep a minimal example.

If you have a variable named student and you want to use its value for the parameter then you need to assign that variable as parameter's value
Dim sql As String = "INSERT INTO exams VALUES (#student)"
Dim opdracht As OleDbCommand = New OleDbCommand(sql, connectie)
opdracht.Parameters.AddWithValue("#student", student)
opdracht.ExecuteNonQuery()
Of course, I am assuming this because you say that the string concatenation version is working, and in that example you concatenate the value of a variable named student in your command text
Remember that with OleDb the name of your parameters is meaningless because OleDb use the position of the placeholder to pass the parameters' values, not the parameter name
EDIT Using INSERT INTO without specifying the column names works only if you add the parameters for all fields. Your database table contains other fields so you need to specify them or use a different syntax for the INSERT INTO
Dim sql As String = "INSERT INTO exams (Student) VALUES (#student)"
But this will fail also because you have the Student field part of your primary key. The fields that belong to a Primary Key cannot be null so you have no choice but add all the values required by the primary key
Dim sql As String = "INSERT INTO exams (Student, locaal, opleidingsOnderdeel) " & _
"VALUES (#student, #local, #oplei)"
.. add the parameter's value for student, local and oplei
However, I am a bit perplexed that the string concatenation works. What is the value of the variable student? You should get the same error as using the parameterized query with only one parameter.

Related

Inserting empty values as string to sql table

I have a project which has a Class which has some members as string which equal "". My teacher had shown examples with Class members declared as String = "NULL". I try to insert to SQL and I get this message:
Error insertion... Error converting data type varchar to numeric.
I know many will suggest to use parameterized values for inserting but I like to finish the way I started this.
I have tried to cast query string Object values with CDec, CInt, Cbit and still no clue how to do it right because I got Exceptions for trying to cast an "".
Also, I have changed to default values of members like this;
Dim NumberOfPackage As String = ""
instead of;
Dim NumberOfPackage As String = "NULL"
Some Columns in SQL table had ALLOW NULL checkBox set to NOT allowed, I changed the design of the Table to make it easier for insertion.
The field in database have been set to not null? I think that dbnull.value do what you want
I think I understand what is happening. Your variable NumberOfPackage contains numbers but since you want to insert NULL sometime, you made it a string.
NumberOfPackage = "23"
NumberOfPackage = "NULL"
"INSERT INTO table (column) VALUES (" & NumberOfPackage & ");"
But since you use a string, you might be trying to do
"INSERT INTO table (column) VALUES ('" & NumberOfPackage & "');"
Which would cause the error on NULL since your column is a number and it is trying to do
"INSERT INTO table (column) VALUES ('NULL');"
Stick with my first example (without the ') if you really want to concatenate strings but everything would be much easier if you used parameters. By using parameters, it would be easier to keep NumberOfPackage as a decimal or a decimal? and do proper math with it.
To insert a NULL value, it must be without the apostrophes like #RichBenner and #the_lotus state:
Dim myCommand As String
myCommand = "INSERT INTO dbo.Foo (Foo_Text) VALUES (NULL);"
'The query for an empty string would look like this
myCommand = "INSERT INTO dbo.Foo (Foo_Text) VALUES ('');"
col1 in my Builder database is datatype int and nulls are allowed. This is how it is done with Parameters. TextBox1 will hold the number of packages and TextBox2 the name. I used the object datatype so it could hold either DBNull.Value or an Integer.
Private Sub InsertRecord()
Dim myValue As Object
Dim myInt As Integer
If Integer.TryParse(TextBox1.Text, myInt) Then
myValue = myInt
Else
myValue = DBNull.Value
End If
Using cn As New SqlConnection(My.Settings.BuildersConnectio)
Using cmd As New SqlCommand("Insert Into Builders (BuilderName, col1) VALUES (#Name, #NoOfPackages);", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar, 100).Value = TextBox2.Text
cmd.Parameters.Add("NoOfPackages", SqlDbType.Int).Value = myValue
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub

Excel to VB: Can't read the zero behind

I'm doing a connection with excel and I have a problem when I try to use an ID that have 0 behind...
I'm using a ListBox and add the IDs from the excel's worksheet as items. IDs have 9 numbers, like "123456789" or "098765430". So that I remove the last 4 characters to search the IDs with the same 5 numbers and add in another ListBox. It works fine, except with the codes with 0 (zero) behind.
Dim ConnectionString As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Application.StartupPath & "\Tabela_Precos.xlsx; Extended Properties=Excel 12.0;")
ConnectionString.Open()
Dim ds As New DataSet
Dim dt As New DataTable
ds.Tables.Add(dt)
Dim da
For i = 0 To Form1.ListBox1.Items.Count - 1
Dim str As String = Compras.ListBox1.Items(i).ToString
Dim prod As String = str.Remove(str.Length - 4)
da = New OleDbDataAdapter("SELECT * FROM [Sheet1$] WHERE ID like '%" & prod & "%'", ConnectionString)
ListBox1.Items.Add(dt.Rows(i).Item(0))
Next
Your Excel file has the ID column entered as integer values, but is formatted for left-zero padding to present as a nine character field. Your Excel db connection is reading the values as numbers (type Double, even-though they are integers). Your original select statement is implicitly convert ID to a string for the Like comparison; however, this conversion does not now you want left-zero padding. To use this type of comparison, you need to format ID yourself.
Select * From [sheet1$] Where (Format([ID], ""000000000"") Like '" & prod & "%')"
As you have indicated in the comments above, this works. However, it is not the most efficient in terms of speed. Since ID is numeric, it should be faster to do a numeric comparison. You have already defined a String variable named prod and the following solution uses that variable to prepare a numeric value for use in constructing an alternate select based on your criteria.
Dim prodNum As Int32 = Int32.Parse(prod) * 10000I
Then the Select statement would become:
"Select * From [sheet1$] Where ((([ID]\10000) * 10000)=" & prodNum.ToString & ")"
These examples use a concatenated select statement, and ideally you would not do it this way, but rather use a parameterized statement with replacement values. I'll leave that exercise up to you to perform.

Can't compare vb.net item with access number

Edit: For anyone facing this problem, don't miss the tips about only using
parameters instead of inserting the values directly into the SQL queries.
i'm facing a big problem with my vb.net project, i'm stuck with this for a week
i've a combobox item that i need to compare with an access number which is my database to retrieve some information, but i just got an error, no matter what format i convert my combobox item, it says my datatype is inconpatible with the expression
Here's one of the SQL queries from my code:
Dim dt1 As New DataTable
'This query select some itens from a row that match with the selected combobox number
Dim find1 As New OleDb.OleDbDataAdapter("SELECT Product, Number," _
& " Customer, Quantity, ProductionDate, AskDay, Pack, Company FROM RegOPE" _
& " WHERE Number ='" & CInt(mycombobox.SelectedItem) & "'", cn)
'Ive tried SelectedItem, Item, Text, SelectedValue...
'For conversion i tried parse, tryparse, conversion...
cn.Open() 'Opens database connection
find1.Fill(dt1) <- I got the error here
cn.Close() 'Close database connect
mydatagrid.DataSource = dt1 'Show the result in datagridview
number criteria should be without quote
Dim find1 As New OleDb.OleDbDataAdapter("SELECT Product, Number, " _
& "Customer, Quantity, ProductionDate, AskDay, Pack, Company FROM RegOPE " _
& "WHERE Number =" & CInt(mycombobox.SelectedItem), cn)
But better always use parameters:
Dim comm = New OleDb.OleDbCommand("SELECT Product, Number, " _
& "Customer, Quantity, ProductionDate, AskDay, Pack, Company FROM RegOPE " _
& "WHERE Number =?", cn)
comm.Parameters.AddWithValue("unusedName", mycombobox.SelectedItem)
Dim find1 As New OleDb.OleDbDataAdapter(comm)
In your WHERE clause have you tried to remove the quotes ? They are not required if you are looking for a number.
First, I must mention that you really ought to be using parameters. You should not concatenate the values directly into the SQL command string like that. Your SQL command string should simply contain parameter name placeholders for those values and then you should specify the values for those parameters separately.
However, if you are going to concatenate the value with the command like that, the command is a string, not an integer. It makes little sense to use CInt to convert the item to an integer just before concatenating it with a string (which requires first converting it from the integer into a string). It would make more sense to simply call ToString to convert it to a string, instead of CInt. Also, if the Number column in your database is typed as a number, rather than as text, then you should not be surrounding the value with quotes.
I recommend trying this:
Dim find1 As New OleDb.OleDbDataAdapter("SELECT Product, Number," _
& " Customer, Quantity, ProductionDate, AskDay, Pack, Company FROM RegOPE" _
& " WHERE Number =" & mycombobox.SelectedItem.ToString(), cn)
Although, recommend is to strong a word, since I would never recommend doing it that way in the first place. Use parameterized queries!

Error in My Add button SQL Server Management Studio And Visual Basic 2010

Here is the thing I can't use insert query in my code there is an error in my SqlCommand that says the ExecuteNonQuery() not match with the values blah blah
Here is my code
Dim con As New SqlClient.SqlConnection("Server=.\SQLExpress;AttachDBFilename=C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\Finals.mdf;Database=Finals;Trusted_Connection=Yes;")
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = con
cmd.CommandText = "Insert Into [Finals].[dbo].[Nokia] Values ('" & Unit.Text & "'),('" & Price.Text & " '),('" & Stack.Text & "'),('" & Processor.Text & "'),('" & Size.Text & "'),('" & RAM.Text & "'),('" & Internal.Text & "'),('" & ComboBox1.Text & "')"
con.Open()
cmd.ExecuteNonQuery()
con.Close()
The problem is the cmd.CommandText can anyone please help me?
You need to rewrite your query to use a parameterized query. This would avoid parsing problems if your textboxes contains single quotes and, most important, would remove any possibility of Sql Injection.
So you code could look like this
Dim cmdText = "Insert Into [Finals].[dbo].[Nokia] Values (#unit, #price,#stack," & _
"#processor,#size,#ram,#internal,#lastvalue"
Using con As New SqlConnection(......)
Using cmd As New SqlCommand(cmdText, con)
con.Open()
cmd.Parameters.AddWithValue("#unit",Unit.Text )
cmd.Parameters.AddWithValue("#price",Price.Text)
cmd.Parameters.AddWithValue("#stack",Stack.Text)
cmd.Parameters.AddWithValue("#processor", Processor.Text)
cmd.Parameters.AddWithValue("#size",Size.Text)
cmd.Parameters.AddWithValue("#ram", RAM.Text)
cmd.Parameters.AddWithValue("#internal",Internal.Text)
cmd.Parameters.AddWithValue("#lastvalue", ComboBox1.Text)
cmd.ExecuteNonQuery()
End Using
End Using
Said that, be aware of two more problems:
You don't specify a column list before the VALUES statement. This means that you need to pass the exact number of parameters for every column present in your table named Nokia AND in the EXACT ORDER of the underlying columns. If you forget one parameter you will receive an exception and if you swap the order of the parameters you end writing your data in the wrong column (with an exception waiting for you if the datatype doesn't match).
The second problem concerns the datatype of every parameter passed to the query. In your case you use the Text property of the textboxes and this means that you are passing a string for every column in the datatable. Of course, if a column expects a numeric value you get a mismatch error.
For example the #price parameter could be used to update a decimal column in the datatable and thus you need to convert the parameter from string to decimal before adding it using the AddWithValue method
cmd.Parameters.AddWithValue("#price",Convert.ToDecimal(Price.Text))

MS access SELECT INTO in vba

I'm having some issues with some functionality of my application. There is a particular instance where I have an instance of a 'pending class' on a form for an administrator to review. The form is populated with students associated with this pending class. After their grades are finished, I have a button at the footer that will delete this class from my 'pending' table and add the grades to all of the students. This works.
However, I want to essentially copy this pending class, which just has the class name, date, and teacher to a completed class table before it's deleted from pending. Since no data about this class other than the primary key(class number) persists throughout this form, I can't populate the other fields(class name, date) of the row into my completed class table.
I am trying a "SELECT INTO" operation in VBA to get these values. It's going like this:
dim cname as String
dim classdate as Date
dim pid as integer
dim teacher as String
dim qry as String
pid = [Forms]![frmClasses]![txtID]
qry = "Select className INTO cname FROM tblPending WHERE tblPending.id = " & " ' " & pid & " ' " & ";"
db.execute qry
debug.print qry
debug.print cname
From here, I do the same operations for each other variable, build my INSERT query, and execute it. The problem is-- my select into's are not working. Debug.print shows that the local variables were never initialized from the SELECT INTO statement. Any thoughts?
First, having all classes in one table and just setting a "NotPending" or "Completed" column would be better.
Having two identical tables for classes and moving values from one into the other to indicate status changes is bad database design.
If you really need to do this by using two tables and copying rows, then you need an INSERT INTO query (and not SELECT INTO), as already mentioned by Remou in the comments, because SELECT INTO creates a new table (or overwrites an existing one with the same name, if already there).
The syntax for INSERT INTO looks like this:
INSERT INTO CompletedClassTable (ClassName, Teacher)
SELECT ClassName, Teacher FROM tblPending WHERE id = 123
And finally, you asked this in a comment:
So SELECT INTO is completely different in Access than Oracle? In Oracle and PL/SQL, you can select a row into a variable OR a table. In Access can you not select into a variable?
To load a row into a variable, you need to use a Recordset.
Example code to load your query into a Recordset and output the ClassName field:
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset("SELECT * FROM tblPending WHERE id = 123")
If Not RS.EOF Then
Debug.Print RS("classname")
End If
RS.Close
Set RS = Nothing
Seems you want to retrieve a text value, className, from tblPending where tblPending.id matches the value found in your text box, txtID, and store that text value in a string variable named cname.
If that interpretation is correct, you needn't bother with a query and recordset. Just use the DLookup Function to retrieve the value, similar to this untested code sample.
Dim cname As String
Dim pid As Integer
Dim strCriteria As String
pid = [Forms]![frmClasses]![txtID]
strCriteria = "id = " & pid
cname = Nz(DLookup("className", "tblPending", strCriteria), vbNullString)
Debug.Print "cname: '" & cname & "'"
Notes:
I assumed the data type of the id field in tblPending is numeric. If it is actually text data type, change strCriteria like this:
strCriteria = "id = '" & pid & "'"
DLookup() returns Null if no match found. Since we are assigning the function's return value to a string variable, I used Nz() to convert Null to an empty string. Alternatively, you could declare cname As Variant (so that it can accept a Null value) and get rid of Nz().