database identity column not working - database

I am creating a database application in vb.net. I have set an identity column(is identity = true) in visual studio. However when I run my application no identity column is recognized. Where am I going wrong?
My connections string is :
"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Administrator\Desktop\SKEDULERING LOCAL DATABASE\SkeduleringLD1.0\SkeduleringLD1.0\Databasis\Skeddatabasis.mdf;Integrated Security=True"
I have set this is the app.config file. I then open the connection with :
Public konneksie As New
SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("konneksie").ConnectionString)
The connection does open. But the identity columns seems to be a problem.

Identity is a reserved word, so you need to call it with [Identity] in your query, or use a different name for that column.
See Reserved Keywords List for more

Here's a general purpose utility method I use...
Assuming you have this declared:
Friend Shared ConnectionString As String = ConfigurationManager.ConnectionStrings("konneksie").ToString
You can pass SQL Query and an instantiated DataTable into this:
Friend Shared Sub LoadData(SQL As String, ByRef TableObject As DataTable, Optional Clear As Boolean = True)
If Clear Then TableObject.Clear()
Using SqlConnection As New SqlClient.SqlConnection(ConnectionString)
With New SqlClient.SqlDataAdapter(SQL, SqlConnection)
.SelectCommand.CommandTimeout = 60
.MissingSchemaAction = Data.MissingSchemaAction.AddWithKey
.FillSchema(TableObject, SchemaType.Source)
.Fill(TableObject)
.Dispose()
End With
End Using
For Each col As DataColumn In TableObject.PrimaryKey
With col
If .AutoIncrement Then
' Always set Step BEFORE Seed
.AutoIncrementStep = -1
.AutoIncrementSeed = -1
End If
End With
Next
End Sub

Related

SQL Server database population pre-existing Data Table and fields (FORM). NO database file

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

How to Insert value to sql server database from data table vb.net

