How to copy Access table to SQL table in C#? - c#

As title says I've used odbcconnection to sqlconnection and for the life of me cant get it to work.. Copied a bunch of code from this site but cant get them both to work.
The program just hangs so maybe I am doing something wrong, but would appreciate maybe a bare bones template that i could just fill in the connection details and bulk copy the table to table..
using (OdbcConnection myConnection = new OdbcConnection())
{
string myConnectionString = #"Driver={Microsoft Access Driver (*.mdb)};" +
"Dbq=//####/data/Toronto/wrkgrp/wrkgrp30/Business Risk Oversight and Control/DATA INTEGRITY/CDE/CDE Testing Portal Requirements/Migration Requirements/RCM/Mutual Funds/Mutual Funds.mdb;";
myConnection.ConnectionString = myConnectionString;
myConnection.Open();
//execute queries, etc
OdbcCommand cmd = myConnection.CreateCommand();
cmd.CommandText = "SELECT * FROM RCM_MF_New_Accounts_Samples";
OdbcDataReader reader = cmd.ExecuteReader(); // close conn after complete
DataTable myDataTable = new DataTable();
myDataTable.Load(reader);
//myConnection.Close();
string destinationConnectionString = "Data Source=####;Initial Catalog=DYOF_STAGING_BROC;User ID=;Password=;Connection Timeout=999";
SqlConnection destination = new SqlConnection(destinationConnectionString);
SqlBulkCopy bulkData;
//destination.Open();
Exception ex = null;
try
{
Console.WriteLine("step1");
bulkData = new SqlBulkCopy(destinationConnectionString, SqlBulkCopyOptions.FireTriggers);
bulkData.BulkCopyTimeout = 1;
bulkData.DestinationTableName = "Load_CTR_Sample_Account_Opening2";
bulkData.WriteToServer(myDataTable);
bulkData.Close();
Console.WriteLine("moved from here to there");
reader.Close();
//destination.Close();
}
catch (Exception e)
{
ex = e;
}

I actually wrote an ORM to make this kind of task easier.
var accessDS = new AccessDataSource(connectionString1);
var dt = accessDS.From("RCM_MF_New_Accounts_Samples").ToDataTable().Execute();
var sqlDS = new SqlServerDataSource(connectionString2);
sqlDS.InsertBulk("Load_CTR_Sample_Account_Opening2", dt).Execute();
This does not work for .NET Core.
Packages:
https://www.nuget.org/packages/Tortuga.Chain.Access/
https://www.nuget.org/packages/Tortuga.Chain.SqlServer

Read the data from Access into a DataTable:
string strConnect = #"Provider=Microsoft.ACE.OLEDB.12.0;data source=D:\Temp\MyDB.accdb";
DataTable dt = new DataTable();
using (OleDbConnection con = new OleDbConnection(strConnect))
{
OleDbCommand cmd = new OleDbCommand("SELECT * FROM MyTable", con);
con.Open();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dt);
}
Then use SqlBulkCopy to update SQL:
string strConnect = #"Data Source=GRIFFPC\SQLEXPRESS;Initial Catalog=Testing;Integrated Security=True";
using (SqlConnection con = new SqlConnection(strConnect))
{
con.Open();
using (SqlBulkCopy bulk = new SqlBulkCopy(con))
{
bulk.DestinationTableName = "Test";
bulk.WriteToServer(dt);
}
}
Of course, there is a much easier way to go straight from Access to SQL Server, using VBA, SQL , or other methods.
https://support.office.com/en-us/article/import-or-link-to-data-in-an-sql-server-database-a5a3b4eb-57b9-45a0-b732-77bc6089b84e
https://www.sqlshack.com/six-different-methods-to-copy-tables-between-databases-in-sql-server/

Here's a basic example of bulk insert.
public void BulkInsert(DataTable employees)
{
if (employees == null)
throw new ArgumentNullException(nameof(employees), $"{nameof(employees)} is null.");
using (var con = OpenConnection())
using (var sbc = new SqlBulkCopy(con))
{
sbc.DestinationTableName = "HR.Employee";
foreach (DataColumn column in employees.Columns)
sbc.ColumnMappings.Add(column!.ColumnName, column.ColumnName);
sbc.WriteToServer(employees);
}
}
Note the foreach (DataColumn column in employees.Columns) loop. This is required so that it knows the column names are the same in the source and the target table. (If they're not the same, manually map them in the same fashion.)
Source: https://grauenwolf.github.io/DotNet-ORM-Cookbook/BulkInsert.htm#ado.net

Following option need to verify
1) Column Name should be the same.
2) verify the column length.
3) verify the data type.

