Cannot connect to dbf file - vb.net

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.

Related

How can I allow multiple users to access/edit a microsoft access database?

Now I know right off the bat that Microsoft access isn't the ideal client for multiple users accessing it but it's the only one I've got right now. I have built a small program as a sort of inventory management system. There are currently three users that will be using it regularly and at the same time. One issue I am running into with this is that sometimes the database will not be accessible and will give an error stating that the file is already in use by "so and so" user. The other issue is that I'm getting a similar error every now and then where it states "The database has been placed in a state by user on machine that prevents it from being opened or locked". I am connecting to the database through an ACE OLEDB connection using the line below
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
I have also changed some of the settings in the actual access database such as:
Enable all macros
Add the folder the database is in to the trusted locations list
Confirm that the database is set to open in shared mode by default
I don't know if there is something small I've missed or a setting I need to change but as of yet, the problem is still persisting.
Below is an example of how I am using the database. I am using string based SQL commands but am not too familiar with DataSet/DataTable/etc. items, so I may be doing something incorrectly.
'close connection from any previous session
con.Close()
'clear dataset so as not to append data
ds.Clear()
'Select SQL query that selects ALL records from a table
Dim str As String = "SELECT * FROM " & "[" & table & "]" & ""
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=P:\Tool & Cutter Grinding\Tool Cutter Database.accdb;Persist Security Info = False"
'use try catch statement to open the connection
Try
con.Open()
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'use try catch statement to add a table (dt) to the dataset (ds) in order to store values
Try
ds.Tables.Add(dt)
Catch ex As Exception
End Try
'create new dataadapter object using the sql string from above and the connection created above
da = New OleDbDataAdapter(str, con)
'create new command builder in order to excecute the SELECT SQL statement using the dataadapter created (da)
'specify prefix and suffix for cb
Dim cb = New OleDbCommandBuilder(da) With {
.QuotePrefix = "[",
.QuoteSuffix = "]"
}
'use try catch statement to fill the datatable (dt) using the dataadapter (da)
Try
da.Fill(dt)
Catch ex As Exception
MsgBox(Convert.ToString(ex))
End Try
'set the datasource of the datagridview to the datatable
dgv.DataSource = dt.DefaultView
'close the connection to the database
con.Close()
Go to your Back-End Access DB file. File > Options > Client Settings. For your Use Case No Locks should be fine, but Edited record setting will work as well if you need it
but its [sic] the only one I've got right now
Actually, it's not.
Have a look at SQL Server Compact. It's free, it's small and it handles multiple users with aplomb.
You can add all the references you need using NuGet.

Queries appear to work, but don't actually affect Access database

I've added an access db to my project as a datasource. So I get the automatically generated tableadapters class and therefore, access to the table adapter instance which includes the connection string. I'm using this to open a connection to my db so I can first, delete some records, and then replace them with new records.
The queries seem to work because the .executenonquery does return the rows affected. I even tried a delete * command to be sure. But, when I open the database everything is the same.
I had some ideas as to why. I thought the connection string returned by the tableadapter might be goofy because it contains a generic pointer to the project's data directory.
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\DupeMDB.mdb;Persist Security Info=True
I also thought maybe I had a problem with the Build Action or the Copy to Output Directory. I really don't understand the mechanics behind these two things. I think maybe the copy to output directory thing might be the culprit.
Here's me goal. I want to deploy this project to my secretary so she can use the program to deal with a duplicate record list etc. The data has to go with the program. I want to package this .mdf file with the deployment and get it back from her when she's done with it. I am so close to the end here (writing back to the table). Does anyone know why the table won't update?
Dim Connector As DupeTblTableAdapter = New DupeTblTableAdapter
Dim Conn As New System.Data.OleDb.OleDbConnection
Conn = Connector.Connection
Conn.ConnectionString = Connector.Connection.ConnectionString
MsgBox(Conn.ConnectionString)
Dim Comm As System.Data.OleDb.OleDbCommand
Conn.Open()
For Each DR In DeleteRecords
Comm = New System.Data.OleDb.OleDbCommand($"DELETE from DupeTbl where DupeTbl.CUST_NO={DR.ToString}", Conn) '
Dim aff As Integer = Comm.ExecuteNonQuery
'MsgBox(aff)
Comm = Nothing
Next
For Each RR In ReplaceRecords
Comm = New System.Data.OleDb.OleDbCommand($"INSERT INTO DupeTbl ( CUST_NO, PREDIR, POSTDIR, SUFFIX, CUSTSIZE, AddFlag, IgnoreRecord ) VALUES ({RR.Cust_No}, '{RR.PreDir}', '{RR.PostDir}', '{RR.Suffix}', {RR.Size}, {RR.AddFlag}, {RR.Ignore});", Conn)
Comm.ExecuteNonQuery()
Comm = Nothing
Next
Conn.Close()
The issue in such cases is usually the working database being overwritten on each build. When adding a local data file to your project, it is added as a source file in the project folder. By default, the Copy to Output Directory property is set to Copy Always. That means that every time you build your project, which will happen each time you make a code change and run the project by default, the source file will be copied over the top of the working database in the output folder, thus wiping out any changes you made while debugging. To prevent this, change that property to Copy if Newer, which means that the working database will only be overwritten if you make a change to the source database, e.g. modify the schema.
Dim Connector As DupeTblTableAdapter = New DupeTblTableAdapter
Dim Conn As New System.Data.OleDb.OleDbConnection
Conn = Connector.Connection
Conn.ConnectionString = Connector.Connection.ConnectionString
MsgBox(Conn.ConnectionString)
Dim Comm As System.Data.OleDb.OleDbCommand
Conn.Open()
For Each UR In UpdateRecords
Comm = New System.Data.OleDb.OleDbCommand($"UPDATE DupeTbl SET CUST_NO = <NewValue>, PREDIR = <NewValue, POSTDIR = <NewValue> etc. where DupeTbl.CUST_NO={DR.ToString}", Conn) '
Dim aff As Integer = Comm.ExecuteNonQuery
'MsgBox(aff)
Comm = Nothing
Next
Conn.Close()

