sql Transaction and dual table insertion in vb.net - sql-server

What I wanted to do is insert data on the first table, then get the last inserted ID on the first table and insert it on the second. I already got this without transaction, but I can't do it because I need to have transactions later on because I will add a lot of inserts in one go.
This is my code so far..
Take note that this is inside a transaction..
command.CommandText = "INSERT INTO tblCarMaintenance " & _
"(ID_Car, fDate, fMechanic, fOverseer, fDescription, fDateNext, fAmount) " & _
"VALUES (#myCarID, #myDate, #myMechanic, #myOverseer, #myDescription, #myDateNext, #myAmount)"
command.Parameters.Add("#myCarID", SqlDbType.Int).Value = pCarID
command.Parameters.Add("#myDate", SqlDbType.DateTime).Value = myDate
command.Parameters.Add("#myMechanic", SqlDbType.VarChar).Value = pMechanic
command.Parameters.Add("#myOverseer", SqlDbType.VarChar).Value = pOverseer
command.Parameters.Add("#myDescription", SqlDbType.VarChar).Value = pDescription
command.Parameters.Add("#myDateNext", SqlDbType.DateTime).Value = pNext
command.Parameters.Add("#myAmount", SqlDbType.Float).Value = pAmount
command.ExecuteNonQuery()
'insert records on the second table (the problem is here)
command.CommandText = "INSERT INTO tblCarMaintenance2 " & _
"(ID_Main, ID_Supplier, fParts, fAmount) " & _
"VALUES (#myMainID, #mySupplierID, #myParts, #myAmount) " & _
"FROM tblCarMaintenance"
command.Parameters.Add("#myMainID", SqlDbType.Int).Value = myID
command.Parameters.Add("#mySupplierID", SqlDbType.DateTime).Value = myDate
command.Parameters.Add("#myParts", SqlDbType.VarChar).Value = pMechanic
command.Parameters.Add("#myAmount", SqlDbType.VarChar).Value = pOverseer
command.ExecuteNonQuery()
transaction.Commit()
EDIT: #myMainID is the parameter equal to the last inserted ID on tblCarMaintenance
EDIT:
The solution for the problem is this:
command.CommandText = "INSERT INTO tblCarMaintenance " & _
"(ID_Car, fDate, fMechanic, fOverseer, fDescription, fDateNext, fAmount) " & _
"VALUES (#myCarID, #myDate, #myMechanic, #myOverseer, #myDescription, #myDateNext, #myAmount)" & _
"Select SCOPE_IDENTITY()"
command.Parameters.Add("#myCarID", SqlDbType.Int).Value = pCarID
command.Parameters.Add("#myDate", SqlDbType.DateTime).Value = myDate
command.Parameters.Add("#myMechanic", SqlDbType.VarChar).Value = pMechanic
command.Parameters.Add("#myOverseer", SqlDbType.VarChar).Value = pOverseer
command.Parameters.Add("#myDescription", SqlDbType.VarChar).Value = pDescription
command.Parameters.Add("#myDateNext", SqlDbType.DateTime).Value = pNext
command.Parameters.Add("#myAmount", SqlDbType.Float).Value = pAmount
Dim InsertedItemID = command.ExecuteScalar()
command.CommandText = "INSERT INTO tblCarMaintenance2 " & _
"(ID_Main, ID_Supplier, fParts, fAmount) " & _
"VALUES (" & InsertedItemID & ", #mySupplierID, #myParts, #myAmount2) "
command.Parameters.Add("#mySupplierID", SqlDbType.Int).Value = pSupplier
command.Parameters.Add("#myParts", SqlDbType.VarChar).Value = pParts
command.Parameters.Add("#myAmount2", SqlDbType.Float).Value = 12
command.ExecuteNonQuery()

In your first query, edit to:
command.CommandText = "INSERT INTO tblCarMaintenance " & _
"(ID_Car, fDate, fMechanic, fOverseer, fDescription, fDateNext, fAmount) " & _
"VALUES (#myCarID, #myDate, #myMechanic, #myOverseer, #myDescription, #myDateNext, #myAmount)" & _
"Select SCOPE_IDENTITY()";
and change the first command.ExecuteNonQuery() to:
Dim InsertedItemID = command.ExecuteScalar()

Related

