Do columns need to match exactly when using dataadapter.update - vb.net

I'm working on a project to import data from a Microsoft Access database into a blank MS-SQL database. The structure of the table in Access (VM) does not match up exactly with the table in MS-SQL (vlVerticalMarketing).
AccessTable VM SQLTable vlVerticalMarketing
ID (autonumber) VMID (PK, identity)
VM VerticalMarketing
Deleted (required)
Archive (required)
Other non-required fields
I'm filling the Access data into a DataTable DT using the following query:
select VM as VerticalMarketing, 0 as Deleted, 0 as Archive from VM where VM is not null
Then I change the name of the DataTable using:
DT.TableName = "vlVerticalMarketing"
From there, I pass the DataTable into a class function.
Public Function CopyFromDataTable(ByVal sourceDT As DataTable, ByVal TableName As String) As Boolean
Try
OpenDB()
Dim DA As New SqlDataAdapter("select VerticalMarketing, Deleted, Archive from " & TableName, Me.DBConn)
Dim CB = New SqlCommandBuilder(DA)
CB.QuotePrefix = "["
CB.QuoteSuffix = "]"
DA.InsertCommand = CB.GetInsertCommand(True)
Dim destDT = sourceDT.Copy()
DA.Update(destDT)
OpenDB is a class method that I use for other things and I know is good. It sets the connection string and creates DBConn as a SqlConnection object. The rest is standard VB.Net. Everything runs without error. Both sourceDT and destDT have data in them (viewed through the DataSet Visualizer while debugging). The problem is that no data gets passed out to the SQL database.
Any ideas on what I'm doing wrong that is causing the SQL database not to receive the data.

i think the problem is that the rows in destDt don't have RowState.Added when you call Update on the DataAdapter ... you can check the return value of the Update statement ... i guess it will be 0 because no inserts were executed ... you could check this with sql server profiler ...
as a workaround for this you could call DataRow.SetAdded() on the rows in your destDT ...

Related

selecting from one database and inserting row to new database

I'm looking for a pseudo code to write a VB.NET cursor to select columns from one table in one database and inserting it into another table in a different database (they are *not on the same server) using data adapter etc.
I just need something to refer to as I learn. Thanks
Dim selectStr As String = _
"select * from db1"
Dim insertStr As String = _
"insert into db2(col1)"
Try
da_adapter = New OleDb.OleDbDataAdapter(selectStr, connStr)
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
da_adapter.SelectCommand.CommandTimeout = 720
da_adapter.Fill(ds)
da2_adapter.SelectCommand.CommandTimeout = 720
da2_adapter.Fill(ds)
Catch ex As Exception
End Try
In your original code, this part is wrong:
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
When you create a data adapter that way, the SQL statement you provide becomes part of the SelectCommand. You want yours to be part of the InsertCommand, which you need to do yourself:
Dim cmd2 As New OleDb.OleDbCommand(insertStr, connStr2)
da2_adapter = New OleDb.OleDbDataAdapter
da2_adapter.InsertCommand = cmd2
Also, you need to set the AcceptChangesDuringFill property of the first data adapter to False. That way, instead of setting the RowState of all the rows to Unchanged after populating the DataTable, they will remain as Added and ready to be inserted.
You then need to call Update on the second data adapter to save the data rather than calling Fill, which retrieves data.

Using VB.Net to import my CSV file to my Access DB