Opening SQL connection

I have inherited software to maintain. The previous version used a third party Datagridview substitute that isn't compatible with versions of Windows from Vista on. In attempting to put Datagridviews in I have run into a problem with connecting to the database.
I am trying to make a small program to play around with connection and SELECT outside of the original software so I can further understand what I am doing and without going through the full process of using the original software to get to the testing point.
Private Shared Function GetData(ByVal sqlCommand As String) As DataTable
Dim table As New DataTable()
Dim connectionString As String = "Data Source=.\SQLExpress;Integrated Security=true;" _
& "AttachDbFilename=C:blah\blah\blah.mdf;User Instance=true;"
Using con = New SqlConnection(connectionString)
Using command = New SqlCommand(sqlCommand, con)
Using da = New SqlDataAdapter(command)
da.Fill(table)
End Using
End Using
End Using
Return table
End Function
My SQL command is a simple "Select * FROM Setup" and the rest of the program is form loads, imports, and DataGridView formatting. I don't think it affects the SQL part and would be cumbersome to include here.
This results in what appears to be a closed connection.
![Connection Property] http://i.imgur.com/b5V3Qy5.png
This is a screenshot of my SQLExpress which might help diagnose connection problems.
![SQL Properties] http://i.imgur.com/bakBq5D.png
I've blurred out the computer name in grey, but I did notice that there was another computer name in pink. I don't know what it means other than maybe this database was originally created on another computer and has been copied and pasted.
Finally this is the connection string that the original software used:
"Data Source=.\SQLExpress;AttachDbFilename=C:\blah\blah\blah.mdf;Trust_Connection=Yes;"
I have also tried:
"Data Source=.\SQLExpress;AttachDbFilename=C:\blah\blah\blah.mdf;Trusted_Connection=Yes;User Instance=true"
Finally, this is my exception:
"An attempt to attach an auto-named database for file C:\blah\blah\blah.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."
I got my alternate connection strings from www.connectionstrings.com.
You are missing the Open() command.
con.Open()
Full code listing. (Also a good idea is to wrap your code in a Try.... End Try block).
Private Shared Function GetData(ByVal sqlCommand As String) As DataTable
Dim table As New DataTable()
Dim connectionString As String = "Data Source=.\SQLExpress;Integrated Security=true;" _
& "AttachDbFilename=C:blah\blah\blah.mdf;User Instance=true;"
Using con = New SqlConnection(connectionString)
conn.Open()
Using command = New SqlCommand(sqlCommand, con)
Using da = New SqlDataAdapter(command)
da.Fill(table)
End Using
End Using
End Using
Return table
End Function

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

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

Can't open SQLCompact database

I am working with a SQL compact database and I am able to test the connection when I import it and copy the exact file path to my code, but it still says that it hasn't been opened. What am I doing wrong? Are there any shortcuts available if I have already added the database to my project?
Thanks!
Imports System.Data.SqlServerCe
Module Module1
Sub Main()
Dim constring As String = "Data Source=C:\Users\test\Desktop\MyDatabase1.sdf"
Dim conn As New SqlCeConnection(constring)
Dim cmd As New SqlCeCommand("SELECT * FROM ACCOUNT")
conn.Open()
Dim reader As SqlCeDataReader = cmd.ExecuteReader()
While reader.Read()
Console.WriteLine(reader)
End While
End Sub
End Module
You need to assign the connection to the command:
Immediately after this line:
conn.Open()
add:
cmd.Connection = conn
Alternatively, you can add the connection to the command's constructor:
Dim cmd As New SqlCeCommand("SELECT * FROM ACCOUNT", conn)
One of the main advantage of using SQL server CE (3.5) is to have Linq to SQL. You should make use of strongly typed database, and of DataContext. if you do so, then creating a new DataContext is ONE line of code, not 8. And if your DataBase file does not exist, the CreateDataTable method of your DataContext will create them for you. Dig a little into this, because using SQL Server CE like an old fashion OLEDB data provider is... well... not optimal :-)