vb.net SQL connection string, writing only last value in database - sql-server

Probably a very easy question, but i am having some problems with it.
Currently I am extracting data from OLAP Sever and writing it to SQL Database. I created my database with the below string.
Dim strSQL As String =
"CREATE TABLE Datab(" &
"ID Int IDENTITY(1,1) PRIMARY KEY," &
"No Int NOT NULL," &
"Name NVarChar(40) NOT NULL," &
"basicvalue NVarChar(40) NOT NULL," &
"Datee Date NOT NULL," &
")"
My connection is as follows:
Dim dbConnection As New SqlConnection(connectionString)
'A SqlCommand object is used to execute the SQL commands.
Dim cmd As New SqlCommand(strSQL, dbConnection)
Dim regDate As DateTime = DateTime.Now
Dim strDate As String = regDate.ToString("yyyy-MM-dd")
If IsError(mdsRet) = vbTrue Then
MsgBox("Error Connecting: " & IsError(MdsGetLastError))
Else
' MsgBox("Connected to Server: " + mdsRet)
'Check the number of Cubes in OLAP
If tables.TablesCount(srv) >= 0 Then
dbConnection.Open()
'Counter from 1 to nu. of Cubes
cmd1.CommandType = System.Data.CommandType.Text
For counter As Integer = 1 To tables.TablesCount(srv)
cmd1.CommandText = "INSERT INTO Datab(No, Name, basicvalue,datee) VALUES ('" & counter & "','" + tables.TablesName(srv, counter) + "','" & tables.TableGetInfo(srv, tables.TablesName(srv, counter), 56) & "','" & strDate & "')"
cmd1.Connection = dbConnection
cmd.ExecuteNonQuery()
cmd1.ExecuteNonQuery()
counter = counter + 1
Next
End If
End If
'close DB connection
dbConnection.Close()
The connection writes the line into database, but not incrementing the index Row and so I am getting the last value in database table i.e. after execution is finished..
in total there are about 60 rows to be written.
I tried different options to increment the counter, but its not working. Can anyone help and explain.
Thank you

I figured it out, such a fool of me..
At every execution it was executing the create query that means it was deleting the table and creating new.
I deleted the row cmd.ExecuteNonQuery() from the loop and added it before the loop execution. It worked perfectly.
Although thanks #Jinx88909

Related

VBA - Running an Insert Statement is returning rowsAffected = 1 but isn't actually inserting any rows into table. Statement works fine in SQL Server

