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();
}
}
}
}
}
}
}
}
Related
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.
I am coding win form app, which checks on startup right of the currently logged user. I had these right saved in MS SQL server in the table. When importing data to Datatable, there is no problem. But when I want to read value, there is message "cannot find column xy".
SqlDataAdapter sdaRights = new SqlDataAdapter("SELECT * FROM rights WHERE [user]='" + System.Security.Principal.WindowsIdentity.GetCurrent().Name + "'", conn);
DataTable dtRights = new DataTable(); //this is creating a virtual table
sdaRights.Fill(dtRights);
Object cellValue = dt.Rows[0][1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
I would like, that program would save the value from SQL to int.
You are assuming that you have rows being returned, would be my first guess. You should loop through your DataTable instead of simply trying to access element 0 in it.
DataTable dtRights = new DataTable();
sdaRights.Fill(dtRights);
foreach(DataRow row in dtRights.Rows) {
Object cellValue = row[1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
}
using (SqlConnection con = new SqlConnection("your connection string"))
{
using (SqlCommand cmd = new SqlCommand("SELECT [column_you_want] FROM [rights] WHERE [user] = #user"))
{
cmd.Parameters.AddWithValue("#user", System.Security.Principal.WindowsIdentity.GetCurrent().Name);
con.Open();
int right = Convert.ToInt32(cmd.ExecuteScalar());
}
}
When I check more than one item in the CheckedListBox, than it only gets the Selected.Value of the last selected item and uses that for the amount of times the foreach is used.
Extra context: It's an application that can put exercises on certain days, so it's a workout app, but when you select more than 1 exercise in the CheckedListBox, than it only adds items with the last selected value.
So selects 3 different items(pushups, pullups, situps) --> 3 situps get added with all the same values.
Code that adds exercises to the other normal ListBox:
query = "INSERT INTO Xercise_Day (DayId, ExerciseId) " +
"VALUES(#DayId, #ExerciseId)";
foreach (CheckedListBox exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", clbXcercises.SelectedValue);
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}
for(int i = 0; i < clbXcercises.Items.Count; i++)
{
clbXcercises.SetItemChecked(i, false);
}
As stated in the comments, reference exercise instead of clbXcercises to get the selected value. The code becomes:
foreach (object exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", exercise.ToString());
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}
I have a table in MS Access where few columns are memo datatype.Using c# code, I am reading data from that table and creating a list.That list i am binding with a datagridview.I am able to read the data from each row of the ms access table rows but whereever large data is available it it unable to read the complete data. Any suggestion please?
Here is the code what i am trying. It's getting the data, but for each cell few data only reading, not all:
List<RavasCustomOptional> lstAllAccessories = new List<RavasCustomOptional>();
using (OleDbConnection cn = new OleDbConnection(connectionstring))
{
OleDbCommand cmd = new OleDbCommand(query, cn);
cn.Open();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
if (ds.Tables.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
RavasCustomOptional aRavasOptional = new RavasCustomOptional();
aRavasOptional.OptionalId = Convert.ToInt32(dr["pk_aid"].ToString().Substring(1));
aRavasOptional.OptionalCustomId = dr["pk_aid"].ToString();
aRavasOptional.OptionalMake = dr["c_make"].ToString();
aRavasOptional.OptionalName = dr["c_nam"].ToString();
aRavasOptional.OptionalDescription = dr["c_des"].ToString();
aRavasOptional.OptionalPrice = dr["c_pri"].ToString();
string optionalOtherDescription = dr["OtherDesc"].ToString();
aRavasOptional.OptionalOtherDescription = optionalOtherDescription.Replace("•", Environment.NewLine + "• ");
aRavasOptional.OptionalRemark = dr["c_remark"].ToString();
aRavasOptional.OptionalForProductId = dr["c_pid"].ToString();
aRavasOptional.OptionalForProductModel = dr["c_mod"].ToString();
lstAllAccessories.Add(aRavasOptional);
}
}
}
i am working on visual studio 2012 c# ...
i inserted values into the combox ...i took them from database...I WANT TO KNOW HOW CAN I ADD AN ITEM TO THE COMBOBOX ...ill show u the code below:
Here this function to fill the combobox with names taken from a table in database containig name and id:
List<Lookup> fillCombo(string query, string column)
{
List<Lookup> lookups = new List<Lookup>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Lookup lookupobject = new Lookup();
lookupobject.ID = Convert.ToInt32(reader["ID"]);
//if (reader["Name"] != DBNull.Value)
lookupobject.Name = reader[column].ToString();
lookups.Add(lookupobject);
}
conn.Close();
}
return lookups;
}
then i call this function as follows:
lookups = fillCombo("select id,name from LookupDetails where LOOKUPID = (select id from Lookup where Name = 'users')", "name");
comboBox2.DataSource = lookups;
comboBox2.DisplayMember = "name";
ComboxBox Items collection cannot be modified when the DataSource property is set.
You got the options of either modifying the List<Lookup> or by adding items into combox by iterating over the List<Lookup>.
Here is option to add items in combobox using foreach loop and insert item at 0 index of comboxbox:
lookups = fillCombo(#"select id,name from LookupDetails where LOOKUPID =
(select id from Lookup where Name = 'users')", "name");
foreach(var obj in lookups)
comboBox2.Items.Add(obj);
comboBox2.DisplayMember = "Name";
comboBox2.Items.Insert(0, "");
Note: In the code mentioned in the question, SqlDataReader was never closed, I have modified it by including using statement. You don't have to close SqlDataReader or SqlConnection when you write these in using block:
List<Lookup> fillCombo(string query, string column)
{
List<Lookup> lookups = new List<Lookup>();
string sConstring = ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(sConstring))
using(SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Lookup lookupobject = new Lookup();
lookupobject.ID = Convert.ToInt32(reader["ID"]);
//if (reader["Name"] != DBNull.Value)
lookupobject.Name = reader[column].ToString();
lookups.Add(lookupobject);
}
}
}
return lookups;
}