Related

How do I return a table from a SQL query as a List in C#?

I have a Xamarin app that connects to a SQL Server (*), and I want to insert the data from the SQL Server's tables into a local SQLite database. My approach is to execute a query like
select * from Table1
retrieve the results of the query as a List, then insert that List into my SQLite table. That said I'm very new at using SqlClient, so please share if there are better ways to do this. Thanks.
Edit: the smallest number of columns these tables have is 5. Don't know if that disqualifies Lists as the best option.
My code:
private void LoadData()
{
string cs = #"connection string here";
using (SqlConnection sconn = new SqlConnection(cs))
{
sconn.Open();
SqlDataReader reader = null;
SqlCommand aml = new SqlCommand("select * from Table1");
reader = aml.ExecuteReader();
while (reader.Read())
{
// get result of query as List somehow?
}
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
// insert the list object
}
}
}
}
(*) The app does not use a web service as the app is intended for onsite use only and will not be distributed publicly.
A better alternative way to do it more easier is to use a ORM like dapper
With the help of dapper, all you need to do is
using (var connection = new SqlConnection(_sqlConnectionString))
{
var results = connection.Query<YourTableModel>(query).ToList();
return results;
}
You can get data from the SQL Server as DataTable or convert it to a list as you prefer.
public DataTable GetDataTable(string connectionString, string tableName)
{
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
string query = $'SELECT * FROM [{tableName}]';
SqlCommand cmd = new SqlCommand(query, conn);
DataTable t1 = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
a.Fill(t1);
}
return t1;
}
Then use this table or list returned from the above method to insert in the SQLite table.
string cs = #"Data Source=datasource;Initial Catalog=databasename;User ID=user;Password=password";
DataTable table = GetDataTable(cs, "Table1");
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
foreach(DataRow row in table.Rows)
{
//Access values of each row column row["columnName"]
// insert the list object
}
}
}
Refer to this one:
Inserting Data from SQL Server to Sqlite

How to get data from SQL and write it in textbox?

I need a help.
I searched and I tried a lot but I am too bad to make it work on my project by myself.
This is code for button-Seek. I want to make Seek-button to fill textbox by respective data.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
var Conn = new SqlConnection();
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
var Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = " + Number;
var DataAdapter = new SqlDataAdapter(Cmd);
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
}
}
And This is the data table.
This is what happens when I put 3 in the text box and press Seek-button.
So here, I want all text boxes to be filled by the data which I searched.
You will get only one row for the query right?
So give like that,
txtFirstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
txtLasttName.Text = DataSet.Tables[0].Rows[0]["LastName"].ToString();
Like this you need to assign the values to the respective text boxes.
There are three problem need to fix.
You forget to open the connection with DB,add Conn.Open(); before you excute sql command.
You need to add parameter to prevention SQL Injection
Please use using it will help you to use external resources to return the memory.
when the DataSet be filled you can get the data then fill in textbox
You can follow like this.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
using (var Conn = new SqlConnection())
{
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
using (var Cmd = new SqlCommand())
{
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = #Number";
Cmd.Parameters.AddWithValue("#Number", Number);
//You miss to add Conn.Open()
Conn.Open();
using (var DataAdapter = new SqlDataAdapter(Cmd))
{
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
//when the DataSet be filled you can get the data then fill in textbox
txt_firstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
}
}
}
}
}

Inserting variables as well as columns using SqlBulkCopy