Problem: Insert statements run through VBA are returning rowsAffected = 1, however when a select statement is run on that table, it does not show any new rows. Running the exact same insert statement through SQL Server works as intended, so I know it isn't the statement itself that is the issue.
I have created a spreadsheet in which my colleagues can input some data into columns and my VBA will determine what data needs to be updated into our server. I am having trouble with INSERT statements, however my UPDATE statements are working just fine.
Below is the code I am running. It runs an UPDATE query first, and if rowsAffected returns 0, then it instead grabs the corresponding INSERT statement and attempts to run that. Prior to this subroutine running, I have another sub that creates all the UPDATE queries and all of the INSERT queries and stores them in collections which are passed to the below subroutine.
Private Sub sqlQueryNotes(queries As Collection, iQueries As Collection)
'queries collection stores all of the UPDATE queries
'iQueries collection stores all of the INSERT queries
Dim rAffected As Integer
Dim cn As Adodb.Connection
Set cn = New Adodb.Connection
Dim cString As String
cString = "Provider=MSOLEDBSQL;" & _
"Server=[SERVERNAME];" & _
"Database=[DATABASENAME];" & _
"Trusted_Connection=yes;"
cn.connectionString = cString
cn.Open
Dim i As Integer
For i = 1 To queries.Count
cn.Execute "Begin Tran " & queries.Item(i), rAffected 'UPDATE statement
If rAffected = 0 Then
'below code looks a bit messy but it works, it finds the contractID from the update query and uses that as a key for the insertQuery key to find the corresponding insert query. It could be done better, but it works
cn.Execute "Begin Tran " & iQueries.Item(getContractID(queries.Item(i))), rAffected
If rAffected > 1 Then
cn.Execute "Rollback"
GoTo NextQuery
ElseIf rAffected = 0 Then
GoTo NextQuery
Else
cn.Execute "Commit"
GoTo NextQuery
End If
ElseIf rAffected = 1 Then
cn.Execute "Commit "
End If
NextQuery:
Next i
cn.Close
Set cn = Nothing
End Sub
I have tested this dozens of times, each time individually stepping through each line and checking the rowsAffected variable manually confirming that it has in fact inserted the data I want (by returning the value 1). This code DOES work exactly the way as intended, and I do in fact get rowsAffected = 1 when I run the INSERT statements.
However, when I run a SELECT statement for the table it is inserting into, it returns no new rows!
I have taken the INSERT statements generated with my VBA code and have run them through SQL Server and they work fine. So why won't it work through my VBA code?
In case it is relevant, below is the code I run to generate the UPDATE statements and the INSERT statements. I have removed quite a few irrelevant lines for the sake of brevity
Sub UpdateBackendDatabase()
Dim ws As Worksheet
Dim updNoteCol As Integer: updNoteCol = Range("_" & Replace(Left(ws.Name, 6), " ", vbNullString) & "_uNotes").Column
Dim refNoteCol As Integer: refNoteCol = updNoteCol - 1
Dim contractIdCol As Integer: contractIdCol = Range("_" & Replace(Left(ws.Name, 6), " ", vbNullString) & "_contractId").Column
Dim contractID As String
Dim tbl As Range
Set tbl = ws.Range("tblReporting_" & Replace(Left(ws.Name, 6), " ", vbNullString))
Dim notesQueriesColl As New Collection
Dim insCollection As New Collection
Dim updateQry As String
Dim insertQry As String
'Loop through all rows in table and find values that have been updates and add them to a query and add the queries to a collection of queries.
Dim i As Integer
For i = 3 To Range("tblReporting_" & Replace(Left(ws.Name, 6), " ", vbNullString)).Rows.Count + 2
contractID = tbl.Cells(i, contractIdCol).Value
'===============
'==== NOTES ====
'===============
If tbl.Cells(i, updNoteCol).Value <> vbNullString Then
'grabs notes from the refNoteCol and concats it with new additional notes from the updNotesCol
updateQry = "Update tblCMNotes " & _
"Set strNotes = '" & tbl.Cells(i, refNoteCol) & "; " & Format(Date, "dd/mm/yyyy") & " - " & tbl.Cells(i, updNoteCol).Value & "' " & _
"Where fkidContract = " & CStr(contractID)
insertQry = "Insert Into tblCMNotes " & _
"(fkidContract, strNotes) " & _
"Values " & _
"(" & contractID & ", '" & tbl.Cells(i, refNoteCol) & "; " & Format(Date, "dd/mm/yyyy") & " - " & tbl.Cells(i, updNoteCol).Value & "') "
notesQueriesColl.Add updateQry
insCollection.Add insertQry, getContractID(updateQry)
End If
Next i
Set ws = Nothing
End Sub
Thank you very much for looking into this question.
The provider-specific command text "Commit" or "Commit " are SQL server commands. You probably should be using the ADODB method committran

vb.net insert statement : sql Error converting data type varchar to numeric