Import from txt (MS Access 2013) to SQL Server 2016 slow

I have a txt file on my local PC, this has to be check and then line by line uploaded into SQL Server 2016 using a Stored Procedure from MS Access using ADODB. It looks like Access is running always 2 rows fast and then making a short stop.
In MS Access I'm using this function:
Public Function ImportData(FileString As String)
Dim WholeLine As String
Dim cc As Variant
Dim sapPurchaseDocument As String
Dim sapPartNumber As String
Dim sapPartName As String
Dim sapDocumentDate As String
Dim sapSupplier As String
Dim sapPlant As String
Dim sapSLoc As String
Dim sapQuantity As Double
Dim sapUOM As String
Dim sapTargetQuantity As Double
Dim sapDeliveryDate As String
Dim sapPrevQuantity As Double
Dim sapReceivedQuantity As Double
Dim sapIssuedQuantity As Double
Dim sapDeliveredQuantity As Double
Dim sapPurchaseRequisition As String
Dim sapPurchaseRequisitionItem As String
Dim sapCreationIndicatior As String
Dim sapNoOfPositions As Double
Dim totalCount As Integer
Dim sapPurchaseDocumentItem As String
Dim rs As New ADODB.Recordset
Call GetConnection
Set rs.ActiveConnection = myCN
If Right(FileString, 3) = "txt" Then
totalCount = GetRowCount(FileString)
Open FileString For Input As #1
i = 0
Do While Not EOF(1)
Line Input #1, WholeLine
If Left(WholeLine, 3) = "| 4" Then
'Debug.Print WholeLine
cc = Split(WholeLine, "|")
sapPurchaseDocument = Trim(cc(1))
sapPartNumber = Trim(Replace(cc(2), ".", ""))
sapPartName = Trim(Replace(cc(3), "'", ""))
sapDocumentDate = Right(cc(4), 4) & "-" & Mid(cc(4), 4, 2) & "-" & Left(cc(4), 2)
sapSupplier = cc(5)
sapPlant = cc(6)
sapSLoc = cc(7)
sapQuantity = Replace(cc(8), ",", "")
sapUOM = Trim(cc(9))
sapTargetQuantity = Replace(cc(10), ",", "")
sapDeliveryDate = Right(cc(11), 4) & "-" & Mid(cc(11), 4, 2) & "-" & Left(cc(11), 2)
sapPrevQuantity = cc(12)
sapReceivedQuantity = Replace(cc(13), ",", "")
sapIssuedQuantity = Replace(cc(14), ",", "")
sapDeliveredQuantity = Replace(cc(15), ",", "")
sapPurchaseRequisition = Trim(cc(16))
sapPurchaseRequisitionItem = Trim(cc(17))
sapCreationIndicatior = cc(18)
sapNoOfPositions = cc(19)
sapPurchaseDocumentItem = Trim(cc(20))
strSQL = "spInsertUpdateSAPME2M '" & sapPurchaseDocument & "', '" & sapPartNumber & "', '" & sapPartName & "', '" & _
sapDocumentDate & "', '" & sapSupplier & "', '" & sapPlant & "', '" & sapSLoc & "', " & _
sapQuantity & ", '" & sapUOM & "', " & sapTargetQuantity & ", '" & sapDeliveryDate & "', " & _
sapPrevQuantity & ", " & sapReceivedQuantity & ", " & sapIssuedQuantity & ", " & _
sapDeliveredQuantity & ", '" & sapPurchaseRequisition & "', '" & sapPurchaseRequisitionItem & "', '" & _
sapCreationIndicatior & "', '" & sapNoOfPositions & "', '" & sapPurchaseDocumentItem & "'"
rs.Open (strSQL)
DoEvents
End If
i = i + 1
Debug.Print i
Forms!frm_Overview.lblStatus.Caption = "Record " & i & " of " & totalCount & " loaded. Please wait!"
DoEvents
'Refresh
Loop
MsgBox "Import done"
End If
Close #1
End Function
And on SQL Server I have a stored procedure which looks like this:
USE [MOBILEPRINT]
GO
/****** Object: StoredProcedure [dbo].[spInsertUpdateSAPME2M] Script Date: 5/25/2020 11:39:31 AM ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CHANGE NO ACTION
ALTER PROCEDURE [dbo].[spInsertUpdateSAPME2M]
-- Add the parameters for the stored procedure here
#sapPurchaseDocument varchar(50),
#sapPartNumber varchar(50),
#sapPartName varchar(300),
#sapDocumentDate date,
#sapSupplier varchar(50),
#sapPlant varchar(100),
#sapSLoc varchar(50),
#sapQuantity float,
#sapUOM varchar(50),
#sapTargetQuantity float,
#sapDeliveryDate date,
#sapPrevQuantity float,
#sapReceivedQuantity float,
#sapIssuedQuantity float,
#sapDeliveredQuantity float,
#sapPurchaseRequisition varchar(50),
#sapPurchaseRequisitionItem varchar(50),
#sapCreationIndicatior varchar(50),
#sapNoOfPositions varchar(50),
#sapPurchaseDocumentItem varchar(50)
AS
BEGIN TRANSACTION
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #RESULT int
DECLARE #UPDATE_CHECK int
DECLARE #UpdateDate datetime = GetDate()
BEGIN
SELECT #RESULT = COUNT(sapPurchaseDocument) FROM SAP_ME2M WHERE sapPurchaseDocument = #sapPurchaseDocument AND sapPartNumber = #sapPartNumber
IF ISNULL(#RESULT,0) = 0
BEGIN
INSERT INTO SAP_ME2M (
sapPurchaseDocument,
sapPartNumber,
sapPartName,
sapDocumentDate,
sapSupplier,
sapPlant,
sapSLoc,
sapQuantity,
sapUOM,
sapTargetQuantity,
sapDeliveryDate,
sapPrevQuantity,
sapReceivedQuantity,
sapIssuedQuantity,
sapDeliveredQuantity,
sapPurchaseRequisition,
sapPurchaseRequisitionItem,
sapCreationIndicatior,
sapNoOfPositions,
ChangeDate,
sapPurchaseDocumentItem)
VALUES
(#sapPurchaseDocument, #sapPartNumber, #sapPartName, #sapDocumentDate, #sapSupplier, #sapPlant,
#sapSLoc, #sapQuantity, #sapUOM, #sapTargetQuantity, #sapDeliveryDate, #sapPrevQuantity,
#sapReceivedQuantity, #sapIssuedQuantity, #sapDeliveredQuantity, #sapPurchaseRequisition,
#sapPurchaseRequisitionItem, #sapCreationIndicatior, #sapNoOfPositions, #UpdateDate, #sapPurchaseDocumentItem)
END
ELSE
SELECT #UPDATE_CHECK = COUNT(*) FROM SAP_ME2M WHERE
sapPurchaseDocument = #sapPurchaseDocument AND
sapPartNumber = #sapPartNumber AND
sapPartName = #sapPartName AND
sapDocumentDate = #sapDocumentDate AND
sapSupplier = #sapSupplier AND
sapPlant = #sapPlant AND
sapSLoc = #sapSLoc AND
sapQuantity = #sapQuantity AND
sapUOM = #sapUOM AND
sapTargetQuantity = #sapTargetQuantity AND
sapDeliveryDate = #sapDeliveryDate AND
sapPrevQuantity = #sapPrevQuantity AND
sapReceivedQuantity = #sapReceivedQuantity AND
sapIssuedQuantity = #sapIssuedQuantity AND
sapDeliveredQuantity = #sapDeliveredQuantity AND
sapPurchaseRequisition = #sapPurchaseRequisition AND
sapPurchaseRequisitionItem = #sapPurchaseRequisitionItem AND
sapCreationIndicatior = #sapCreationIndicatior AND
sapNoOfPositions = #sapNoOfPositions AND
sapPurchaseDocumentItem = #sapPurchaseDocumentItem
IF #UPDATE_CHECK = 0
BEGIN
UPDATE SAP_ME2M SET
sapPartName = #sapPartName ,
sapDocumentDate = #sapDocumentDate ,
sapSupplier = #sapSupplier ,
sapPlant = #sapPlant ,
sapSLoc = #sapSLoc ,
sapQuantity = #sapQuantity ,
sapUOM = #sapUOM ,
sapTargetQuantity = #sapTargetQuantity ,
sapDeliveryDate = #sapDeliveryDate ,
sapPrevQuantity = #sapPrevQuantity ,
sapReceivedQuantity = #sapReceivedQuantity ,
sapIssuedQuantity = #sapIssuedQuantity ,
sapDeliveredQuantity = #sapDeliveredQuantity ,
ChangeDate = #UpdateDate
WHERE
sapPartNumber = #sapPartNumber AND
sapPartName = #sapPartName AND
sapDocumentDate = #sapDocumentDate AND
sapSupplier = #sapSupplier AND
sapPlant = #sapPlant AND
sapSLoc = #sapSLoc AND
sapPurchaseDocumentItem = #sapPurchaseDocumentItem
END
END
COMMIT TRANSACTION WITH (DELAYED_DURABILITY = ON);
I have to upload around 30000 Records which takes more then an hour at the moment.
If you have suggestions, please let me know.
For fast data transfer, use a disconnected recordset with batch operations enabled.
Dim conn As ADODB.Connection
Call GetConnection
Set conn = myCN
Dim rs As New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "Table1", conn, adOpenForwardOnly, adLockBatchOptimistic
'Disconnect
Set rs.ActiveConnection = Nothing
Dim i As Long
For i = 1 To 3000
rs.AddNew
rs.Fields(1) = i
Next
'Reconnect
Set rs.ActiveConnection = conn
'Batch insert
rs.UpdateBatch
Debug.Print Now()
For me, this executes in 2 seconds, but it highly depends on the location of SQL server.
Then, process further on the data set when uploaded. Processing on a per-record basis is usually going to be slow.

vb.net creating table. using textbox.text for the per column of table

I have a program that add new employee it adds there personal information and there benefits id (ex. tax number). but i want to do is create a new table for there salary by making a new table and the columns will be there benefits id (ex.tax number) but i want to create the table automatically after the new employee is added here is my code if it will help you:
BTW IM GETTING A MESSAGEBOX THAT SHOW "incorrect syntax near '#idd'.
Dim add As String = String.Empty
add &= "insert into rec_member(firstname,middlename,lastname,age,birthday,pagibig,philhealth,sss,tin,department)"
add &= "values "
add &= "(#first,#middle,#last,#age,#bday,#pagibig,#philhealth,#sss,#tin,#dept);select scope_identity()"
Dim benefits As String = String.Empty
benefits &= "create table #idd(" & _
"pagibig(#ibig) integer not null, " & _
"philhealth(#phil) integer not null," & _
"sss(#rsss) integer not null," & _
"tin(#rtin) integer not null)"
Using conn As New SqlConnection("server=WIN10;database=add_member;user=hradmin;password=admin;")
Using cmd As New SqlCommand
With cmd
.Connection = conn
.CommandType = CommandType.Text
.CommandText = add
.Parameters.Add("#first", SqlDbType.VarChar).Value = afirstname.Text
.Parameters.Add("#middle", SqlDbType.VarChar).Value = amiddlename.Text
.Parameters.Add("#last", SqlDbType.VarChar).Value = alastname.Text
.Parameters.Add("#age", SqlDbType.Int).Value = aage.Value
.Parameters.Add("#bday", SqlDbType.Date).Value = abirthday.Text
.Parameters.Add("#pagibig", SqlDbType.Int).Value = apagibig.Text
.Parameters.Add("#philhealth", SqlDbType.Int).Value = aphilhealth.Text
.Parameters.Add("#sss", SqlDbType.Int).Value = asss.Text
.Parameters.Add("#tin", SqlDbType.Int).Value = atin.Text
.Parameters.Add("#dept", SqlDbType.VarChar).Value = adepartment.SelectedItem
End With
Try
conn.Open()
If afirstname.Text.Length < 2 Then
MsgBox("Please input more value on the FIRST NAME")
ElseIf amiddlename.Text.Length < 2 Then
MsgBox("Please input more value on the MIDDLE NAME")
ElseIf alastname.Text.Length < 2 Then
MsgBox("Please input more value on the LAST NAME")
ElseIf aage.Value < 16 Then
MsgBox("Age must be appropriate")
ElseIf abirthday.Text > "1997-01-01" Then
MsgBox("Please select a birthday")
ElseIf apagibig.Text.Length < 5 Then
MsgBox("Please input more value on the PAG-IBIG")
ElseIf adepartment.SelectedItem = "" Then
MsgBox("Please Select a Department")
ElseIf aphilhealth.Text.Length < 5 Then
MsgBox("Please input more value on the PHILHEALTH")
ElseIf asss.Text.Length < 5 Then
MsgBox("Please input more value on th SSS")
ElseIf atin.Text.Length < 5 Then
MsgBox("Please input more value on the TIN")
Else
Dim id As Integer = CInt(cmd.ExecuteScalar)
MsgBox("NEW EMPLOYEE ADDED" & Environment.NewLine &
"ID NUMBER:" & id & Environment.NewLine &
"FIRST NAME:" & afirstname.Text & Environment.NewLine &
"MIDDLE NAME:" & amiddlename.Text & Environment.NewLine &
"LAST NAME:" & alastname.Text & Environment.NewLine &
"AGE:" & aage.Value & Environment.NewLine &
"BIRTHDAY:" & abirthday.Text & Environment.NewLine &
"PAG-IBIG:" & apagibig.Text & Environment.NewLine &
"PHIL-HEALTH:" & aphilhealth.Text & Environment.NewLine &
"SSS:" & asss.Text & Environment.NewLine &
"TIN:" & atin.Text & Environment.NewLine &
"DEPARTMENT:" & adepartment.SelectedItem & Environment.NewLine
)
Using cmd1 As New SqlCommand
With cmd1
.Connection = conn
.CommandType = CommandType.Text
.CommandText = benefits
.Parameters.Add("#idd", SqlDbType.Int).Value = id
.Parameters.Add("#ibig", SqlDbType.Int).Value = apagibig.Text
.Parameters.Add("#phil", SqlDbType.Int).Value = aphilhealth.Text
.Parameters.Add("#rsss", SqlDbType.Int).Value = asss.Text
.Parameters.Add("#rtin", SqlDbType.Int).Value = atin.Text
End With
cmd1.ExecuteNonQuery()
MsgBox("New Table is Set for new employee")
End Using
End If
afirstname.Clear()
amiddlename.Clear()
alastname.Clear()
aage.Value = 0
abirthday.Text = "1997-01-01"
apagibig.Clear()
adepartment.ResetText()
aphilhealth.Clear()
asss.Clear()
atin.Clear()
conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Using
The problem is:
create table #idd ...
you cant send command with non static table-name.
for this, you need build the command-text with tokens:
benefits &= "create table {0}(" & _
"pagibig(#ibig) integer not null, " & _
"philhealth(#phil) integer not null," & _
"sss(#rsss) integer not null," & _
"tin(#rtin) integer not null)"
and:
Using cmd1 As New SqlCommand
With cmd1
.Connection = conn
.CommandType = CommandType.Text
.CommandText = String.Format(benefits, id)
.Parameters.Add("#ibig", SqlDbType.Int).Value = apagibig.Text
.Parameters.Add("#phil", SqlDbType.Int).Value = aphilhealth.Text
.Parameters.Add("#rsss", SqlDbType.Int).Value = asss.Text
.Parameters.Add("#rtin", SqlDbType.Int).Value = atin.Text

How to avoid duplicate entries when saving in database in vb.net

I have a button but it can save duplicate entries i don't know how to correctly put a if not exist operator pls help..
cmd = New SqlCommand("INSERT INTO Students(Familyname,Firstname,Middlename,StudentID)VALUES('" & txtname.Text & "','" & txtfname.Text & "','" & txtmname.Text & "','" & txtid.Text & "')", cn)
cn.Open()
i = cmd.ExecuteNonQuery
cn.Close()
If txtname.Text <> "" Then
ElseIf i > 0 Then
MsgBox("Save Sucessfully!", MessageBoxIcon.Information, "Success")
showrecord()
clear()
Else
MsgBox("Save Failed!", MessageBoxIcon.Error, "Error")
End If
You can use NOT EXISTS to prevent duplicate insert:
Dim sql = "INSERT INTO Students(Familyname, Firstname, Middlename, StudentID) " & _
"VALUES(#FamilyName, #Firstname, #Middlename, #StudentID)" & _
"WHERE NOT EXISTS(SELECT 1 FROM Students WHERE StudentId = #StudentID)"
Using cn As New SqlConnection("Your connection string here")
Dim cmd As SqlCommand = New SqlCommand(sql, cn)
cmd.Parameters.Add("#FamilyName", SqlDbType.VarChar, 50).Value = txtname.Text
cmd.Parameters.Add("#Firstname", SqlDbType.VarChar, 50).Value = txtfname.Text
cmd.Parameters.Add("#Middlename", SqlDbType.VarChar, 50).Value = txtmname.Text
cmd.Parameters.Add("#StudentID", SqlDbType.VarChar, 50).Value = txtid.Text
Dim i = cmd.ExecuteNonQuery
End Using
You should always use parameterized queries to avoid SQL Injection attacks.
NOTE: Please apply appropriate field types.
Try this one :
cn.Open()
Dim intReturn as integer
Dim strSql as string = "Select * from Students where StudentID = #StudentID"
sqlcmd = new sqlcommand(strSql, cn)
With sqlcmd.parameters
.addwithvalue("#StudentID", ctype(txtid.text,string)
End with
intReturn = sqlcmd.ExecuteScalar
If(intReturn > 0)
cmd = New SqlCommand("INSERT INTO Students(Familyname,Firstname,Middlename,StudentID)VALUES('" & txtname.Text & "','" & txtfname.Text & "','" & txtmname.Text & "','" & txtid.Text & "')", cn)
i = cmd.ExecuteNonQuery
If txtname.Text <> "" Then
ElseIf i > 0 Then
MsgBox("Save Sucessfully!", MessageBoxIcon.Information, "Success")
showrecord()
clear()
Else
MsgBox("Save Failed!", MessageBoxIcon.Error, "Error")
End If
Else
MsgBox("Student Already Exist", MessageBoxIcon.Error, "Error")
End If
cn.Close()
And don't forget to make your StudentID field as Unique in your database.

I try to update to SQL but it show this error " object reference is not set instance of an object "

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim CON As SqlConnection
CON = New SqlConnection("Data Source=.;Initial Catalog=PantienDatabase;Integrated Security=True")
CON.Open()
Try
'cmd.CommandText = "UPDATE Patient_Detail SET (Name ='" & TextBoxName.Text & "',Age = '" & TextBoxAge.Text & "',Sex = '" & TextBoxSex.Text & "',Address = '" & TextBoxAddress.Text & "',Check_In = '" & TextBoxCHiN.Text & "',Check_In_Illness = '" & TextBoxCHinL.Text & "',Sevice = '" & TextBoxService.Text & "',Check_out_Illness = '" & TextBoxCHoutL.Text & "',Check_out = '" & TextBoxCHout.Text & "',Transfer = '" & TextBoxTransfer.Text & "',Patient_result = '" & ComboBoxPtr.Text & "') WHERE ID = '" & TextBoxid.Text & "' "
cmd.CommandText = "UPDATE Patient_Detail SET (Name = #Name, Age = #Age, Sex = #Sex, Address = #Address, Check_In = #Check_In, Check_In_Illness =#Check_in_illness, Sevice =#Service, Check_out_Illness =#Check_out_Illness, Check_out = #Check_out ,Transfer = #Transfer, Patient_result = #Pantient_result WHERE ID = #ID "
cmd.Parameters.AddWithValue("#ID", TextBoxid.Text)
cmd.Parameters.AddWithValue("#Name", TextBoxName.Text)
cmd.Parameters.AddWithValue("#Age", TextBoxAge.Text)
cmd.Parameters.AddWithValue("#Sex", TextBoxSex.Text)
cmd.Parameters.AddWithValue("#Address", TextBoxAddress.Text)
cmd.Parameters.AddWithValue("#Check_In", TextBoxCHiN.Text)
cmd.Parameters.AddWithValue("#Check_in_illness", TextBoxCHinL.Text)
cmd.Parameters.AddWithValue("#Service", TextBoxService.Text)
cmd.Parameters.AddWithValue("#Check_out_Illness", TextBoxCHoutL.Text)
cmd.Parameters.AddWithValue("#Check_out", TextBoxCHout.Text)
cmd.Parameters.AddWithValue("#Transfer", TextBoxTransfer.Text)
cmd.Parameters.AddWithValue("#Pantient_result", ComboBoxPtr.Text)
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
CON.Close()
You don't declare cmd anywhere. At least, not in that code block. Thus, cmd is not set as an instance of anything.
Add this under your declaration of CON:
Dim cmd as SqlCommand
The set it to a new instance and set CON as the connection at the top of your TRY block:
cmd = New SqlCommand()
cmd.Connection = CON

Copy Datatable to SqlServer New or Existing Table with BulkCopy

Is there a way to copy a in memory datatable (vb.net) and its columns(schema) into a sql server new or existing table? And if a column has been added to the temp table is there a way to BulkCopy the data adding the new column into existing sql server table?
Here is what I use to persist a DataTable to SQL Server, it is written in C# but you should be able to convert it rather easily:
public static string CreateCopyTableDataSQLServer(DataTable dt, string tableName, string connectionString)
{
//Create the Destination Table based upon the structure of the DataTable
string sql = string.Empty;
string retValue = string.Empty;
StringBuilder sbu;
try
{
if (dt.Rows.Count == 0)
{
retValue += "The table " + tableName + " was NOT created because the source table contained zero (0) rows of data";
}
else
{
sbu = new StringBuilder(string.Format("IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[{0}]') AND type in (N'U')) DROP TABLE [dbo].[{0}] ", tableName));
sbu.Append("Create Table " + tableName + " (");
string dataType = string.Empty;
foreach (DataColumn column in dt.Columns)
{
switch (column.DataType.Name)
{
case "String":
dataType = " nvarchar(MAX) ";
break;
case "DateTime":
dataType = " nvarchar(MAX) ";
break;
case "Boolean":
dataType = " nvarchar(MAX) ";
break;
case "Int32":
dataType = " int ";
break;
case "Byte[]":
dataType = " varbinary(8000) ";
break;
default:
dataType = " nvarchar(MAX) ";
break;
}
string columnName = column.ColumnName.ToString();
columnName = columnName.FormatProperNameCase();
columnName = column.ColumnName.ToString().Replace(" ", "_").Replace("-", "_").Replace("#", "_").FormatRemoveNonLettersNumbers();
sbu.Append("[" + columnName + "]" + dataType + " null, ");
}
sbu.Remove(sbu.Length - 2, 2);
sbu.Append(")");
sql = sbu.ToString();
sql = sql.Replace("/", "_").Replace("\\", "_");
//Copy the Data From the Data Table into the destination Table that was created above
bool errorRetValue = SQLServerBulkCopy(dt, sql, tableName, connectionString);
if (!errorRetValue)
{
retValue += " \r\n";
retValue += "There was an error!";
}
}
return retValue;
}
catch (Exception ex)
{
retValue = string.Format("Error - There was a problem with table {0} and thus it's data has NOT been transferred - {1}", tableName, ex.Message);
return retValue;
}
}
public static bool SQLServerBulkCopy(DataTable dt, string Sql, string TableName, string connectionString, bool connectionTypeSQL = true)
{
try
{
if (connectionTypeSQL)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlBulkCopy sqlcpy = new SqlBulkCopy(conn))
{
using (SqlCommand cmd = new SqlCommand(Sql, conn))
{
cmd.ExecuteNonQuery();
sqlcpy.DestinationTableName = TableName; //copy the datatable to the sql table
sqlcpy.WriteToServer(dt);
}
}
}
return true;
}
else
{
throw new ArgumentOutOfRangeException("This method is only for SQL Server Engines");
}
}
catch (Exception ex)
{
return false;
}
}
For creating a new table:
select *
into YourDb.dbo.NewTable
from #YourTempTable
To append to an existing table:
insert YourDb.dbo.ExistingTable
select *
from #YourTempTable
Where I work they wouldn't allow Linked Servers so I transferred two tables form different servers across using VB.NET:
Copying source Sql table into Datatable
Mapping columns in Datatable
Copying Datatable into destination Sql table
The code is below:
Sub BulkTransferSQLTables(strSchema As String, strTable As String, StrOutputServer As String, StrOutputDatabase As String) ', strEndSrvrDb As String)
Dim DTBulkTransfer As New DataTable
'get table of information
Dim strSchemaTable As String = strSchema & "." & strTable
Dim sqlstring As String = "Select * from " & strSchemaTable
Dim Conn As SqlConnection = New SqlConnection("Data Source=" & PubstrServer & ";Initial Catalog=" & PubstrDatabase & ";Integrated Security=True") 'connection to server end
Dim selectCMD As SqlCommand
Dim adapter As SqlDataAdapter
adapter = New SqlDataAdapter(sqlstring, Conn)
'fill dataset
Conn.Open()
adapter.Fill(DTBulkTransfer)
'Debug.Print(DTBulkTransfer.Rows.Count & " Rows, " & DTBulkTransfer.Columns.Count & " Cols ") 'works
'build create table statement using details of destination table
Dim strColname As String
Dim intRecCount As Integer
'Dim strSchema As String = "SuffolkPseudo"
'Dim strTable As String = "Acute_Supporting"
strSchemaTable = strSchema & "." & strTable
Dim strCreateTableSQL As String = "CREATE TABLE [" & StrOutputDatabase & "].[" & strSchema & "].[" & strTable & "]("
Dim strSQL As String = " select [Statement], [RowNo] = ROW_NUMBER() OVER (ORDER BY Statement) FROM [" & PubstrDatabase & "].[dbo].[vwTableAndColumns] " & _
"where [TABLE_SCHEMA] = '" & strSchema & "' and table_name = '" & strTable & "'"
Dim strSQL2 As String = "" & _
" with CTE as ( " & _
" " & _
strSQL & _
" ) " & _
" " & _
" select count(*) from CTE "
intRecCount = GetSQLTableVal(strSQL2)
For X = 1 To intRecCount
strSQL2 = "" & _
" with CTE as ( " & _
" " & _
strSQL & _
" ) " & _
" " & _
" select * from CTE "
strColname = GetSQLTableVal(strSQL2 & " Where [RowNo] = " & X)
strCreateTableSQL = strCreateTableSQL & " " & Chr(13) & strColname
Next
strCreateTableSQL = Microsoft.VisualBasic.Left(strCreateTableSQL, Microsoft.VisualBasic.Len(strCreateTableSQL) - 1) & ") ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]"
Debug.Print(strCreateTableSQL)
Conn.Close()
Dim Conn2 As SqlConnection = New SqlConnection("Data Source=" & StrOutputServer & ";Initial Catalog=" & StrOutputDatabase & ";Integrated Security=True") 'connection to server end
'create sql string to check if table exists or not.
strSQL = " select count(*) FROM [" & StrOutputDatabase & "].sys.Tables as t1 " & _
" inner join [" & StrOutputDatabase & "].sys.schemas as t2 " & _
" ON t1.schema_id = t2.schema_id" & _
" where t2.name = '" & strSchema & "' " & _
" and t1.name = '" & strTable & "'"
If GetSQLTableValExternalServer(strSQL, StrOutputServer, StrOutputDatabase) > 0 Then
Conn2.Open()
'drop old table in destination area and recreate table.
strSQL = "drop table " & StrOutputDatabase & "." & strSchema & "." & strTable
selectCMD = New SqlCommand(strSQL, Conn2)
selectCMD.CommandTimeout = 600
selectCMD.ExecuteNonQuery()
Conn2.Close()
End If
Conn2.Open()
'create the table structure
selectCMD = New SqlCommand(strCreateTableSQL, Conn2)
selectCMD.CommandTimeout = 600
selectCMD.ExecuteNonQuery()
'list datatable columns
Dim name(DTBulkTransfer.Columns.Count) As String
Dim i As Integer = 0
'transfer to sql database from datatable to newly created empty detsination table
Using bulkcopy As SqlBulkCopy = New SqlBulkCopy(Conn2)
bulkcopy.BulkCopyTimeout = 3000
bulkcopy.DestinationTableName = strSchemaTable
For Each column As DataColumn In DTBulkTransfer.Columns
name(i) = column.ColumnName
Dim ColMap As New SqlBulkCopyColumnMapping(name(i).ToString, name(i).ToString)
bulkcopy.ColumnMappings.Add(ColMap)
Debug.Print("dt COLUMN: " & name(i).ToString)
i += 1
Next
bulkcopy.WriteToServer(DTBulkTransfer)
End Using
Conn2.Close()
MsgBox("Bulk Transfer Complete")
End Sub
Thanks
Eddy Jawed

Resources