What my program supposed to do : My goal is to create a windows service which acts as a mediator between multiple SQL databases. In total there are 3 different tables in 3 different servers In detail, when this service runs it should oversee the data in the "Table1" and copy it to the "Table2" in periodical time(every 1 minute). But tricky part is it cannot paste duplicate records, has to check for "Table2" 's ID field and validate for not pasting the same record with the same ID.I've added a diagram for understanding purposes of what my goal is
What I've done : So far I've developed the code completely but the issue is it only copies data from one table(specifically "NOR_LABOR" according to the diagram I've attached) to "DEV_Test_Nor_Data" in the "MES_DEV" Database(con1 to con2). According to the diagram con1, con3, con4 are tables "NOR_LABOR", "SETTER_LABOR" and "wrap_labor" respectively. con2 is the destination which is "MES_DEV" DB.
Can anybody figure out why does other table's data(con3 to con2 & con4 to con2) won't copy?
My code - Data Collector
Imports System.Configuration
Imports System.Data.SqlClient
Public Class DataCollector
Dim con1, con2, con3, con4 As New SqlConnection
Dim timer1 As Timers.Timer
Dim p_oConn As New Wisys.AllSystem.ConnectionInfo
Protected Overrides Sub OnStart(ByVal args() As String)
con1 = New SqlConnection("Data Source=NORMAC-CTMS\SQLEXPRESS;Database=Normac Data;Integrated Security=true")
con1.Open()
con2 = New SqlConnection("Data Source=STLEDGSQL01;Database=MES_DEV;Integrated Security=true")
con2.Open()
con3 = New SqlConnection("Data Source=201706-SETTER1\SQLEXPRESS;Database=Edge;Integrated Security=true")
con3.Open()
con4 = New SqlConnection("Data Source=PRINTER\SQLEXPRESS;Database=Wrapper Data;Integrated Security=true")
con4.Open()
timer1 = New Timers.Timer()
timer1.Interval = 5000
AddHandler timer1.Elapsed, AddressOf OnTimedEvent
timer1.Enabled = True
FileIO.WriteLog("Service has started")
End Sub
Protected Overrides Sub OnStop()
timer1.Enabled = False
FileIO.WriteLog("Service has stopped")
con1.Close()
con2.Close()
con3.Close()
con4.Close()
End Sub
Private Sub OnTimedEvent(obj As Object, e As EventArgs)
Dim cmd1, cmd2, cmd3 As SqlCommand
'Connecting the Normac Data table
Dim da1 As SqlDataAdapter = New SqlDataAdapter("select ID, trx_date, work_order, department, work_center, operation_no, operator, total_labor_hours, feet_produced, item_no, posted, labor_feet_produced from NOR_LABOR", con1)
Dim cb1 As SqlCommandBuilder = New SqlCommandBuilder(da1)
Dim dt1 As DataTable = New DataTable()
da1.Fill(dt1)
'Connecting the Setter_Labor table
Dim da2 As SqlDataAdapter = New SqlDataAdapter("select ID, trx_date, work_order, department, work_center, operation_no, operator, total_labor_hours, labor_feet_produced, item_no, posted from Setter_Labor", con3)
Dim cb2 As SqlCommandBuilder = New SqlCommandBuilder(da2)
Dim dt2 As DataTable = New DataTable()
da2.Fill(dt2)
'Connecting the Wrap_Labor table
Dim da3 As SqlDataAdapter = New SqlDataAdapter("select ID, trx_date, work_order, Department, work_center, operation_no, operator, total_labor_hrs, job_start, job_end, qty_ordered, qty_produced, item_no, lot_no, default_bin, posted, wrapped, total_shift_hrs, check_emp, machine, operation_complete from wrap_labor", con4)
Dim cb3 As SqlCommandBuilder = New SqlCommandBuilder(da3)
Dim dt3 As DataTable = New DataTable()
da3.Fill(dt3)
Dim i, j, k As Integer
'Inserting into DEV_Test_Nor_Data table
For Each dr As DataRow In dt1.Rows
cmd1 = New SqlCommand("Insert into DEV_Test_Nor_Data values('" & dr(0) & "','" & dr(1) & "','" & dr(2) & "','" & dr(3) & "','" & dr(4) & "','" & dr(5) & "','" & dr(6) & "','" & dr(7) & "','" & dr(8) & "','" & dr(9) & "','" & dr(10) & "','" & dr(11) & "')", con2)
i = cmd1.ExecuteNonQuery()
Next
'Inserting into DEV_Test_Set_Lbr table
For Each dr As DataRow In dt2.Rows
cmd2 = New SqlCommand("Insert into DEV_Test_Set_Lbr values('" & dr(0) & "','" & dr(1) & "','" & dr(2) & "','" & dr(3) & "','" & dr(4) & "','" & dr(5) & "','" & dr(6) & "','" & dr(7) & "','" & dr(8) & "','" & dr(9) & "','" & dr(10) & "')", con2)
j = cmd2.ExecuteNonQuery()
Next
'Inserting into DEV_Test_Wrp_Lbr table
For Each dr As DataRow In dt3.Rows
cmd3 = New SqlCommand("Insert into DEV_Test_Wrp_Lbr values('" & dr(0) & "','" & dr(1) & "','" & dr(2) & "','" & dr(3) & "','" & dr(4) & "','" & dr(5) & "','" & dr(6) & "','" & dr(7) & "','" & dr(8) & "','" & dr(9) & "','" & dr(10) & "','" & dr(11) & "','" & dr(12) & "','" & dr(13) & "','" & dr(14) & "','" & dr(15) & "','" & dr(16) & "','" & dr(17) & "','" & dr(18) & "','" & dr(19) & "','" & dr(20) & "')", con2)
k = cmd3.ExecuteNonQuery()
Next
da1.Update(dt1)
cmd1.Dispose()
dt1.Dispose()
da1.Dispose()
da2.Update(dt2)
cmd2.Dispose()
dt2.Dispose()
da2.Dispose()
da3.Update(dt3)
cmd3.Dispose()
dt3.Dispose()
da3.Dispose()
End Sub
End Class
Reference2
Reference3
Reference4
See if this helps. It may be the parameterized queries are your entire problem.
Public Class DataCollector
'Question text said one minute
Private timer1 As New Timers.Timer(60000)
Protected Overrides Sub OnStart(ByVal args() As String)
AddHandler timer1.Elapsed, AddressOf OnTimedEvent
timer1.Enabled = True
FileIO.WriteLog("Service has started")
End Sub
Protected Overrides Sub OnStop()
timer1.Enabled = False
FileIO.WriteLog("Service has stopped")
End Sub
Private Sub OnTimedEvent(obj As Object, e As EventArgs)
' DEV_Test_Nor_Data Table
ProcessOneTable("DEV_Test_Nor_Data", 12,
"Data Source=NORMAC-CTMS\SQLEXPRESS;Database=Normac Data;Integrated Security=true",
"SELECT ID, trx_date, work_order, department, work_center, operation_no, operator, total_labor_hours, feet_produced, item_no, posted, labor_feet_produced FROM NOR_LABOR"
)
' DEV_Test_Set_Lbr Table
ProcessOneTable("DEV_Test_Set_Lbr", 11,
"Data Source=201706-SETTER1\SQLEXPRESS;Database=Edge;Integrated Security=true",
"SELECT ID, trx_date, work_order, department, work_center, operation_no, operator, total_labor_hours, labor_feet_produced, item_no, posted from Setter_Labor"
)
' DEV_Test_Wrp_Lbr Table
ProcessOneTable("DEV_Test_Wrp_Lbr", 21,
"Data Source=PRINTER\SQLEXPRESS;Database=Wrapper Data;Integrated Security=true",
"SELECT ID, trx_date, work_order, Department, work_center, operation_no, operator, total_labor_hrs, job_start, job_end, qty_ordered, qty_produced, item_no, lot_no, default_bin, posted, wrapped, total_shift_hrs, check_emp, machine, operation_complete from wrap_labor"
)
End Sub
Private EdgeConnStr As String = "Data Source=STLEDGSQL01;Database=MES_DEV;Integrated Security=true"
Private Sub ProcessOneTable(destTableName As String, ParameterCount As Integer, sourceConnectionString AS String, sourceSql As String)
Dim data As New DataTable()
Using sourceConn As New SqlConnection(sourceConnectionString), _
da As New SqlDataAdapter(sourceSql, sourceConn)
da.Fill(data)
End Using
Dim paramList As String = String.Join(",", Enumerable.Range(0, ParameterCount).Select(Function(p) $"#p{p}"))
' Assumes first parateter (#p0) is always the ID.
Dim sql As String = $"INSERT INTO {destTableName} SELECT {paramList} WHERE NOT EXISTS(SELECT ID FROM {destTableName} WHERE ID = #p0)"
Using cn As New SqlConnection(EdgeConnStr), _
cmd As New SqlCommand(sql, cn)
For i As Integer = 0 To ParameterCount - 1
cmd.Parameters.Add($"#p{i}", SqlDbType.VarChar)
Next i
cn.Open()
For Each dr As DataRow In data.Rows
For i As Integer = 0 to ParameterCount - 1
cmd.Parameters(i).Value = dr(i)
Next i
cmd.ExecuteNonQuery()
Next dr
End Using
End Sub
End Class
It sounds like you also need to worry about merging the data, but start with this anyway; it fixes the HUGE GAPING SECURITY ISSUE in the original code, as well as isolating the important part of the code down to the minimum possible method size. This will make it easier to refactor just that part to also worry about what IDs may already exist... but I'll let you make an attempt at that yourself first (hint: INSERT + SELECT + WHERE NOT EXISTS() all in the same query)
I'm trying to copy a datatable from a vb.net form I've set up into an access database. I'm using a snippet of code (with some alterations) posted by another user (Casbar27, Records added to ms access database with vb 2010 not saving).
Back_EndDataSet.tblTest.Clear()
Dim adapter As New Back_EndDataSetTableAdapters.tblTestTableAdapter
Dim rowCode As DataRow = Back_EndDataSet.tblTest.NewtblTestRefreshxinRow
For Each row As DataRow In source.Rows
adapter.Fill(Back_EndDataSet.tblTest)
rowCode.Item(0) = row.Item(0)
rowCode.Item(1) = row.Item(1)
rowCode.Item(2) = row.Item(2)
rowCode.Item(3) = row.Item(3)
rowCode.Item(4) = row.Item(4)
rowCode.Item(5) = row.Item(5)
rowCode.Item(6) = row.Item(6)
rowCode.Item(7) = row.Item(7)
rowCode.Item(8) = row.Item(8)
rowCode.Item(9) = row.Item(9)
Back_EndDataSet.tblTest.AddtblTestRow(rowCode)
adapter.Update(Back_EndDataSet.tblTest)
Next
While this is working, it's slow and is producing multiples of the same record if it's run several times. I want this to wipe the access table on start and rewrite it, and preferably in under a minute. Any suggestions?
Following #Gord Thompson's suggestion I wrote an OleDbCommand to delete the table, and decided to keep going an rewrote my filling method using an OleDbCommand. It work's great, the completion speed is up and I no longer have duplicate records. Thanks Gord!
Private Sub UpdateDataBase(ByVal source As DataTable)
Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= H:\AppDev\Visual Studio 2010\Projects\RawFixerTest1\Raw Fixer Back End.accdb")
Dim cmdClr As New OleDbCommand
Dim cmdFill As New OleDbCommand
Dim i = 0
con.Open()
cmdClr.CommandText = "DELETE * FROM tblTestRefreshxin"
cmdClr.Connection = con
cmdClr.ExecuteNonQuery()
cmdFill.Connection = con
For Each row As DataRow In source.Rows
cmdFill.CommandText = "INSERT INTO tblTestRefreshxin (numCode, featDesc, alphaCode, clientCode, DTMexclude, attrCode1, attrCode2, attrCode3, attrCode4, lineToPrev) VALUES(" & "'" & row.Item(0) & "','" & row.Item(1) & "','" & row.Item(2) & "','" & row.Item(3) & "','" & row.Item(4) & "','" & row.Item(5) & "','" & row.Item(6) & "','" & row.Item(7) & "','" & row.Item(8) & "','" & row.Item(9) & "')"
cmdFill.ExecuteNonQuery()
Next
con.Close()
End Sub
what am I doing wrong??? I have 7 textbox, 1 datetimepicker and 1 combobox in my form. When I click the save button, It doesn't do nothing, just like a new button without code, not even the customer saved message or error message.
Private Sub btnSaveCust_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveCust.Click
Try
Dim sex As String
sex = ""
If cbSex.SelectedIndex >= 0 Then
sex = cbSex.Items(cbSex.SelectedValue).ToString
End If
Dim conex As New SqlConnection("Data Source=localhost;Initial Catalog=BD_;Integrated Security=True")
Dim query As String = "SELECT * FROM tableCustomer WHERE ID=#ID"
Dim cmd1 As SqlCommand = New SqlCommand(query, conex)
cmd1.Parameters.AddWithValue("#ID", txtID.Text)
cmd1.Parameters.AddWithValue("#[Today date]", txtToday.Text)
cmd1.Parameters.AddWithValue("#Name", txtName.Text)
cmd1.Parameters.AddWithValue("#Middlename", txtMiddle.Text)
cmd1.Parameters.AddWithValue("#[Last name]", txtLastName.Text)
cmd1.Parameters.AddWithValue("#Birth", DateTimePickerBirth.Value)
cmd1.Parameters.AddWithValue("#Age", txtAge.Text)
cmd1.Parameters.AddWithValue("#Sex", cbSex.SelectedValue)
cmd1.Parameters.AddWithValue("#Phone", txtPhone.Text)
cmd1.Parameters.AddWithValue("#E-mail", txtEmail.Text)
conex.Open()
Using read As SqlDataReader = cmd1.ExecuteReader()
If read.HasRows Then
MsgBox("ID '" & txtID.Text & "' already in DB. Enter another ID", MessageBoxIcon.Error)
txtID.Focus()
Else
read.Close()
Dim cmd As SqlCommand = New SqlCommand _
("Insert into [BD_].[dbo].[tableCustomer] ([ID],[Today date],[Name],[Middlename],[Last name],[Birth],[Age],[Sex],[Phone],[E-mail]) values ('" + txtID.Text + "','" + txtToday.Text + "','" + txtName.Text + "','" + txtMiddle.Text + "','" + txtLastName.Text + "','" + DateTimePickerBirth.ToString("dd MM yyyy") + "','" + txtAge.Text + "','" + sex + "','" + txtPhone.Text + "','" + txtEmail.Text + "')", conex)
conex.Open()
cmd.ExecuteNonQuery()
MsgBox("Customer '" & txtName.Text & "' saved.", MessageBoxIcon.Information)
conex.Close()
End If
End Using
Catch ex As Exception
End Try
End Sub
If you have access to the SQL profiler (in SQL Server) you can catch the SQL being sent from your app, copy, paste and run that directly in SQL Server query window and you should see any errors... Alternatively, add your data using a Stored Procedure, you'll find it is a lot easier to get working...
I tried out to connect my database(ms-access) to Visual basic.But it came up with the following error:
A first chance exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: Syntax error in INSERT INTO statement.
If there is a handler for this exception, the program may be safely continued.
I used the following code.please see if there is any error..please help me out for it..
The Code is:
Private Sub frmGive_Load(sender As Object, e As EventArgs) Handles Me.Load
con = New OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;Data Source=C:\Users\AntivirUS Vandry\Documents\Visual Studio 2013\Projects\Give And Get\dbaseMain.mdb")
Dim sql As String = "Select * from tblGive"
Dim dbcmd As OleDbCommand = New OleDbCommand(sql, con)
con.Open()
Dim dbadapter As OleDbDataAdapter = New OleDbDataAdapter(sql, con)
Dim db As DataSet = New DataSet("TABLE")
dbadapter.Fill(db, "TABLE")
'create new instance of table so that row can be accessed
Dim dt As New DataTable
dt = db.Tables("TABLE")
CmbGenre.Text = dt.Rows(0)(0)
CmbLanguage.Text = dt.Rows(0)(1)
txtNMovie.Text = dt.Rows(0)(2)
txtFName.Text = dt.Rows(0)(3)
txtLname.Text = dt.Rows(0)(4)
CmbClass.Text = dt.Rows(0)(5)
txtnull.Text = dt.Rows(0)(6)
End Sub
There are some codes in between them.Including textboxes and combo boxes.
Public Sub submit()
con = New OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;Data Source=C:\Users\AntivirUS Vandry\Documents\Visual Studio 2013\Projects\Give And Get\dbaseMain.mdb")
con.Open()
Dim sql As String
sql = "Insert into tblGive (Genre,Language,NMovie,FName,LName,Class,SaveDate)" + "VALUES (" & CmbGenre.Text & "','" & CmbLanguage.Text & "','" & txtNMovie.Text & "','" & txtFName.Text & "','" & txtLname.Text & "','" & CmbClass.Text & "','" & txtnull.Text & "')"
MsgBox(sql)
Dim dbcmd As OleDbCommand
dbcmd = New OleDbCommand(sql, con)
dbcmd.ExecuteNonQuery()
MsgBox("Saved")
End Sub
You are missing a single quote at the beginning of the values keyword.
In other words,
VALUES (" & CmbGenre.Text & "','" & CmbLanguage.Text &
should be
VALUES ('" & CmbGenre.Text & "','" & CmbLanguage.Text &
How can you add data in a window form to a sql database in visual studio 2005?
I'm facing problems while saving.
Public Class Staff
Dim myconnection As SqlConnection
Dim mycommand As SqlCommand
Dim dr As SqlDataReader
Dim dr1 As SqlDataReader
Dim ra As Integer
Private Sub cmdsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdsave.Click
myconnection = New SqlConnection("server=localhost;uid=sa;pwd=;database=medisam")
myconnection.Open()
mycommand = New SqlCommand("insert into staff([FirstName],[LastName],[Address],[DOB], [TelephoneNum], [DateJoinIn], [HighestQualifi], [AppointedAs], [Salary]) VALUES ('" & txtfname.Text & "','" & txtlname.Text & "','" & txtaddress.Text & "','" & txtdob.Text & "','" & txttelephone.Text & "','" & txthqualifi.Text & "','" & ComboBox1.SelectedValue & "','" & txtsalary.Text & "')", myconnection)
mycommand.ExecuteNonQuery()
myconnection.Close()
End Sub
End Class
Well, at first glance, I can see a missing value in your query text:
I can count 9 fields and only 8 values... but this could be only an typing error.
More serious instead is the lack of parameter use. As #slaks pointed in its comment, this kind of code leads to Sql Injection Attacks. Also, you are passing all values as strings. I doubt that your [staff] table contains only text fields (DOB, DateJoinIn, AppointedAs). If it does, your schema design is horribly broken. The parameters could also help avoid this kind of error. Finally, connecting with the sa account will cause your dba to hunt you down and beat you to within an inch of your life.
Please rewrite your method in this way:
Private Sub cmdsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdsave.Click
Using (myconnection as SqlConnection = New SqlConnection("server=localhost;uid=sa;pwd=;database=medisam"))
myconnection.Open()
mycommand = New SqlCommand("insert into staff([FirstName],[LastName],[Address],[DOB], " & _
"[TelephoneNum], [DateJoinIn], [HighestQualifi], [AppointedAs], [Salary]) " & _
"VALUES (#first, #last, #address, #dob, #tel, #dateJ, #highQ, #appointed, #sal)", myconnection)
mycommand.Parameters.AddWithValue("#first", txtfname.Text)
mycommand.Parameters.AddWithValue("#last", txtlname.Text)
mycommand.Parameters.AddWithValue("#address", txtaddress.Text)
mycommand.Parameters.AddWithValue("#dob",txtdob.Text) ' if this is a date, need to convert
mycommand.Parameters.AddWithValue("#tel",txttelephone.Text)
mycommand.Parameters.AddWithValue("#dateJ", txt??? Missing ????)
mycommand.Parameters.AddWithValue("#highQ",txthqualifi.Text)
mycommand.Parameters.AddWithValue("#appointed",ComboBox1.SelectedValue) ' need to convert ???
mycommand.Parameters.AddWithValue("#sal",txtsalary.Text) ' need to convert ???
mycommand.ExecuteNonQuery()
End Using
End Sub