I am trying to insert data from vb.net into a SQL Server database.
My table :
CREATE TABLE [dbo].[gsb_dtab]
(
[gsb_sno] [int] IDENTITY(1,1) NOT NULL,
[gsb_date] [date] NOT NULL,
[gsb_quality] [nchar](20) NOT NULL,
[gsb_stype] [nchar](1) NOT NULL,
[gsb_taka] [int] NULL
)
VB.NET code:
cmd.CommandText = "INSERT INTO gsb_dtab (gsb_date, gsb_quality, gsb_taka)
VALUES('" + out_date + "','" + se_qcombo.Text + "','" + txt_taka.Text + "');"
The values I want to store are :
out_date = 2020-05-03
se_qcombo = Ranial
txt_taka = 48
but SQL Server throws an error:
Error converting data type varchar to numeric
The error happens in txt_taka insert; when I ignore txt_taka, then data is inserted successfully.
I am using SQL Server 2008 R2 and vb.net 2010
Please help - what can I do ?
Do not concatenate strings to build .CommandText. You will be open to sql injection and you .CommandText is much harder to read and maintain.
The Using...End Using block ensures that you connection and command are closed and disposed even it there is an error.
Private Sub InsertSomething(out_date As Date)
Dim sqlString = "INSERT INTO gsb_dtab (gsb_date, gsb_quality, gsb_taka)
VALUES(#Date, #seq, #taka);"
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand(sqlString, cn)
cmd.Parameters.Add("#Date", SqlDbType.Date).Value = out_date
cmd.Parameters.Add("#seq", SqlDbType.NVarChar, 20).Value = se_qcombo.Text
cmd.Parameters.Add("#taka", SqlDbType.Int).Value = CInt(txt_taka.Text)
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
Put strings in apostrophes, but don't do it with numbers. The format of date values should be "'yyyy-MM-dd'" or 'yyyy-MM-dd HH:mm:ss'. Also use "&" for string concatenation, because "+" could lead to weird errors. And the semicolon at the end isn't needed. So the code could look like:
Dim SQL As String = "INSERT INTO gsb_dtab (gsb_date, gsb_quality, gsb_taka) " &
"VALUES(" & Strings.Format(out_date, "\'yyyy-MM-dd\'") &
", '" & se_qcombo.Text & "', " & txt_taka.Text & ")"
cmd.CommandText = SQL
Please use below code.
cmd.CommandText = "INSERT INTO gsb_dtab (gsb_date, gsb_quality, gsb_taka)
VALUES('" + out_date + "','" + se_qcombo.Text + "','" + Convert.toInt32(txt_taka.Text) + "');"
you need to convert the int value.

Deleting Records in SQL server table prior to insert

I have a excel workbook that is a project plan template, that the PM fills in information and it gets loaded into a sql database. Currently the process if via a batch process that loads two tables(1 with 1 row of data and the other with multiple records). I am changing it to be a direct insert from excel into sql server via vba. I have the insert working but each table has a project id column which is the PK. The pm may update and save this file multiple times. The tables get updated with the most recent save information. I have solved this by adding a delete statement into my code and then inserting the updated record. This works great for the table with 1 record but I can't get the table with multiple records to work. It deletes the records and goes through the first loop of the insert but then goes back to the delete and removes the records.
I have attached the code for the multiple table delete and insert. Can someone tell me what I am doing wrong?
Public Sub exportprojdetaildata()
Dim stSQL As String
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strConn As String
Dim iRowNo As Integer
Dim targetedFieldNames As Variant
Dim rowData As Variant
Dim lastrow As Long
Dim sql As String
Dim i As Integer
Dim cvt As Double
Dim aField As String
Dim compare As Variant
Dim value As Variant
Dim dvalue As Long
With Sheets("Data")
lastrow = .Range("A:A").Find(what:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row
'Open a connection to SQL Server
conn.Open _
"Provider=SQLOLEDB;Data Source=PWIRTPAUDD1HV8;Initial Catalog=STAR;User Id=STAR_USER;Password=dcistarrtp"
'Skip the header row
iRowNo = 2
targetedFieldNames = Join(WorksheetFunction.Transpose(wks_TargetFieldNames.Range("targetedFieldNames").value), "," & vbNewLine)
Do While iRowNo <= lastrow
rowData = wks_BackgroundData.Range("A" & iRowNo & ":AV" & iRowNo).value
compare = wks_BackgroundData.Range("AV2").value
'Generate and execute sql statement to import the excel rows to SQL Server table
With rs
.ActiveConnection = conn
.Open "Select proj_id from dbo.STAR_DC_INITIAL_ProjectDetails_ExcelDevCopy where proj_id = " & compare
wks_BackgroundData.Range("BA2").CopyFromRecordset rs
.Close
End With
value = wks_BackgroundData.Range("BA2").value
If compare = value Then
sql = "delete from dbo.STAR_DC_INITIAL_ProjectDetails_ExcelDevCopy where proj_id = " & value
conn.Execute sql
Else
sql = "insert into dbo.STAR_DC_INITIAL_ProjectDetails_ExcelDevCopy ("
sql = sql & targetedFieldNames
' Debug.Print sql
sql = sql & ") values (" & vbNewLine
' Debug.Print sql
'couldn't do transpose since rowData represents a row, not a column
For i = 1 To UBound(rowData, 2)
aField = Replace(rowData(1, i), "'", "''")
'escape single quotes
Select Case i
Case 1, 6, 16, 17, 23 To 47
' cvt = CDbl(aField)
If aField = vbNullString Then
sql = sql & "Null," & vbNewLine
Else
sql = sql & aField & "," & vbNewLine
End If
Case 2 To 5, 7 To 15, 18 To 22
sql = sql & "'" & aField & "', " & vbNewLine
Case 48
If aField = vbNullString Then
sql = sql & "Null"
Else
sql = sql & aField
End If
End Select
Next i
sql = sql & ");"
'sql = sql & "');"
' End If
conn.Execute sql
iRowNo = iRowNo + 1
Loop
End If
conn.Close
Set conn = Nothing
End With
End Sub
It's difficult to be sure without seeing the data that you're trying to save, but I suspect you have a logic error.
The value for rowData is built up dynamically in a loop. which is correct.
rowData = wks_BackgroundData.Range("A" & iRowNo & ":AV" & iRowNo).value
but the values for compare and value are always read from the same location inside the loop. So the delete statement will be executed over and over again.
compare = wks_BackgroundData.Range("AV2").value
value = wks_BackgroundData.Range("BA2").value
Should compare and value not also be read dynamically?
compare = wks_BackgroundData.Range("AV" & iRowNo).value
value = wks_BackgroundData.Range("BA" & iRowNo).value
Or
you should move the delete statement outside of the loop, to ensure that it's only executed once
Or
you should keep a flag that will indicate that the delete has already been executed, and not execute it again.
hasExecuted = false <- OUTSIDE THE LOOP
...
...
If compare = value and hasExecuted = false Then
sql = "delete from dbo.STAR_DC_INITIAL_ProjectDetails_ExcelDevCopy where proj_id = " & value
conn.Execute sql
hasExecuted = true
...
...
Also, I don't think you should have a IF x=y THEN delete ELSE INSERT. Should it not be IF x=y THEN delete, and always INSERT. With the else, it will only insert if the record didn't exist, but if it deleted the record, it will never insert the new one.
Hope that helps a bit
Avoid using VBA for new development work. If you need to constantly take this Excel document and insert it into a SQL Server database, then use SSIS and some C# to easily make it a scheduled task via the SQL Agent, or simply do as the screen shot below suggests, which is a no-code and easily configurable import of flat files / database tables into SQL Server. Lastly, from a usability standpoint, There are many better methods to track Excel sheets or forms data (SharePoint, Excel 2013, Access, cloud/on premise drives) or using an internal WordPress distribution with some plugins like WP-document revisions.
As noted above I used Spock addition of dynamic lookup of values for the compare and value variable. Once I did that I added the hasExecuted flag.
Public Sub exportprojinfodata()
Dim stSQL As String
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strConn As String
Dim iRowNo As Integer
Dim targetFieldNames As Variant
Dim rowData As Variant
Dim lastrow As Long
Dim sql As String
Dim i As Integer
Dim aField As String
Dim compare As Variant
Dim value As Variant
Dim hasExecuted As String
hasExecuted = False
With Sheets("Data2")
lastrow = .Range("A:A").Find(what:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row
'Open a connection to SQL Server
conn.Open _
"Provider=SQLOLEDB;Data Source=PWIRTPAUDD1HV8;Initial Catalog=STAR;User Id=STAR_USER;Password=dcistarrtp"
'Skip the header row
iRowNo = 2
targetFieldNames = Join(WorksheetFunction.Transpose(wks_TargetFieldNames.Range("TargetFieldNames").value), "," & vbNewLine)
Do While iRowNo <= lastrow
rowData = wks_ProjDescription.Range("A" & iRowNo & ":AO" & iRowNo).value
compare = wks_ProjDescription.Range("B"& iRowNo).value
'Generate and execute sql statement to import the excel rows to SQL Server table
With rs
.ActiveConnection = conn
.Open "Select proj_id from dbo.STAR_DC_INITIAL_ProjectInfo_ExcelDevCopy where proj_id= " & compare
wks_ProjDescription.Range("AX2").CopyFromRecordset rs
.Close
End With
value = wks_ProjDescription.Range("AX"& iRowNo).value
If compare = value And hasExecuted = False Then
stSQL = "delete from dbo.STAR_DC_INITIAL_ProjectInfo_ExcelDevCopy where proj_id = " & value
conn.Execute stSQL
hasExecuted = True
End If
sql = "insert into dbo.STAR_DC_INITIAL_ProjectInfo_ExcelDevCopy ("
sql = sql & targetFieldNames
sql = sql & ") values (" & vbNewLine
'
'couldn't do transpose since rowData represents a row, not a column
For i = 1 To UBound(rowData, 2)
aField = Replace(rowData(1, i), "'", "''")
Select Case i
Case 1 To 40
sql = sql & "'" & aField & "', " & vbNewLine
Case 41
If aField Like "*,*" Then
sql = sql & "'" & """" & aField & """" & vbNewLine
Else
sql = sql & "'" & aField & "' " & vbNewLine
End If
End Select
Next i
sql = sql & ");"
' sql = sql & "');"
conn.Execute sql
iRowNo = iRowNo + 1
Loop
conn.Close
Set conn = Nothing
End With
End Sub

Why is this SQLite query slow and getting slower?

I have a long term data logging service which produces files containing one day worth of data each. I'm loading the files into an SQLite DB in a Windows forms application. The procedure to insert the data from the file into the DB includes two queries, the result of which is used in the subsequent insert.
Using SQLconnect As New SQLite.SQLiteConnection("Data Source=" & fn & ";")
SQLconnect.Open()
Using SQLcommand As SQLite.SQLiteCommand = SQLconnect.CreateCommand
Dim SqlTrans As System.Data.SQLite.SQLiteTransaction = SQLconnect.BeginTransaction
For Each Path As String In paths
fs = System.IO.File.Open(Path, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read) 'Open file
Do While ReadFromStoreFile(fs, dt, Sent) = True 'Read a Timestamp/sentence pair
'Create a positions table for this MMSI if one doesn't already exist
SQLcommand.CommandText = "CREATE TABLE IF NOT EXISTS MMSI" & msg.MMSI & " (PosID INTEGER PRIMARY KEY AUTOINCREMENT, Date NUMERIC, Lat REAL, Lon REAL, Status INTEGER, SOG REAL, COG INTEGER, HDG INTEGER, VoyageID INTEGER);"
SQLcommand.ExecuteNonQuery()
Select Case msg.Type 'Dynamic position report
Case AIS.MsgType.PosRptClsA
'###THIS QUERY TAKES 20 secs per file (day) and increases 3 seconds per day!
SQLcommand.CommandText = "SELECT * FROM Voyages WHERE MMSI = " & msg.MMSI & " ORDER BY VoyageID DESC LIMIT 1" 'still the same
SQLreader = SQLcommand.ExecuteReader()
SQLreader.Read()
VID = SQLreader.Item(0)
SQLreader.Close()
SQLcommand.CommandText = "INSERT INTO MMSI" & msg.MMSI & " (Date, Lat, Lon, Status, SOG, COG, HDG, VoyageID) VALUES (" & ts & ", " & msg.Latitude & ", " & msg.Longitude & ", " & msg.NavStatus & ", " & SOG & ", " & COG & ", " & HDG & ", " & VID & ")"
SQLcommand.ExecuteNonQuery()
SQLreader.Close()
Case AIS.MsgType.StatAndVge
'Find the latest entry for this MMSI in the Voyages table
'###THIS QUERY takes 3 secs for same number of queries and does NOT increase
SQLcommand.CommandText = "SELECT * FROM Voyages WHERE MMSI = " & msg.MMSI & " ORDER BY VoyageID DESC LIMIT 1"
SQLreader = SQLcommand.ExecuteReader()
SQLreader.Read()
Dim NoVoyage As Boolean = Not (SQLreader.HasRows)
If Not NoVoyage Then
'If the data has changed, add a new entry
If Not (SQLreader.Item(2) = msg.Length) Then Changed = True
If Not (SQLreader.Item(3) = msg.Breadth) Then Changed = True
If Not (SQLreader.Item(4) = msg.Draught) Then Changed = True
If Not (SQLreader.Item(5) = msg.Destination) Then Changed = True
If Not (SQLreader.Item(6) = msg.ETA.Ticks) Then Changed = True
VoyageID = SQLreader.Item(0)
End If
SQLreader.Close()
If Changed Or NoVoyage Then
Changed = False 'reset flag
SQLcommand.CommandText = "INSERT INTO Voyages (Date, Length, Breadth, Draught, Destination, ETA, MMSI) VALUES (" & ts & ", " & msg.Length & ", " & msg.Breadth & ", " & msg.Draught & ", '" & msg.Destination.Replace("'", "''") & "', " & msg.ETA.Ticks & ", " & msg.MMSI_int & ")"
SQLcommand.ExecuteNonQuery()
SQLcommand.CommandText = "SELECT last_insert_rowid() FROM Voyages"
SQLreader = SQLcommand.ExecuteReader()
SQLreader.Read()
VoyageID = SQLreader.Item(0)
SQLreader.Close()
End If
End Select 'message type
Loop 'Read next entry from file
fs.Close() 'Close the file
'Write this file into the files table, so we know it has been written to the DB
fileinf = New System.IO.FileInfo(Path)
SQLcommand.CommandText = "INSERT OR REPLACE INTO Files (Name, Size, Date) VALUES ('" & fileinf.Name & "', '" & fileinf.Length & "', '" & fileinf.LastWriteTimeUtc.Ticks & "')"
SQLcommand.ExecuteNonQuery()
Next 'The next path in the list of paths to decode
SqlTrans.Commit() 'End of all files reached, commit all the changes to the DB
End Using 'SQLcommand
End Using 'SQLconnect
As indicated in the code, the first query is taking a very long time and (more importantly) is increasing in duration as data is loaded into the DB. When adding to 21 days of data in the DB, this query alone takes a cumulative time of around 20 secs per day and increases by about 3 secs per day for each day added. The really strange thing is that the second query (which seems identical to me) is fast (around 3 secs for the same number of queries) and is NOT increasing as more data is added.
Here is the function that creates the empty database:
Public Function CreateDB(fn As String, Force As Boolean) As Boolean
If System.IO.File.Exists(fn) Then
If Force Then
System.IO.File.Delete(fn) 'Delete the old DB and create a new one
Else
Return True 'DB alrewady exists so just return true
End If
End If
Using SQLconnect As New SQLite.SQLiteConnection
SQLconnect.ConnectionString = "Data Source=" & fn & ";"
SQLconnect.Open()
'Create Tables
Using SQLcommand As SQLite.SQLiteCommand = SQLconnect.CreateCommand
'Set page size
SQLcommand.CommandText = "PRAGMA Page_size = 4096;"
SQLcommand.ExecuteNonQuery()
'Set journalling mode to off
SQLcommand.CommandText = "PRAGMA journal_mode = OFF;"
SQLcommand.ExecuteNonQuery()
'Set auto indexing off
SQLcommand.CommandText = "PRAGMA automatic_index = false;"
SQLcommand.ExecuteNonQuery()
'Create Vessels Table
SQLcommand.CommandText = "CREATE TABLE Vessels(MMSI TEXT PRIMARY KEY, Name TEXT, Type INTEGER, IMO TEXT, CallSign TEXT, MothershipMMSI INTEGER, LastVoyageID INTEGER);"
SQLcommand.ExecuteNonQuery()
'Create Voyages Table
SQLcommand.CommandText = "CREATE TABLE Voyages(VoyageID INTEGER PRIMARY KEY AUTOINCREMENT, Date NUMERIC, Length INTEGER, Breadth INTEGER, Draught INTEGER, Destination TEXT, ETA NUMERIC, MMSI INTEGER);"
SQLcommand.ExecuteNonQuery()
'Create Meta Table
SQLcommand.CommandText = "CREATE TABLE Files(Name TEXT PRIMARY KEY, Size NUMERIC, Date NUMERIC);"
SQLcommand.ExecuteNonQuery()
End Using 'SQLcommand
End Using ' SQLconnect
Return True
End Function
What could be causing the first query to be so slow, compared to the second query, and take longer as more data is added to the DB?
SQlite and System.Data.Sqlite are the latest versions.
Assuming msg is changed by ReadFromStoreFile, then the query
"SELECT * FROM Voyages WHERE MMSI = " & msg.MMSI & " ORDER BY VoyageID DESC LIMIT 1"
will be slower if there are more voyages for the given MMSI. So I assume the MMSI values that have AIS.MsgType.PosRptClsA are inserted more frequently than the other MMSIs.
It appears the query is getting the maximum voyage id for the MMSI. You could do this more directly with
"SELECT max(VoyageID) FROM Voyages WHERE MMSI = " & msg.MMSI
I don't know if this will run faster.
Alternately, you could keep a dictionary of MMSI and max voyage id and update it when you do an insert into voyage to eliminate the query.

find the duplicate and write it in log file

I have craeted code which reads the acc no, rtn, name and amt from text file and stores in recordset. After that i created sql that stores recordset data into sql server 2005 table.
The problem is In that accno column is primary key. but i have some duplicate accno in my text file. While adding recordset to database, if it finds duplicate accno it is stopping there and not inserting any rows after that duplicate column.
Now i what i want to do is if there is any duplicate column, i want to store that column into log file and skip that column and insert remaining columns into databse. I dont know how to do it. Can anybody help me. like how to check the duplicate column and skip that and insert remaining.
' Write records to Database
frmDNELoad.lblStatus.Caption = "Loading data into database......"
Dim lngRecCount As Long
lngRecCount = 0
rcdDNE.MoveFirst
With cmdCommand
.ActiveConnection = objConn
.CommandText = "insert into t_DATA_DneFrc (RTN, AccountNbr, FirstName, MiddleName, LastName, Amount) values ('" & rcdDNE("RTN") & "', '" & rcdDNE("AccountNbr") & "', '" & rcdDNE("FirstName") & "', '" & rcdDNE("MiddleName") & "', '" & rcdDNE("LastName") & "', '" & rcdDNE("Amount") & "')"
.CommandType = adCmdText
End With
Set rcddnefrc = New ADODB.Recordset
With rcddnefrc
.ActiveConnection = objConn
.Source = "SELECT * FROM T_DATA_DNEFRC"
.CursorType = adOpenDynamic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open
End With
Do Until rcdDNE.EOF
lngRecCount = lngRecCount + 1
frmDNELoad.lblStatus.Caption = "Adding record " & lngRecCount & " of " & rcdDNE.RecordCount & " to database."
frmDNELoad.Refresh
DoEvents
Call CommitNew
rcdDNE.MoveNext
Loop
frmDNELoad.lblStatus.Caption = "DNE Processing Complete."
frmDNELoad.Refresh
End Function
Sub CommitNew()
' Add records to DneFrc table
With rcddnefrc
.Requery
.AddNew
.Fields![RTN] = rcdDNE.Fields![RTN]
.Fields![AccountNbr] = rcdDNE.Fields![AccountNbr]
.Fields![FirstName] = rcdDNE.Fields![FirstName]
.Fields![MiddleName] = rcdDNE.Fields![MiddleName]
.Fields![LastName] = rcdDNE.Fields![LastName]
.Fields![Amount] = rcdDNE.Fields![Amount]
.Update
End With
End Sub
More of a strategy then a specific answer but ...
When importing data from external sources we'll often insert the data into staging tables that do not have the same keys/contraints placed on them and then sanitize the data prior to insertion.
What is done during "sanitation" depends on your requirements (for example, when you have two of the same account numbers are the records the same or are the data fields different, if the fields are different, how do you choose which data to use?). And then insert/move it into the production table once sanitization is complete.
I ran into this problem and what I did is to make a collection that I stored the object and the key into the Key. If I try to add a duplicated key I get an error.
This is the easyest way I found to do this in vb6. in c# is dictionary.
My suggestion would be to add error handling to CommitNew to see if the row inserted would create a primary key violation, and if so then perform other handling.
Example:
Sub CommitNew()
''#Add records to DneFrc table
On Error GoTo CommitNew_Error
With rcddnefrc
.Requery
.AddNew
.Fields![RTN] = rcdDNE.Fields![RTN]
.Fields![AccountNbr] = rcdDNE.Fields![AccountNbr]
.Fields![FirstName] = rcdDNE.Fields![FirstName]
.Fields![MiddleName] = rcdDNE.Fields![MiddleName]
.Fields![LastName] = rcdDNE.Fields![LastName]
.Fields![Amount] = rcdDNE.Fields![Amount]
.Update
End With
Exit Sub ''# If no error, exit routine.
CommitNew_Error:
If Err.Number = -2147217873 Then
''# code here will only execute if the constraint violation occurs
Call WriteDuplicateAccountToFile()
Err.Clear() ''# This clears the error, since you handled it
Else
''# Do stuff with other errors.
''# If you're not sure, at least display what error its giving, like so
MsgBox "The following error was encountered when new record was saved:" & _
vbNewLine & CStr(Err.Number) & " - " & Err.Description & vbNewLine & _
"New record not saved.", vbOkOnly + vbCritical, "Error"
End If
End Sub

Resources