Cant save or update my SQL Server tables using vb.net - sql

I am a complete beginner to .net and am confused at some basic things. Please help.
First of all the table I create and populate (by right clicking tables in server explorer) disappear once I restart the computer. how do I keep them.
Is there any better place/interface to type SQL queries in vb.net than the command prompt.
In the following code:
Dim cn As SqlConnection = New SqlConnection(strConnection)
cn.Open( )
' Create a data adapter object and set its SELECT command.
Dim strSelect As String = _
"SELECT * FROM Categories"
Dim da As SqlDataAdapter = New SqlDataAdapter(strSelect, cn)
' Load a data set.
Dim ds As DataSet = New DataSet( )
da.Fill(ds, "Categories")
This far the code runs fine but just to gain better understanding, I would like to ask that
while data from SQL Server database was saved into da in accordance to the query, why do we need to save/transfer it in the dataset object ds.
Is there any additional benefit of SqlCommand over SqlDataAdapter besides speed?
Dim autogen As New SqlCommandBuilder(da)
Dim dt As DataTable = ds.Tables("Categories")
' Modify one of the records.
Dim row As DataRow = dt.Select("CategoryName = 'Dairy Products'")(0)
row("Description") = "Milk and stuff"
gives an error when I use it with
da.Update(ds, "Categories")
regarding dt.select not returning any value.
What is the way out?

