how to insert update and delete records in tables - sql-server

I have a large windows form with 50 different fields (text boxes,combo boxes,listview,check box) i have 10 tables in sql server database each table have different column I want to insert my windows forms 50 fields in these 10 tables. Here is my code to insert record in a table
Dim cmd As New SqlCommand
cmd.Connection = conn
cmd.CommandText = "Insert Into ChartOfAccount (MainCode,MainDescription,AccountCode,AccountDescription,OpeningBalance) values ('" & MainCode & "','" & MainDescription & "','" & AccountCode & "','" & AccountDescription & "','" & OpeningBalance & "')"
cmd.ExecuteNonQuery()
So question is if I insert data into 10 different tables then I need to write 10 insert statments.
If I update or delete record I need to write update and delete command 10 tables seprately
this will take long time please guide me if any short method exists.

Your query is susceptible with SQL injection so better to use parameters:
Dim connStr as String = "connection string values here";
using con as new SqlConnection(connStr)
Dim commandText as String =
#"Insert Into ChartOfAccount (MainCode
,MainDescription,AccountCode
,AccountDescription,OpeningBalance)
VALUES
(#MainCode, #MainDesc,#AccountCode
,#AccountDesc,#OpeningBalance)"
Dim cmd as New SqlCommand(commandText,con)
cmd.Parameters.AddWithValue("#MainCode",MainCode)
cmd.Parameters.AddWithValue("#MainDesc",MainDescription)
cmd.Parameters.AddWithValue("#AccountCode",AccountCode)
cmd.Parameters.AddWithValue("#AccountDesc",AccountDescription)
cmd.Parameters.AddWithValue("#OpeningBalance",OpeningBalance)
Try
con.Open()
cmd.ExecuteNonQuery()
Catch ex as Exception
MessageBox.Show(ex.Message)
End Try
End Using
Now, this is only for Inserting records example.

You can create a stored procedure for that. In order to create a stored procedure, you can use the following SQL query:
Create procedure [dbo].[NewUser]
#Yourparameter1 int ,
#Yourparamtere2
As
Insert into dbo.Users
(
// Db columns
Column1 ,
Column2
)
values
(
#Yourparameter1
#Yourparameter2
)
And in your C# code, create a SQLParameter collection and pass it to the procedure. It will work fine and smoothly, and this way your code will be simpler.

Related

Updating ms access database [duplicate]

I am trying to create an SQL statement using user-supplied data. I use code similar to this in C#:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES ('" + someVariable + "', '" + someTextBox.Text + "');";
var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();
and this in VB.NET:
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES ('" & someVariable & "', '" & someTextBox.Text & "');"
Dim cmd As New SqlCommand(sql, myDbConnection)
cmd.ExecuteNonQuery()
However,
this fails when the user input contains single quotes (e.g. O'Brien),
I cannot seem to get the format right when inserting DateTime values and
people keep telling me that I should not do this because of "SQL injection".
How do I do it "the right way"?
Use parameterized SQL.
Examples
(These examples are in C#, see below for the VB.NET version.)
Replace your string concatenations with #... placeholders and, afterwards, add the values to your SqlCommand. You can choose the name of the placeholders freely, just make sure that they start with the # sign. Your example would look like this:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES (#someValue, #someOtherValue);";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("#someValue", someVariable);
cmd.Parameters.AddWithValue("#someOtherValue", someTextBox.Text);
cmd.ExecuteNonQuery();
}
The same pattern is used for other kinds of SQL statements:
var sql = "UPDATE myTable SET myField1 = #newValue WHERE myField2 = #someValue;";
// see above, same as INSERT
or
var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = #someValue;";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("#someValue", someVariable);
using (var reader = cmd.ExecuteReader())
{
...
}
// Alternatively: object result = cmd.ExecuteScalar();
// if you are only interested in one value of one row.
}
A word of caution: AddWithValue is a good starting point and works fine in most cases. However, the value you pass in needs to exactly match the data type of the corresponding database field. Otherwise, you might end up in a situation where the conversion prevents your query from using an index. Note that some SQL Server data types, such as char/varchar (without preceding "n") or date do not have a corresponding .NET data type. In those cases, Add with the correct data type should be used instead.
Why should I do that?
It's more secure: It stops SQL injection. (Bobby Tables won't delete your student records.)
It's easier: No need to fiddle around with single and double quotes or to look up the correct string representation of date literals.
It's more stable: O'Brien won't crash your application just because he insists on keeping his strange name.
Other database access libraries
If you use an OleDbCommand instead of an SqlCommand (e.g., if you are using an MS Access database), use ? instead of #... as the placeholder in the SQL. In that case, the first parameter of AddWithValue is irrelevant; instead, you need to add the parameters in the correct order. The same is true for OdbcCommand.
Entity Framework also supports parameterized queries.
VB.NET Example Code
This is the example code for the wiki answer in vb.net, assuming Option Strict On and Option Infer On.
INSERT
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES (#someValue, #someOtherValue);"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("#someValue", someVariable)
cmd.Parameters.AddWithValue("#someOtherValue", someTextBox.Text)
cmd.ExecuteNonQuery()
End Using
UPDATE
Dim sql = "UPDATE myTable SET myField1 = #newValue WHERE myField2 = #someValue;"
' see above, same as INSERT
SELECT
Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = #someValue;"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("#someValue", someVariable)
Using reader = cmd.ExecuteReader()
' ...
End Using
' Alternatively: Dim result = cmd.ExecuteScalar()
' if you are only interested in one value of one row.
End Using

Inserting into SQL Server table with GUID pk from MS Access

I'm in the process of moving our DB from an Access backend to a SQL Server backend while keeping the Access front end. One of the tables was set up with a replication ID for its PK. As an access DB, we could insert values into this table without referencing the PK field, as Access automatically generates a new GUID.
We have a function that builds a record to insert into this table that no longer works with the linked SQL Server version of the table and I'm pretty sure it must has something to do with this replcationID field. In SQL Server, it imported as data type 'uniqueidentifier'. When the function runs, it return no errors, but also inserts nothing.
I'd like to know if there is a way to get this working without changing it to a passthrough. How do I get MS Access to tell SQL Server to generate a new GUID when inserting a new record.
As a side note, the PK field is called PurchaseID and is not referenced currently in the vba (since it used to auto generate for this field)
Public Sub BuildReorderRecord(Market As String, MPID As String, FloorsetID As String)
Dim values As String
Dim sql As String
Dim P3ID As String
Dim Username As String
Dim dt As String
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT ID FROM tblAttributes WHERE MPID = """ & MPID & """")
'Get P3ID and auditing values
dt = Now()
Username = Environ("USERNAME")
P3ID = rs![ID]
'build record values string
values = """" & P3ID & """, """ & Market & """, """ & MPID & "', """ & FloorsetID & """"
values = values & ", #" & dt & "#, """ & Username & """, #" & dt & "#, """ & Username & """"
'build sql string
sql = "INSERT INTO tblReorders (P3ID, country, mpid, floorsetID"
sql = sql & ", CreateDate, CreatorUsername, ChangeRecord_Timestamp, ChangeRecord_Username)" & vbNewLine
sql = sql & "VALUES(" & values & ")"
'insert the new record
db.Execute sql
Set db = Nothing
Set rs = Nothing
End Sub
You could add a default constraint on the table for that column in sql server like so:
alter table t
add constraint [df_t_guid]
default newid() for [guid];
Or you could use a custom function in access to generate a guid like stguidgen()
insert into ... (guid...
values (stguidgen(), ...)
With a pass-through query, you could use newid() which generates a new uniqueidentifier in sql server.
insert into ... (guid...
values (newid(), ...)

Issues adding column from DGV to SQL server

I'm sorry if the title is a little vague but I wasn't sure how to put it in a short space.
For context, I have a save button, which is when changes made are updated in the SQL server database. This works fine when adding rows, or changing values, even deleting rows. Nothing wrong there.
However, when I try to add or remove columns the app becomes a bit more problematic and simply does not update added/removed columns in the database and doesnt throw an error.
The only way I can get adding or removing columns to work is to use a sql query on the add/delete buttons, but this saves directly to the server - which i do not want.
What I need is for the changes to appear in the table, and then only update the database when the save button is clicked.
My code is here --- (Note, this is done over three forms, I have the main form with the table, plus two more that are used for inputting the name of the "trainer column" that is to be added or removed)
Private Function save() ''''' Main form
Try
ds.Tables(0).AcceptChanges()
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
End Function
Public Function AddTrainerFunc() ''''' Main form
'Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & TrainerName.Trim() & "] nvarchar(255)"
'Using con As New OleDbConnection(cs)
' Using cmd As New OleDbCommand(SqlAddCol, con)
' con.Open()
' cmd.ExecuteNonQuery()
' End Using
'End Using
ds.Tables(0).Columns.Add(TrainerName.Trim()).DefaultValue = " "
RefreshBtn()
End Function
Public Function delTrainerFunc() ''''' Main form
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & TrainerName.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
ds.Tables(0).Columns.Remove(TrainerName)
DelTrainer.Close()
RefreshBtn()
MessageBox.Show("Trainer '" & TrainerName.Trim() & "' has been deleted from the table.")
End Function
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click '''''Add Column Form
If Not txtTrainerName.Text = "Trainer Name Here" Or txtTrainerName.Text = "" Then
MTS.TrainerName = txtTrainerName.Text
MTS.Enabled = True
Me.Close()
MTS.AddTrainerFunc()
Else
MessageBox.Show("Please input a name for the trainer in the text box above.")
End If
End Sub
Private Sub btnDel_Click(sender As Object, e As EventArgs) Handles btnDel.Click ''''' Delete Column form
Dim delYN As Integer = MessageBox.Show("Are you sure you want to delete '" & cmbTrainers.Text & "' from the MTS table? The action will be permanent!", "Delete Trainer?", MessageBoxButtons.YesNo)
If delYN = DialogResult.Yes Then
MTS.Enabled = True
MTS.delTrainerFunc()
End If
End Sub
Sorry if this was a bit long winded but... I can't seem to find a way to add columns to the Database quite how I wanted too, neither through googling the answer, nor through simple experimentation, so I came here in the hopes that one of you may be able to help. Thanks in advance for any help you can provide.
EDIT --- I am using oleDB as the connection to sql, if this helps.
EDIT 2 --- Here's a few screenshots in case you wish to have a look at the visual side of the app.
The add form being used. (with the main form in the background. Sorry I couldnt get that on its own - only allowed two links with 6 rep!)
And the delete trainer form. The dropdown lists everyone in the table for you, then prompts you when you click "delete"
EDIT 3 --- Okay, I know the normalizing tables thing that Sean was on about could have worked, but it might have required quite a big change to the server used and to the program as well. I managed to find a simpler way to get this working that calls the sql queries to add or remove columns to the table on the save, only after the changes have been made to the data grid.
Heres some code in case anyone was interested. It's a little messy and can probably be optimized a bit, but this works for me regardless.
` Private Function save()
Try
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
'This section reads the SQL server for column names, and adds any that are listed in the DGV, but not the database. I know its a little messy but itll do.
Dim columnnum As Integer = -1
Dim columname As String
For Each column In ds.Tables(0).Columns
columnnum = columnnum + 1
columname = dgvSchedule.Columns(columnnum).HeaderText
If Not ds2.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Table does not include " & columname)
Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & columname.Trim() & "] nvarchar(255)"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlAddCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
columnnum = -1
For Each column In ds2.Tables(0).Columns
columnnum = columnnum + 1
columname = ds2.Tables(0).Columns(columnnum).ColumnName
If Not ds.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Will Delete " & columname)
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & columname.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
ds2.Tables.Clear()
da2 = New OleDbDataAdapter(sql, cs)
da2.Fill(ds2)
End Function`
I don't know very many details of what you are doing here but here is an example of a more normalized approach to this.
create table Trainers
(
TrainerID int identity
, FirstName varchar(25)
, LastName varchar(25)
, CONSTRAINT PK_Trainers PRIMARY KEY CLUSTERED (TrainerID)
)
create table Courses
(
CourseID int identity
, CourseName varchar(50)
, CONSTRAINT PK_Courses PRIMARY KEY CLUSTERED (CourseID)
)
create table TrainerCourses
(
TrainerID int not null
, CourseID int not null
, StartDate date not null
, EndDate date not null
, DailyStartTime time not null
, CONSTRAINT PK_TrainerCourses PRIMARY KEY CLUSTERED (TrainerID, CourseID, StartDate, DailyStartTime)
, CONSTRAINT FK_TrainerCourses_Trainers FOREIGN KEY (TrainerID) REFERENCES Trainers(TrainerID)
, CONSTRAINT FK_TrainerCourses_Courses FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
)

Insert Complete RecordSet to another table in other database MS Access

I have 2 Tables with same colums in two diferent files. One file "Base PT.accdb" where i want to insert all the Recordset from the other file "Sanchez_Mar.mdb". Both tables have 7 Columns with the same name.
I had a lot of problems using "System.Data.OleDb.OleDbConnection" so i decided to use RecordSets.
At the moment i'm using loop to insert all, but there is a lot of data so it take quite long.
It's posible to insert all the recordset to the other database ?
this is the part of my code i need help:
Sub Copiar_BasePT2(RutaPT As String)
Dim Cant as Long
Dim db As Database
Dim dbBase_PT As Database
Set dbBase_PT = OpenDatabase(RutaPT & "\Base PT.accdb")
Set db = CurrentDb
Dim rsSYM As Recordset
Set rsSYM = db.OpenRecordset("SELECT * from FINAL_Alarma_SYM")
rsSYM.MoveLast
Cant = rsSYM.RecordCount
rsSYM.MoveFirst
For i = 1 To Cant
dbBase_PT.Execute ("Insert into Tab_PT values('" & rsSYM.Fields(0) & "','" & rsSYM.Fields(1) & "','" & rsSYM.Fields(2) & "','" & rsSYM.Fields(3) & "','" & rsSYM.Fields(4) & "','" & rsSYM.Fields(5) & "','" & rsSYM.Fields(6) & "');")
rsSYM.MoveNext
DoEvents
Next i
End Sub
It is posible to insert all the recordset ?
Or how can I bring the table From "Sanchez_Mar.mdb" to "Base PT.accdb" faster?
You can run an insert query using your other database as the source for the data.
"INSERT INTO Tab_PT (Field1, Field2, Field3, Field4, Field5, Field6, Field7) " & _
" SELECT Field1, Field2, Field3, Field4, Field5, Field6, Field7 " & _
" FROM [MS Access;DATABASE=PathToSanchez_MarDB].FINAL_Alarma_SYM"
Do the following from the source database:
1) Create a linked table to the destination table.
On the External Data tab, in the Import group, click Access.
Select Link rather than import
Browse to the destination database and select the file
Select the destination table from the list
2) Create an append query selecting from the source table and appending to the linked table.
Create a select query by selecting each field independently
Change the query to an append query by clicking "Append" in the Design tab
Select the (linked) destination table
3) Run it
This is probably as fast as it gets if you already have the destination table. If you don't mind starting over, you could delete the destination table and just do an import from the destination database.

Generating database tables' CREATE script

I am working on an application which backs up database tables and stores their data as CSV. When I want to restore a table back to the database I use a 'model' table which creates an existing table based on the model.
However there are multiple structures of these tables and I would like to generate the tables' 'Create' script and save it somewhere for restoring purposes.
Is there anyway for this? I am only interested to do this via coding and not sql script because we are using both SQL Server and Oracle and this process will be automated for more than 3000 tables.
In the code below I create the table based on a table model:
If ProductData.Tables(0).Rows(0).Item(0) = 0 Then 'Does not exist
'Create table based on a model
Dim sqlCopyFromModel As New SqlCommand("SELECT TOP 0 * INTO " & sFileName & " FROM s_20130702;", con)
con.Open()
Dim i As Integer = sqlCopyFromModel.ExecuteNonQuery()
con.Close()
'Enter data from CSV file
Dim sqlInsertDataFromCSV As New SqlCommand("BULK INSERT " & sFileName & " FROM '" & txtFilePath.Text.Trim & "' WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\n', FIRSTROW=2 )", con)
con.Open()
sqlInsertDataFromCSV.ExecuteNonQuery()
con.Close()
MsgBox("success")
In Oracle you can use builtin package DBMS_METADATA where the function GET_DDL can give you the DDL ("create script") needed to create the table.
http://docs.oracle.com/database/121/ARPLS/d_metada.htm#ARPLS66885
SELECT DBMS_METADATA.GET_DDL('TABLE','EMP','SCOTT')
FROM DUAL;
(If you are trying to do something that is database independent and works both on SQL Server and Oracle, then you'd better not use "TOP 0" ;-)

Resources