I am using the below code to import a CSV file to my Access DB. I just have a couple of questions.
Con.Open()
Dim strSqlCommand = "SELECT F1 AS id, F2 AS firstname " &
"INTO MyNewTable " &
"FROM [Text;FMT=Delimited;HDR=No;CharacterSet=850;DATABASE=" & GlobalVariables.strDefaultDownloadPath & "].Airports.csv;"
Dim sqlCommand = New System.Data.OleDb.OleDbCommand(strSqlCommand, Con)
sqlCommand.ExecuteNonQuery()
Con.Close()
How can I change the Character Set to UTF-8? If I enter utf8 instead of 850 I get an error.
Also, the first line of my CSV file contains the column names. Can I amend the above code to take that in to account?
Regards,
Andrew
You could run into trouble trying to import and select all at once, for one thing you may not want to leave converting data types up to Access. For that, you will need 2 connections and SQL string to select from one another to insert into the other.
The connection string will need to look something like this:
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Temp\Tmp;Extended Properties='TEXT;HDR=Yes;FMT=Delimited;CharacterSet=ANSI'"
Note that just the path is listed and the Extended Properties are enclosed in ticks. If the first line has headers/field names then HDR=Yes will skip them in the result set. One of the benefits of having field names as the first line is that OleDB will use them as column names (no need for F1 As foo, F2 As bar; in fact that will fail because they have been renamed from F1, F2...).
The SQL to read from the CSV:
"SELECT * FROM filename.csv"
There are several ways to process it. You could use a reader to read a row at a time to INSERT them into the Access database. This is probably simpler: get all the data from the CSV into a DataTable and use it to INSERT into Access:
Private myDT As DataTable ' form level variable
...
Dim csvStr As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Temp\Tmp;Extended Properties='TEXT;HDR=Yes;FMT=Delimited;CharacterSet=ANSI'"
Dim csvSQL = "SELECT * FROM Capitals.csv" ' use YOUR file name
Using csvCn = New OleDbConnection(csvStr),
cmd As New OleDbCommand(csvSQL, csvCn)
Using da As New OleDbDataAdapter(cmd)
myDT = New DataTable
da.Fill(myDT)
End Using
End Using
For Each r As DataRow In myDT.Rows
'ToDo: INSERT INTO Access
Next
The Connection, Command and DataAdapter are all resources, so they are in USING blocks to dispose of them when we are done with them. myDT will have a collection of Rows, each with a collection of Items representing the fields from the CSV. Just loop thru the rows adding the desired items to the Access DB.
You will very likely have to do same data type conversion from String to Integer or DateTime etc.
As for the question about UTF8 - you can use the Codepage identifier. If you leave it off the connection string it will use whatever is in the Registry which may also work. For UTF8 use CharacterSet=65001.

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

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.

Database connectivity through ADO.Net in VB2010 express

Can anyone give me the source code to add database connectivity in VB2010 express through ADO.Net. Including all the commands to add, update, delete, retrieve and modify the database fields. It would be really helpful if anyone can provide me with a small prototype working model with the source code.
ADO.NET is more or less SQL query based. So for CRUD (Create, Read, Update, Delete) Operations have a look at the SQL-Language (the query syntax might have some smalle differences depending on the database you're using).
The connection uses the specialized provider entities implementing the IDbConnection, IDbCommand, IDbDataAdapter, IDbDataParameter and IDbTransaction Interfaces from the System.Data Namespace.
There are different Database Providers (e.g. Microsoft SQL Server, Oracle, mySQl, OleDb, ODBC etc.). Some of them are natively supported by the .NET Framework (MSSQL=System.Data.SqlClient Namespace, OleDb=System.Data.OleDb, ODBC=System.Data.Odbc Namespace) while others must be added through external libraries (you can also write your own database provider if you like).
With the IDBCommand Objects (e.g. the System.Data.SqlClient.SqlCommand object) you can define your SQL Commands.
Here is a small sample snippet which might help:
Public Class Form1
Sub DBTest()
'** Values to store the database values in
Dim col1 As String = "", col2 As String = ""
'** Open a connection (change the connectionstring to an appropriate value
'** for your database or load it from a config file)
Using conn As New SqlClient.SqlConnection("YourConnectionString")
'** Open the connection
conn.Open()
'** Create a Command object
Using cmd As SqlClient.SqlCommand = conn.CreateCommand()
'** Set the command text (=> SQL Query)
cmd.CommandText = "SELECT ID, Col1, Col2 FROM YourTable WHERE ID = #ID"
'** Add parameters
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = 100 '** Change to variable
'** Execute the value and get the reader object, since we are trying to
'** get a result from the query, for INSERT, UPDATE, DELETE use
'** "ExecuteNonQuery" method which returns an Integer
Using reader As SqlClient.SqlDataReader = cmd.ExecuteReader()
'** Check if the result has returned som results and read the first record
'** If you have multiple records execute the Read() method until it returns false
If reader.HasRows AndAlso reader.Read() Then
'** Read the values of the current columns
col1 = reader("col1")
col2 = reader("col2")
End If
End Using
End Using
Debug.Print("Col1={0},Col2={1}", col1, col2)
'** Close the connection
conn.Close()
End Using
End Sub
End Class