to answer your questions :
The tables you create with the server explorer are IN MEMORY. Same goes for dataset, they are in-memory representation of your table. As for your 2nd example, the DS you use isnt filled when you try to get the DT. hence why the DT is empty.
If your starting, I would suggest you go look into Linq-to-Sql (http://msdn.microsoft.com/en-us/library/bb425822.aspx) for a more up-to-date way of doing sql in .net ( I think its 4.0 framework)
As for the 2nd point, I'd say normally you should use store procedure for most of your sql commands .. the sqlcommand is use like this
Try
Cmd = New SqlClient.SqlCommand("st_InventoryStatus_Or_AnyStoreProcName_Or_ASqlQuery")
Cmd.CommandTimeout = 300 'not really needed'
Cmd.CommandType = CommandType.StoredProcedure 'you can type CommandType.Text here to use directly your "Select * from Category"'
Cmd.Parameters.Clear() 'just to be sure its empty, its not mandatory'
Cmd.Parameters.Add("#idCategory", SqlDbType.Int).Value = myCategory.Id 'here are the parameters of your store proc, or of your query ("select * from Category where Category.id = #Id")'
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try

Related

Parameterized SQL Command does not update my column

I have a simple button which end the Work day in my Management System. Sadly when pressed all fine but the Column in my Table is still empty.
Here is the code:
Dim sql As String = "UPDATE [TA-Arbeitszeit] SET Ende = #ende WHERE Personal_nr = #Personal_nr"
Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\recycle2000.mdb;"),
cmd As New OleDbCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("#Personal_nr", OleDbType.VarChar).Value = tbxUserInput.Text.Trim()
cmd.Parameters.Add("#ende", OleDbType.VarChar).Value = DateTime.Now.ToString("G")
Dim icount As Integer = cmd.ExecuteNonQuery
End Using
Access doesn't fully support named parameters. Although you can and should use parameter names for your own clarity, Access ignores them. It simply inserts your parameter values into the SQL code in the order they are added. That means that they need to be added in the same order as they appear in the SQL code. Your SQL code has #ende before #Personal_nr but when you add parameters you do it the other way around. Switch the order in which you add the parameters and you should hopefully be fine.

Deleting SQL datarow from a table swipes position of first and second row in vb.net

adding updating everything is fine even delete command is working but the strange part is after executing del command from vb.net application it swipes the position of EMPLOYEE_IDAND NAMEit shows normally in datagridviewafter adding or updating but specifically after deleting the record position of these to column changes until I stop the application and re run the entire project for debugging
Dim con As New MySqlConnection("server=localhost; user=root; password=Masoom1; database=airtech_db; convert zero datetime=true;")
Dim cmd As New MySqlCommand
Dim dt As New DataTable
Dim da As New MySqlDataAdapter
Dim sql As String
Dim DR As MySqlDataReader
Dim SQL_CMD_TXT As String
SQL_CMD_TXT = "DELETE FROM `employees` WHERE (`EMPLOYEE_ID` ='" &
EMPLOYEE_DEL_FRM.DEL_ID_TXT.Text & "'); SELECT * FROM `employees`;"
EMPLOYEE_DEL_FRM.Controls.Add(OBJECT_DATAGRIDVIEW)
With OBJECT_DATAGRIDVIEW
.Size = New Size(587, 242)
.Location = New Size(221, 171)
End With
Try
'DB CMD EXECUTION
con.Open()
With cmd
sql = SQL_CMD_TXT
.Connection = con
.CommandText = sql
End With
da.SelectCommand = cmd
da.Fill(dt)
'Command for datagridview object
With OBJECT_DATAGRIDVIEW
.DataSource = dt
'Scroll to the last row.
.Name = "MYDATAGRIDVIEW"
.FirstDisplayedScrollingRowIndex = .RowCount - 1
End With
con.Close()
Catch ex As Exception
Dim MEB = MessageBox.Show("ERROR FOR SQL CMD EXECUTION SECTION-" & ex.Message,
"SQL CMD EXECUTION", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
attaching the normal and after delete result in images
enter image description here
I am not sure I completely understood your problem, but your problem could that the datagridview generates the columns automatically. See: DataGridView.AutoGenerateColumns
Instead of doing SELECT * FROM is would better to select just the fields you need. If you add more fields to your table in the future, the columns in the datagridview may be displaced because they are in no particular order.
Rather than add the datagridview to your form at runtime:
EMPLOYEE_DEL_FRM.Controls.Add(OBJECT_DATAGRIDVIEW)
I would add it directly in the form layout (so you can see it at design time), and then customize it, bind each column to a database field. The appearance of the grid will be more predictable. Here is a small guide: How to bind datatable/list to datagridview with headers?
Relying on AutoGenerateColumns is not a great idea, because this will show all columns (usually not desirable) and not necessarily in the order that you want.
Other remarks:
Records can be edited or deleted directly in the datagridview, by simply selecting one or more rows, and pressing the Del key. Then just invoke the DataAdapter to commit the changes to the database. You should not even be doing DELETE FROM. Just let the user use the datagridview. The benefit is that if the user makes a mistake, you can roll back changes because you are using a datatable. Here you are deleting immediately and without warning.
Don't do stuff like:
SQL_CMD_TXT = "DELETE FROM `employees` WHERE (`EMPLOYEE_ID` ='" &
EMPLOYEE_DEL_FRM.DEL_ID_TXT.Text & "'); SELECT * FROM `employees`;"
Use parameterized queries instead, this code is insecure and will choke on single quotes or special characters (try it !). Here is a simple example: FAQ: How do I make a parameterized query in the database with VB.NET?. Please use parameterized queries from now on, don't develop bad habits that will always bite you sooner or later. The security risk alone is too high.
Also I am wondering why you did stacked queries. It would better to separate the SELECT from the DELETE.
In this code variable sql is not needed:
With cmd
sql = SQL_CMD_TXT
.Connection = con
.CommandText = sql
End With
Just use SQL_CMD_TXT directly. Otherwise it makes the code more difficult to follow.

'No value given for one or more required parameters.' Error, Can't get over it

I'm trying to take a Yes/No value from my database on Access and make it so if the Yes/No is checked on Access it will check it on the form. Although I keep getting
System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.'
On the line Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
Sorry if it's a really easy and stupid mistake, I'm a college student and googling isn't helping me figure this one out.
cn.Open()
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
While rs.Read
Dim DisplayValue As String = rs("staffIn")
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
SQLCmd.ExecuteNonQuery()
End While
cn.Close()
I know this is an old post but I seem to remember that OleDb does not support named parameters.
Also, pretty sure that DarrenSloan should be surrounded by single quotes, like any string value. And indeed, reusing the SQL command like this is not the way to do it.
The CommandText:
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
does not contain any parameter.
Thus, the parameter inorout has no effect:
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
Either use two statements, one SELECT and one UPDATE.
Or use a different mechanism like a databound grid. Maybe you are using a datagridview control to display the data. Then there are different techniques to keep the data in sync. It depends on how you choose to render the data on your form.
Firstly, get rid of the loop. You would only use a loop if you were expecting more than one record. By the looks of it, you are expecting only one record, so no loop.
Secondly, stop calling ExecuteNonQuery. That is for making changes to the database, which you're obviously not trying to do. You obviously know how to get data from the query because you're doing it here:
Dim DisplayValue As String = rs("staffIn")
If you want to get data from another field, do the same thing. You can then use that data in whatever way you like, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = 'DarrenSloan'", connection)
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using
Notice that I have wrapped the text literal in the SQL in single-quotes? I would expect that you would normally not want to hard-code a name there, but use input from the user instead, In that case, you would use a parameter, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = #staffName", connection)
command.Parameters.Add("#staffName", OleDbType.VarChar, 50).Value = staffNameTextBox.Text
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using

please help retrieving data to put it on label

I want to retrieve the price from table Products to use it as label2 on the orderinfo form.
Dim con As New OleDb.OleDbConnection
Dim com As New OleDb.OleDbCommand
com = New OleDb.OleDbCommand("Select Price FROM Products WHERE ProductName='" & ListBox1.SelectedItem.ToString & "'", con)
con.ConnectionString = "PROVIDER = Microsoft.ACE.OLEDB.12.0; Data Source=Database_AntoninosCafe.accdb"
con.Open()
com.ExecuteNonQuery()
orderInfo.Label2.Text = retrieve data
con.Close()
The correct approach to your simple problem
Dim cmdText = "Select Price FROM Products WHERE ProductName=?"
Using con = New OleDb.OleDbConnection( ... connection string here ...)
Using com = New OleDb.OleDbCommand(cmdText, con)
com.Parameters.AddWithValue("#p1", ListBox1.SelectedItem.ToString)
con.Open()
Using reader = com.ExecuteReader()
if reader.Read() Then
orderInfo.Label2.Text = reader("Price").ToString
End If
End Using
End Using
End Using
The first thing is to use a parameterized query to avoid sql injections and parsin problems, then use the Using statement to encapsulate you disposable object in a block of code that ensures the closing and disposing of these objects.
Finally, to read data from a datatable you use the ExecuteReader command that returns an OleDbDataReader instance. It is this instance that could be used to extract the data from your database
As a side note, I have used, as placeholder for the parameter, a question mark. This is the predefined symbol used by OleDb. But, when adding the parameter value to the collection, I have used a different name (#p1). This is acceptable because OleDb do not use the parameter names to find the corresponding placeholders in the query text like the SqlClient or other providers, but use the position of the placeholder. So, first placeholder replaced by the first parameter and so on.

Cannot connect to dbf file

I'm trying to connect to to a foxpro table (.dbf) from a test vb.net form.
I recieve an OleDbException with the message "Cannot open file c:\emp\emptbl.dbf"
Have tried with both of the following connection strings:
Provider=VFPOLEDB.1;Data Source=C:\emp\emptbl.dbf
from the MSDN article here
Provider=vfpoledb;Data Source=C:\emp\emptbl.dbf;Collating Sequence=machine;
from connectionstrings.com
The latter seems to be the type to use when connecting to a single table, but the same exception is thrown regadless of which is used.
I can open and perform the same query okay in visual foxpro 6.0.
Here's my code:
Dim tbl As DataTable = New DataTable()
Using con = New OleDbConnection(conString)
cmd = New OleDbCommand() With {.Connection = con, .CommandType = CommandType.Text}
Dim sSQL As String = "SELECT * FROM(EMPTBL)"
cmd.CommandText = sSQL
Dim adp As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim ds As DataSet = New DataSet()
con.Open()
adp.Fill(ds)
con.Close()
If (ds.Tables.Count > 0) Then
tbl = ds.Tables(0)
End If
End Using
Return tbl
The OleDB provider should only connect to the PATH where the tables are... not the actual file name. Once you connect to the PATH, you can query from ANY .Dbf file that is located in it
Provider=VFPOLEDB.1;Data Source=C:\emp
select * from emptbl where ...
You can also look at other connection string settings at
ConnectionStrings.com
UPDATE per comment.
It appears you are getting closer. with your attempt without the () parens. In VFP, within parens, it interprets that as "look for a variable called EMPTBL", and from its value is the name of the table to query from. Not something you would need to apply via OleDB connection.
Now, cant open the file is another. Is it POSSIBLE that another application has the table open and the file is in exclusive use? and thus can not be opened by the .net app too? Even for grins, if you open VFP, and just do a simple create table in the C:\Emp folder and put a single record in it, then you know no other program will be using it as it is a new file. Quit out of VFP and try to query THAT table. There should be no locks, no other program is expecting it, so it should never be opened by anything else and you should be good to go.