I'm making a application with two database and want to insert my second database table with value from first database table they have same column but on different database. so i make a datatable to populate my data from first database table and try to insert it on my second database
so i make a datatable to populate my data from first database table and try to insert it on my second database using data from datatable but always error cause string value
Dim ds As DataSet = New DataSetMasBrgSpring
Dim dt As DataTable
dt = ds.Tables("DataTable1")
If DataGridView1.Rows.Count > 0 Then
dt.Rows.Clear()
For i = 0 To DataGridView1.Rows.Count - 1
dt.Rows.Add(DataGridView1.Rows(i).Cells(0).Value, etc..
Dim sql1 As String
Dim dataAdapter As New Data.SqlClient.SqlDataAdapter
Dim command As New Data.SqlClient.SqlCommand
command = "insert into MasbrgSpring (KODEC, WIRE, DIMENSION, STD, NOMLOT, STAT) VALUES (#kodec, #wire,#dimension,#std,#nomlot,#stat)"
command.Parameters.Add("#kodec", SqlDbType.VarChar)
etc...
For i As Integer = 0 To DataGridView1.Rows.Count - 1
command.Parameters(0).Value = DataGridView1.Rows(i).Cells(0).Value
command.Parameters(1).Value = DataGridView1.Rows(i).Cells(1).Value
etc...
str.Open()
COMMANDSQL(sql1)
str.Close()
Next
End If
End Sub
this is sub commandsql:
Public Sub COMMANDSQL(ByVal S As String)
sqlcom = New SqlCommand(S, str)
sqlcom.CommandType = CommandType.Text
sqlcom.ExecuteNonQuery()
End Sub
This is the error I get :
value of type string cannot be converted to 'system.data.sqlclient.sqlcommand'
There are many problems in your code. Of course the immediate one that triggers the compilation error is the fact that you use command instead of command.CommandText to assign the query to the command, but there are others.
If DataGridView1.Rows.Count > 0 Then
Dim command As New Data.SqlClient.SqlCommand
command.Text = "insert into MasbrgSpring
(KODEC, WIRE, DIMENSION, STD, NOMLOT, STAT)
VALUES (#kodec, #wire,#dimension,#std,#nomlot,#stat)"
command.Parameters.Add("#kodec", SqlDbType.VarChar)
.... add all the other parameters ....
' Don't forget to set the connection to the command
command.Connection = str
str.Open()
' Now loop over the rows and for each one execute the insert command
For i As Integer = 0 To DataGridView1.Rows.Count - 1
command.Parameters(0).Value = DataGridView1.Rows(i).Cells(0).Value
command.Parameters(1).Value = DataGridView1.Rows(i).Cells(1).Value
.....
command.ExecuteNonQuery()
Next
str.Close()
End If
End Sub
Here I have removed all the stuff about SqlDataAdapter, DataTable and DataSet. They are not needed at all when you execute directly a SqlCommand.
Finally the SqlCommand prepared in the loop is the one to be executed, if you create a new SqlCommand inside that SQLCOMMAND method then you need to give it the same info you have already given to the command used in the loop.
So there is no need also for SQLCOMMAND method but you can directly call ExecuteNonQuery on the prepared SqlCommand.
A final advice. It is a very bad programming practive to have a global SqlConnection object. It keeps resources locked on the client and on the server and if, for any reason, you get an exception, the connection remains open with side effects not immediately obvious when you get problems in other data code blocks.
ADO.NET has a Connection Pooling functionality far more advanced than the one you are trying to re-create keeping a global connection object. Instead use the Using statement around your Sql commands
Using sqlCon = New SqlConnection(......)
If DataGridView1.Rows.Count > 0 Then
Dim command As New Data.SqlClient.SqlCommand
command.Connection = sqlCon
..... the previous code....
End If
End Using
The using statement will help you to close and dispose the connection, while the connection pooling removes the overhead required to reconnect to the same database with the same connection string.
It's probably this line:
command = "insert into MasbrgSpring (KODEC, WIRE, DIMENSION, STD, NOMLOT, STAT) VALUES (#kodec, #wire,#dimension,#std,#nomlot,#stat)"
I think you mean:
command.CommandText = "insert into MasbrgSpring (KODEC, WIRE, DIMENSION, STD, NOMLOT, STAT) VALUES (#kodec, #wire,#dimension,#std,#nomlot,#stat)"

How to change database for linked tables in Access MDB

I have many Access database files that contain linked tables to a SQLServer database. Now the database server has changed and I have to edit the links, possibly without recreating them.
it's possible to do it? I use Access 2013.
Yes it is possible to do with VBA but the way you'll do it really depends on how you linked the tables.
Here are 2 example of connection strings I use for SQL server tables
Direct connection:
Driver=SQL Server Native Client 10.0;Server=server_name;Address=server_address,1433;Network=network_name;Database=database_name;Trusted_Connection=Yes
DSN connection (with an entry in the ODBC control panel)
ODBC;Provider=SQLNCLI10;Server=server_name;DSN=name_of_DSN_entry_in_ODBC_control_panel;Database=database_name;Trusted_Connection=Yes
So the first thing to do is to determine how your tables are linked.
You can use this code (pay attention to the comments):
Public Sub Check_ODBC_tables()
Dim tdef As TableDef
' First loop on all tables to determine the connection strings
For Each tdef In CurrentDb.TableDefs
' only print the constring if the database name is your old database (adapt accordingly)
If InStr(tdef.Connect, "Database=old_database_name") Then
Debug.Print tdef.Connect
End If
Next
End Sub
Run this code (F5) and check the output in the immediate window. You'll find how the table are linked and what are the connection strings.
You should prepare a connection string based on that, and adapt in them the database name to use your new DB.
Once you are ready, you can adapt and run the following code that will delete the old table and recreate them with the new database names (some tweaks might be necessary), so go thought it in debug mode !
Public Sub Change_ODBC_tables()
Dim tDef As TableDef
Dim tDefNew As TableDef
Dim strTable As String
Dim strCOnString As String
' examples of constrings - ADAPT!!!!
strCOnString = "Driver=SQL Server Native Client 10.0;Server=server_name;Address=server_address,1433;Network=network_name;Database=database_name;Trusted_Connection=Yes"
strCOnString = "ODBC;Provider=SQLNCLI10;Server=server_name;DSN=name_of_DSN_entry_in_ODBC_control_panel;Database=database_name;Trusted_Connection=Yes"
For Each tDef In CurrentDb.TableDefs
If InStr(tDef.Connect, "Database=old_database_name") Then
' We find a match, store the table name
strTable = tDef.Name
' delete the linked table
DoCmd.DeleteObject acTable, strTable
' recreate the linked table with new DB name
Set tDef2 = CurrentDB.CreateTableDef(strTable)
tDef2.Connect = strCOnString
tDef2.SourceTableName = strTable
tDef2.Name = strTable
CurrentDb.TableDefs.Append tDef2
End If
Next
End Sub
If you don't fully understand the second piece of code I posted, I urge you to backup your mdb prior to run it because it will delete objects which can cause serious issues.

Creating an imports program to clear a database and migrate new data

Over the last few days, I was asked to move a company program over from an Access back-end, to SQL Server.
There are 2 copies of the program, the live data version, on the server, and the local version on my PCs C: Drive, to ensure if I make a mistake, it doesn't affect the live data.
So, I managed to migrate the Access database, tables and data over to SQL Server 2008, and the local version of the program now works.
The easiest way, or so I'm informed, to now do the same to the live version of the program, is to write an imports program, which wipes all of the data from each table in the SQL Server database, and then copies over the data from the live Access database. However, I've never done this before, so I'm not really even sure where to begin.
Could anybody point me in the right direction on how to begin or do this, so that I only have to change the connection path in the program, rather than go through the whole process again?
PS, I work in vb.net, so that's the language I would need any responses in!
Thanks.
Usually one uses the SQL Server Import and Export Wizard for this.
It's a separate tool that is installed with SQL Server Management Studio (SSMS).
ANSWER
Step 1;
I added a new path to the ini file for the database to read. This connected to the live database. Once this connection is open in the project, proceed to step 2.
Step 2;
Create a new class, where the imports and exports will happen.
Step 3;
Put a button, or some sort of control in the program to initiate the import/export. For example, I had a button which, when clicked, asked the user to confirm that they wanted to import a new database and overwrite the existing one. If yes, call the function which does this, in the newly made imports class.
Step 4;
Now that you know how to get this set up, the code would be something like
Public Function importdatabase(/connections go in here/)
Declare transaction
Create sql variable
Try
Begin the transaction here
sql to delete the data from one table
sql to select all data from database that is being imported
For loop to iterate over each record in the database table
Declare a variable for each field in the database
variable1 = ("fieldname1")
variable2 = ("fieldname2")
sql statement to insert the new values
call to the function which runs the sql query
Next
commit transaction
Catch ex As Exception
Throw
End Try
Step 5; Repeat the delete/insert process for each database table
Below this, I have other functions.
One function created a new datatable, this is referenced as
For each dr as datarow in /functionname(parameters).Rows
Next one is to execute the sql statement (not required, any command to execute it will do)
Next one is used for parameterising my SQL query
The rest are to replace null values in the database with empty strings, set dates, etc
You can use the following class to import table(s) in access to sql server.
You need:
- The connection string of the source (including access file name) and the target one.
- The Source Table ,target tatble (if null it is the same as the source table)
Class ImportHelper
'modify connectionstring as needed
Public Property SourceConnectionString() As String
Get
Return m_SourceConnectionString
End Get
Set
m_SourceConnectionString = Value
End Set
End Property
Private m_SourceConnectionString As String
Public Property DestinationConnectionString() As String
Get
Return m_DestinationConnectionString
End Get
Set
m_DestinationConnectionString = Value
End Set
End Property
Private m_DestinationConnectionString As String
Public Sub New(sourceConnectionString__1 As String, destinationConnectionString__2 As String)
SourceConnectionString = sourceConnectionString__1
DestinationConnectionString = destinationConnectionString__2
End Sub
Public Sub Import(sourceTable As String, Optional targetTable As String = Nothing)
Using sourceConnection = New OleDbConnection(SourceConnectionString)
If String.IsNullOrEmpty(targetTable) Then
targetTable = sourceTable
End If
sourceConnection.Open()
' Perform an initial count on the destination table.
Dim commandRowCount = New OleDbCommand(Convert.ToString("SELECT COUNT(*) FROM ") & sourceTable, sourceConnection)
Dim countStart As Long = Convert.ToInt32(commandRowCount.ExecuteScalar())
Console.WriteLine("Source Table [{0}] has {1} rows", sourceTable, countStart)
' Get data from the source table
Dim commandSourceData = New OleDbCommand(Convert.ToString("SELECT * FROM ") & sourceTable, sourceConnection)
Dim reader = commandSourceData.ExecuteReader()
'---------------
Using destinationConnection As New SqlConnection(DestinationConnectionString)
destinationConnection.Open()
Using bulkCopy As New SqlBulkCopy(destinationConnection)
bulkCopy.DestinationTableName = targetTable
Try
' Write from the source to the destination.
bulkCopy.WriteToServer(reader)
Console.WriteLine(Convert.ToString("Sucess Importing ") & sourceTable)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
reader.Close()
End Try
'using
End Using
'using
End Using
End Using
'using
End Sub
End Class
How to use:
Private Sub Test()
'modify connectionstring as needed
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=; //access 97..2000
Dim SourceConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\temp\database1.accdb;Persist Security Info=False;"
Dim DestinationConnectionString As String = "Data Source=xxxx;Initial Catalog=test;user=xxx;password=xxx;"
New ImportHelper(SourceConnectionString, DestinationConnectionString).Import("table1", "test1")
End Sub

SQL Server CE - Problems updating table

I'm sure my question has been answered many times on the internet, but I couldn't find exactly what I was looking for.
I'm working on VB.NET and my database is a SQL Server Compact .SDF file. The following is my method of opening the database.
Private Shared Sub OpenDatabase(ByVal tablename As String)
If _DBLoaded Then Return
'// open database connection
conn = New SqlCeConnection("Data Source = giadatabase.sdf")
conn.Open()
'// create command for making extracting data
cmd = conn.CreateCommand
cmd.CommandText = "SELECT * FROM [" & tablename & "]"
'// setup database adapter
da = New SqlCeDataAdapter(cmd)
'// create command for inserting/updating database
cb = New SqlCeCommandBuilder(da)
'// load dataset
ds = New DataSet()
da.Fill(ds)
'// get the relevant table
dt = ds.Tables(0)
_DBLoaded = True
End Sub
I run this sub when my application starts. I believe that database needs to be opened just once. Constantly reopening of database will cause performance problems to my application (correct me if I'm wrong).
For loading data in my list object I use the following:
Public Shared Function GetList() As List(Of DatabaseListObject)
OpenDatabase("TestTable")
'// Make a list of items in database
Dim ret As New List(Of DatabaseListObject)
For Each dRow As DataRow In dt.Rows
ret.Add(New DatabaseListObject(dRow("ID"), dRow("LongName"), dRow("ShortName")))
Next
Return ret
End Function
So my GetList function ensures database is already open, and database is always opened once a lifetime of my application. My list object is filled with data from the above function.
This is how I make changes to my database:
Public Shared Function AddItem(LongName As String, ShortName As String) As DatabaseListObject
'// Make changes
Dim row = dt.NewRow()
row("LongName") = TimeOfDay.ToString
row("ShortName") = ShortName
dt.Rows.Add(row)
da.Update(ds, dt.TableName)
Dim newcmd = conn.CreateCommand
newcmd.CommandText = "SELECT ##IDENTITY;"
Dim newID As Integer = newcmd.ExecuteScalar()
Dim item As New DatabaseListObject(newID, LongName, ShortName)
Return item
End Function
Now I assume database is correctly updated from the above code. The ID column in my table is the autonumber. Problem occurs when I call the GetList function after adding a row. System throws error that the newly added row's ID column is NULL. Whereas it should be automatically added number. When I restart the application, i.e. the database is opened from scratch, then the GetList shows the autonumber properly.
Obviously the table's ID column is not getting filled-in with the autonumber when I'm adding a new row. So I need suggestions here. Should I always open the database from scratch whenever I call the GetList (which will be called frequently in my app). If not the entire database then which codes should be called at least to properly refresh the table without causing much performance problems to the application.
SELECT ##IDENTITY will only Work on the same open Connection object, and the DataAdapter opens and Closes its own connection, you must use plain ADO.NET (cmd.ExecuteNonQuery) or implemet extra code as described here: http://blogs.msdn.com/b/bethmassi/archive/2009/09/15/inserting-master-detail-data-into-a-sql-server-compact-edition-database.aspx

Resources