Trying to insert a new record into an MS Access .accdb file. When I run the code below, it appears to work fine. No errors are presented, but nothing updates in the database file either. I have verified that the database is in an accessible location.
selectedNote is an object with the three listed parameters. The only field I'm not including in the query string is the ID field which is autonumber.
string scon = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = |DataDirectory|AMS.accdb";
string str = "INSERT INTO Notes ([ItemID], [Note], [Note Date]) VALUES (?, ?, ?)";
try
{
using (OleDbConnection con = new OleDbConnection(scon))
{
using (OleDbCommand cmd = new OleDbCommand(str, con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("ItemID", selectedNote.ItemID);
cmd.Parameters.AddWithValue("Note", selectedNote.Note);
cmd.Parameters.AddWithValue("Note Date", selectedNote.NoteDate.ToString("dd-MM-yy"));
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
Thanks all, hopefully I can get this hammered out.
EDIT: Curiously, I just found that if I hard-code a path to the .accdb file with a line like the following, it actually does write to that file. So I guess the question becomes why is it not working on the build path where the database is in the same path as the exe.
AppDomain.CurrentDomain.SetData("DataDirectory","C:\temp");
I have tried setting DataDirectory to something like AppDomain.CurrentDomain.BaseDirectory, but this doesn't seem to work either.
A date should not be inserted as text, and you do have the DateTime value, thus:
cmd.Parameters.AddWithValue("Note Date", selectedNote.NoteDate);
Here's what I'm trying to accomplish ... At the click of a button, I want to:
Copy existing data of the live "users" table to "old_users" table for backup purposes
Truncate the existing "new_users" table to prepare it to accept new rows
Parse through a CSV file to insert data into the "new_users" table
Truncate the existing "users" table and then copy data of the "new_users" table to "users" table
I am not a daily programmer and haven't created a program in a very long time. But I've piece-mealed some code together to get something that kinda works. Below is my current code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic.FileIO;
using Renci.SshNet;
using Renci.SshNet.Common;
using MySql.Data.MySqlClient;
namespace ValidationImport
{
public partial class ValiationImport : Form
{
public ValiationImport()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btnImportToDatabase_Click(object sender, EventArgs e)
{
try
{
using (var client = new SshClient("1.1.1.1", "[username]", "[password]")) // establishing ssh connection to server where MySql is hosted
{
client.Connect();
if (client.IsConnected)
{
var portForwarded = new ForwardedPortLocal("127.0.0.1", 3306, "127.0.0.1", 3306);
client.AddForwardedPort(portForwarded);
portForwarded.Start();
using (MySqlConnection con = new MySqlConnection("SERVER=localhost;PORT=3306;UID=[username];PASSWORD=[password];DATABASE=[dbname]")) // MySql database credentials
{
con.Open();
// Copying over the users table (with structure and indexes) to the old_users table. Truncating the new_users table to prepare for new data.
using (MySqlCommand cmd = new MySqlCommand("DROP TABLE test_old_users; CREATE TABLE test_old_users LIKE test_users; INSERT test_old_users SELECT * FROM test_users; TRUNCATE TABLE test_new_users;", con))
{
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
string fileName = "";
// Select the Validation file to import
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
fileName = dlg.FileName;
if (fileName != "")
{
using (TextFieldParser parser = new TextFieldParser(fileName))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters("|");
parser.ReadLine(); // Skip the first row of field title headers
while (!parser.EndOfData)
{
//Copy each row individually over to the MySql table
string[] row = parser.ReadFields();
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO test_new_users (`Indv Id`, `Last Name`, `First Name`, `Middle Name`, `Birth date`, `Indv Addr Line 1`, `Indv Addr Line 2`, `Indv Addr Line 3`, `Indv City`, `Indv State`, `Indv Zip`, `Indv Country`, `Local Id`, `Local Name`, `Local User Id`, `Uniserv Id`, `Uniserv Name`, `Uniserv User Id`, `Chapter Name`, `Chapter User Id`, `Employer Id`, `Employer Name`, `Work Location Id`, `Work Location Name`, `Work Location User Id`, `Group Id`, `Group Name`, `Group Type Id`, `Group Type Name`, `SEA P01`, `Home Phone`, `Home Phone principal Ind`, `Home Phone Unlisted Ind`, `Mobile Phone`, `Mobile Phone Principal Ind`, `Mobile Phone Unlisted Ind`, `Home Email`, `Home Email Principal Ind`, `Work Email`, `Work Email Principal Ind`, `Other Email`, `Other Email Principal Ind`) VALUES (#IndvId, #LastName, #FirstName, #MiddleName, #BirthDate, #IndvAddrLine1, #IndvAddrLine2, #IndvAddrLine3, #IndvCity, #IndvState, #IndvZip, #IndvCountry, #LocalId, #LocalName, #LocalUserId, #UniservId, #UniservName, #UniservUserId, #ChapterName, #ChapterUserId, #EmployerId, #EmployerName, #WorkLocationId, #WorkLocationName, #WorkLocationUserId, #GroupId, #GroupName, #GroupTypeId, #GroupTypeName, #SEAP01, #HomePhone, #HomePhonePrincipalInd, #HomePhoneUnlistedInd, #MobilePhone, #MobilePhonePrincipalInd, #MobilePhoneUnlistedInd, #HomeEmail, #HomeEmailPrincipalInd, #WorkEmail, #WorkEmailPrincipalInd, #OtherEmail, #OtherEmailPrincipalInd);", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#IndvId", row[0]);
cmd.Parameters.AddWithValue("#LastName", row[1]);
cmd.Parameters.AddWithValue("#FirstName", row[2]);
cmd.Parameters.AddWithValue("#MiddleName", row[3]);
cmd.Parameters.AddWithValue("#BirthDate", row[4]);
cmd.Parameters.AddWithValue("#IndvAddrLine1", row[5]);
cmd.Parameters.AddWithValue("#IndvAddrLine2", row[6]);
cmd.Parameters.AddWithValue("#IndvAddrLine3", row[7]);
cmd.Parameters.AddWithValue("#IndvCity", row[8]);
cmd.Parameters.AddWithValue("#IndvState", row[9]);
cmd.Parameters.AddWithValue("#IndvZip", row[10]);
cmd.Parameters.AddWithValue("#IndvCountry", row[11]);
cmd.Parameters.AddWithValue("#LocalId", row[12]);
cmd.Parameters.AddWithValue("#LocalName", row[13]);
cmd.Parameters.AddWithValue("#LocalUserId", row[14]);
cmd.Parameters.AddWithValue("#UniservId", row[15]);
cmd.Parameters.AddWithValue("#UniservName", row[16]);
cmd.Parameters.AddWithValue("#UniservUserId", row[17]);
cmd.Parameters.AddWithValue("#ChapterName", row[18]);
cmd.Parameters.AddWithValue("#ChapterUserId", row[19]);
cmd.Parameters.AddWithValue("#EmployerId", row[20]);
cmd.Parameters.AddWithValue("#EmployerName", row[21]);
cmd.Parameters.AddWithValue("#WorkLocationId", row[22]);
cmd.Parameters.AddWithValue("#WorkLocationName", row[23]);
cmd.Parameters.AddWithValue("#WorkLocationUserId", row[24]);
cmd.Parameters.AddWithValue("#GroupId", row[25]);
cmd.Parameters.AddWithValue("#GroupName", row[26]);
cmd.Parameters.AddWithValue("#GroupTypeId", row[27]);
cmd.Parameters.AddWithValue("#GroupTypeName", row[28]);
cmd.Parameters.AddWithValue("#SEAP01", row[29]);
cmd.Parameters.AddWithValue("#HomePhone", row[30]);
cmd.Parameters.AddWithValue("#HomePhonePrincipalInd", row[31]);
cmd.Parameters.AddWithValue("#HomePhoneUnlistedInd", row[32]);
cmd.Parameters.AddWithValue("#MobilePhone", row[33]);
cmd.Parameters.AddWithValue("#MobilePhonePrincipalInd", row[34]);
cmd.Parameters.AddWithValue("#MobilePhoneUnlistedInd", row[35]);
cmd.Parameters.AddWithValue("#HomeEmail", row[36]);
cmd.Parameters.AddWithValue("#HomeEmailPrincipalInd", row[37]);
cmd.Parameters.AddWithValue("#WorkEmail", row[38]);
cmd.Parameters.AddWithValue("#WorkEmailPrincipalInd", row[39]);
cmd.Parameters.AddWithValue("#OtherEmail", row[40]);
cmd.Parameters.AddWithValue("#OtherEmailPrincipalInd", row[41]);
cmd.ExecuteNonQuery();
}
}
}
}
// Copying over the new_users table (with structure and indexes) to the users table.
using (MySqlCommand cmd = new MySqlCommand("DROP TABLE test_users; CREATE TABLE test_users LIKE test_new_users; INSERT test_users SELECT * FROM test_new_users;", con))
{
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
con.Close();
}
client.Disconnect();
}
else
{
Console.WriteLine("Client cannot be reached...");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
It's all "working" ... except I get an error when in debug mode in visual studio. Something about how it's taking too long to process. Oh, just so you know, there's around 38,000 rows in the CSV file that has to be inserted into the table.
If you have any suggestions or new code for me to try out, I'd greatly appreciate it! Thank you!
In many scenarios where you end up looping over data running the same queries repeatedly for different data, you can help speed things up by preparing the query once, before looping begins.
using (var cn = new MySqlConnection(...))
using (var cmd = cn.CreateCommand())
{
// Setup command
cmd.CommandText = "Some query";
var param1 = cmd.Parameters.Add("#paramName1", MySQLDbType.sometype);
var param2 = cmd.Parameters.Add("#paramName2", MySQLDbType.sometype);
cmd.Prepare();
// get data
// loop over data
foreach(var d in data)
{
param1.Value = d.somevalue;
param2.Value = d.anothervalue;
cmd.ExecuteNonQuery();
}
}
You can also address the parameters by index, like cmd.Parameters[0].Value.
Preparing the statement in this manner reduces the overhead of the work done to parse the query itself every iteration.
In one situation I had to deal with, I found the best solution was to combine the above with an INSERT query that used multiple values lists, of the form INSERT INTO X(a,b,c) VALUES (?,?,?),(?,?,?),(?,?,?). It made the actual implementation much more complicated (having to appropriately handle the "leftovers" at the end that would not fill all values lists), and relied on addressing the parameters by index; but did make a difference.
Edit: pseudo code to handle ssh connection closing on you
connect = true
Open datasource
while (data remains)
{
if (connect)
{
init ssh client
init mysql connection
init mysql command
connect = false
}
while (data remains and enough time remaining)
{
get next data
set command parameters
execute command
}
if (not enough time remaining)
{
close current connection and client
connect = true
}
}
I've been trying to add a row to my SQL CE & nothing works I've tried many things I found here at SO or in other websites by googling but to no avail.
Below if the code I have at the moment.
It compiles and executes with no problem, but nothing is added to the table and no exception is thrown.
Could anyone please provide a solution for this ?
string conString = Properties.Settings.Default.TestConnectionString;
using (SqlCeConnection connect = new SqlCeConnection(conString))
{
connect.Open();
string text = "UsernameTest";
string pass = "PasswordTest";
using (SqlCeCommand command = new SqlCeCommand("insert into MyTable values (#Username, #Password)", connect))
{
command.Parameters.AddWithValue("#Username", text);
command.Parameters.AddWithValue("#Password", pass);
command.ExecuteNonQuery();
}
}
Please do not comment about storing a password in plain text, this was just a test.
I'm trying to save Excel files into the database, I do not want to use filestream as it is required to have a server for that.
So how do I insert/update/select into the table that has a column of type varbinary(max)?
If you want to do it in straight ADO.NET, and your Excel files aren't too big so that they can fit into memory at once, you could use these two methods:
// store Excel sheet (or any file for that matter) into a SQL Server table
public void StoreExcelToDatabase(string excelFileName)
{
// if file doesn't exist --> terminate (you might want to show a message box or something)
if (!File.Exists(excelFileName))
{
return;
}
// get all the bytes of the file into memory
byte[] excelContents = File.ReadAllBytes(excelFileName);
// define SQL statement to use
string insertStmt = "INSERT INTO dbo.YourTable(FileName, BinaryContent) VALUES(#FileName, #BinaryContent)";
// set up connection and command to do INSERT
using (SqlConnection connection = new SqlConnection("your-connection-string-here"))
using (SqlCommand cmdInsert = new SqlCommand(insertStmt, connection))
{
cmdInsert.Parameters.Add("#FileName", SqlDbType.VarChar, 500).Value = excelFileName;
cmdInsert.Parameters.Add("#BinaryContent", SqlDbType.VarBinary, int.MaxValue).Value = excelContents;
// open connection, execute SQL statement, close connection again
connection.Open();
cmdInsert.ExecuteNonQuery();
connection.Close();
}
}
To retrieve the Excel sheet back and store it in a file, use this method:
public void RetrieveExcelFromDatabase(int ID, string excelFileName)
{
byte[] excelContents;
string selectStmt = "SELECT BinaryContent FROM dbo.YourTableHere WHERE ID = #ID";
using (SqlConnection connection = new SqlConnection("your-connection-string-here"))
using (SqlCommand cmdSelect = new SqlCommand(selectStmt, connection))
{
cmdSelect.Parameters.Add("#ID", SqlDbType.Int).Value = ID;
connection.Open();
excelContents = (byte[])cmdSelect.ExecuteScalar();
connection.Close();
}
File.WriteAllBytes(excelFileName, excelContents);
}
Of course, you can adapt this to your needs - you could do lots of other things, too - depending on what you really want to do (not very clear from your question).
It depends on the data access technology you are using. For example, if you use Entity Framework, you can just save a byte array into the database using objects.
I have found a starting point below, but I worry that I can miss calls to CreateDbBackup() and RestoreDbBackup(). I was hoping that I could write and use an attribute on my tests. Is this possible? How? I am using MSTest library and C# 4.0.
http://www.linglom.com/2008/01/12/how-to-backup-and-restore-database-on-microsoft-sql-server-2005/
internal void CreateDbBackup()
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myConStr"].ConnectionString))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = string.Format(#"BACKUP DATABASE [MyDatabase] TO DISK = N'{0}' WITH INIT , NOUNLOAD , NOSKIP , STATS = 10, NOFORMAT", UtilityClassGeneral.DbBackupPath);
con.Open();
cmd.ExecuteNonQuery();
}
}
internal void RestoreDbFromBackup()
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myConStr"].ConnectionString))
{
SqlCommand cmd = con.CreateCommand();
con.Open();
// Make sure to get exclusive access to DB to avoid any errors
cmd.CommandText = "USE MASTER ALTER DATABASE [MyDatabase] SET SINGLE_USER With ROLLBACK IMMEDIATE";
cmd.ExecuteNonQuery();
cmd.CommandText = string.Format(#"RESTORE DATABASE [MyDatabase] FROM DISK = N'{0}' WITH FILE = 1, NOUNLOAD , STATS = 10, RECOVERY , REPLACE", UtilityClassGeneral.DbBackupPath);
cmd.ExecuteNonQuery();
}
}
Have a look at SQL Server Management Objects (SMO). You should be able to use this to backup and restore SQL Server databases.