I'm just learning and have written this code to copy data from one database to another (LOTSCON) = source, CON = destination.
The code all works and copies the data across, however it is based on checkboxes on a previous datagridview form.
The user selects which records to import, but also selects CHKCOMMUNITY which means this patient is a nursing home patient.
In the NEW table, there is a column nursinghome which is a bit type.
If the user ticks chkCommunity in the datagrid, I want to do the bulk copy but also make sure the nursinghome column in the destination table is set to 1.
So I'm not mapping an existing column in the source table..
How can I achieve this?
DO I just import then run a SQL string updating the column based on what I have just entered?
foreach (DataGridViewRow row in dataGridInst.Rows)
{
DataGridViewCheckBoxCell chkcell = row.Cells["chkimport"] as DataGridViewCheckBoxCell;
if (chkcell.Value != null)
{
if (Convert.ToBoolean(chkcell.Value) == true)
{
instid = Convert.ToInt32(row.Cells["clninstid"].Value);
iscommunity = Convert.ToInt32(row.Cells["chkcommunity"].Value);
using (SqlConnection lotscon = new SqlConnection(ConfigurationManager.ConnectionStrings["LOTSConnectionString"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(#"SELECT Person.*, NEWinstitution.institutionname
FROM NEWinstitution INNER JOIN Person ON NEWinstitution.institutionid = Person.InstitutionID
WHERE person.institutionid = #instid", lotscon))
{
cmd.Parameters.Add("#instid", SqlDbType.Int).Value = instid;
using (SqlDataAdapter adapt = new SqlDataAdapter())
{
adapt.SelectCommand = cmd;
lotscon.Open();
DataSet ds = new DataSet();
adapt.Fill(ds);
DataTable dtgenerate = new DataTable();
dtgenerate = ds.Tables[0];
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString))
{
using (SqlBulkCopy bc = new SqlBulkCopy(con))
{
bc.DestinationTableName = "tblpatient";
bc.ColumnMappings.Add("firstname", "pxfirstname");
bc.ColumnMappings.Add("lastname", "pxlastname");
bc.ColumnMappings.Add("address", "address");
bc.ColumnMappings.Add("suburb", "suburb");
bc.ColumnMappings.Add("medicareno", "medicarenumber");
bc.ColumnMappings.Add("personid", "dispenseid");
bc.ColumnMappings.Add("institutionname", "institutionname");
bc.ColumnMappings.Add("VAcardid", "repatnumber");
bc.ColumnMappings.Add("phonenumber", "phonenumber");
con.Open();
bc.WriteToServer(dtgenerate);
con.Close();
lotscon.Close();
}
}
}
}
}
}
}
}

XML data not Complete when reading from SQL Server

I'm executing an sql query through C# to fetch XML data as follows, but in the string getxml_string the XML data is not complete as compared to the data on SQL server, I feel I'm doing something wrong with the getxml_string, but can't figure out:
string getxml = "some query"
DataTable getxml_table = SQLClass.GETSQL(getxml , conn);
var doc = new XmlDocument();
string getxml_string = getxml_table.Rows.OfType<DataRow>().Select(x => x[0].ToString()).First();
doc.LoadXml(getxml_string);
In GETSQL it's nothing fancy just as follows:
public static DataTable GETSQL(string sqller, SqlConnection connection)
{
DataTable data_table = new DataTable();
connection.Open();
using (SqlCommand command = new SqlCommand(sqller, connection))
{
SqlDataAdapter adapter = new SqlDataAdapter(command );
adapter.Fill(data_table);
connection.Close();
return data_table ;
}
}
This worked for me:
List<datarow> list = getxml_table.AsEnumberable().ToList();

How to connect C# app with SQLite database

I want to connect to a SQLite database. Please show me example code which WORKS. Also I want to link datagridview with the database.I use this code but it doesn't work:
private DataTable dt;
public Form1()
{
InitializeComponent();
this.dt = new DataTable();
}
private SQLiteConnection SQLiteConnection;
private void DataClass()
{
SQLiteConnection = new SQLiteConnection("Data Source=PasswordManager.s3db;Version=3;");
}
private void GetData()
{
SQLiteDataAdapter DataAdapter;
try
{
SQLiteCommand cmd;
SQLiteConnection.Open(); //Initiate connection to the db
cmd = SQLiteConnection.CreateCommand();
cmd.CommandText = "select*from PasswordManager;"; //set the passed query
DataAdapter = new SQLiteDataAdapter(cmd);
DataAdapter.Fill(dt); //fill the datasource
dataGridView1.DataSource = dt;
}
catch(SQLiteException ex)
{
//Add your exception code here.
}
SQLiteConnection.Close();
You could use the System.Data.SQLite ADO.NET provider. Once you download and reference the assembly, it's pretty straightforward ADO.NET code:
using (var conn = new SQLiteConnection(#"Data Source=test.db3"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(reader.GetOrdinal("id"));
...
}
}
}
In addition to the answer provided by Darin, there is no "create database" command in SQLite (from what I remember). When you initiate a "SQLiteConnection", if the given database (.db3) does not exist, it automatically creates it... from there, you can then create your tables.

Categories