I have been over my code numerous times and hope someone can help me see something I don't. I'm trying to pull data from Excel into a SQL table with multiple columns in VS2010 but when I try uploading the data, I get the error "Cannot Find Column 8." I see nothing wrong with column 8 nor any of the other columns. Anyone else? Thanks!
protected void Button1_Click(object sender, EventArgs e)
{
//make local copy
string sheetname = "Sheet1";
string path = Server.MapPath("~/Import.xls");
//connect to local Excel
try
{
FileUpload.SaveAs(path);
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.DataSet DtSet;
System.Data.OleDb.OleDbDataAdapter MyCommand; //check sheet name
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;");
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + sheetname + "$]", MyConnection);
MyCommand.TableMappings.Add("Table", "TestTable");
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
SqlConnection curConnection = new SqlConnection(#"Data Source=1tc-Techcomm2;Initial Catalog=EventManagement;Integrated Security=True");
curConnection.Open();
SqlCommand curCommand;
SqlParameter param;
string str;
for (int i = 0; i < DtSet.Tables[0].Rows.Count; i++)
{
if (DtSet.Tables[0].Rows[i][1] == DBNull.Value)
continue;
curCommand = curConnection.CreateCommand();
curCommand.CommandText = #"Insert into TestSP (SessionHead_Title, SessionHead_Type, SessionHead_Description, SessionHead_Confirmed, SessionHead_Presenter, SessionHead_Champion, SessionHead_Objective, SessionHead_Notes, SessionHead_Schedule, SessionHead_Equipment, SessionHead_Hardware, SessionHead_CDA) Values (#a,#b,#c,#d,#e,#f,#g,#h,#i,#j,#k,#l,#m)";
for (int j = 0; j < 13; j++)
{
param = new SqlParameter();
str = "#";
str += (char)('a' + j);
param.ParameterName = str;
param.SqlDbType = SqlDbType.VarChar;
param.Value = DtSet.Tables[0].Rows[i][j];//This is where it errors out at after 8 times through
curCommand.Parameters.Add(param);
}
Label1.Text = "THE EXCEL DATE HAS SUCCESSFULLY BEEN SENT TO THE DATABASE";
int Event_Id = curCommand.ExecuteNonQuery();
}
MyConnection.Close();
curConnection.Close();
}
catch (Exception ex)
{
//Response.Write(ex.ToString());
Label1.Text = ex.Message;
}
}
I believe the issue was that the spreadsheet column headers did not match the table headers. I read somewhere that the Column names in SQL Server table must be the same in the Excel file. I guess this solves it...thanks for the help!
If you know the structure of your Table on the SQL Server, Try using the SqlBulkCopy. Map your columns and write it to the server. You already have the data in your DataSet.
SqlBulkCopy _bc = new SqlBulkCopy(curConnection);
_bc.DestinationTableName = "TestSP";
_bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping("DataTableColumnName1", "SQLServerColumnName1");
_bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping("DataTableColumnName2", "SQLServerColumnName2");
_bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping("DataTableColumnName3", "SQLServerColumnName3");
_bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping("DataTableColumnName4", "SQLServerColumnName4");
_bc.WriteToServer(DtSet.Tables[0]);
You can still use this process if you don't know the structure but you will have to get creative. I had to do that and it was pretty fun.
The solution of user3611272 helped me:
... i tried to append some random table and went to "Advanced Options" at the bottom of the append pop up in this u will see some "Stored Column mappings" and some mappings in it, now delete all of them the relevant mapping and hit "Accept" now u can append the table
Related
My task should be quite simple but after hours and hours I must admit I'm completely stuck!
I simply want to delete a datarow from a datatable. My datatable is a copy of the table in my current dataset in a SQLite databank. It is mandatory to use the table.row.Delete() method. I am aware that delete() just marks the row to be deleted upon table update.
Below is the code I'm currently using:
I retrieve my data via:
public DataTable GetTable(string tableName)
{
string connectionPath = dbVariables.ConnectionString;
try
{
SQLiteConnection myConnection = new SQLiteConnection(connectionPath);
myConnection.Open();
string cmdStr = "SELECT * FROM " + tableName;
DataTable myTable = new DataTable();
SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(cmdStr, myConnection);
myAdapter.FillSchema(myTable, SchemaType.Source);
myTable.Columns[dbVariables.ClassesID].AutoIncrement = true;
myTable.Columns[dbVariables.ClassesID].AutoIncrementSeed = 1;
myTable.Columns[dbVariables.ClassesID].AutoIncrementStep = 1;
myAdapter.Fill(myTable);
myConnection.Close();
return myTable;
}
catch (SQLiteException e)
{
MessageBox.Show(e.ToString());
return null;
}
}
Here I manipulate my data:
if (myResult == DialogResult.Yes)
{
//killTable.AcceptChanges();
DataRow[] dr = killTable.Select("" + cmVariables.ClassName + " = '" + cmbClasses.Text + "'");
//First I need to evaluate the row index of the row I want to delete
string indexName = (killTable.Rows.IndexOf(dr[0])).ToString();
int i = Int32.Parse(indexName);
// And we are done - I got my row index
DataRow modifiedRow = killTable.Rows[i];
killTable.Rows[i].Delete();
//I inserted this messagebox just to see the rowstatus - and yes, it is marked as deleted on runtime...
MessageBox.Show(killTable.Rows[i].RowState);
// I refer to this in the text below
killTable.AcceptChanges();
killClass_Execution(killTable, cmbClasses.Text, ShortClassNm);
}
And at least the code to update my datatable back to the databank:
public void UpdateTable(string tableName, DataTable sourceTable, bool newOrEdit)
{
try
{
string connectionPath = dbVariables.ConnectionString;
//Connection erstellen --> der connectString gibt dabei den Pfad an.
SQLiteConnection myConnection = new SQLiteConnection(connectionPath);
myConnection.Open();
//Einen Befehls-String erstellen, der das UPDATE-Command auslöst
// UPDATE cm_ClassTest SET className = userEditInput WHERE className = 'oldClassName'
string myUpdateString = "SELECT * FROM " + tableName + "";
SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myUpdateString, myConnection);
SQLiteCommandBuilder comBuild = new SQLiteCommandBuilder(myAdapter);
myAdapter.DeleteCommand = comBuild.GetDeleteCommand(true);
myAdapter.UpdateCommand = comBuild.GetUpdateCommand(true);
myAdapter.InsertCommand = comBuild.GetInsertCommand(true);
myAdapter.Update(sourceTable);
myConnection.Close();
if (newOrEdit == true)
{
MessageBox.Show("Klasse erstellt!");
}
else
{
MessageBox.Show("Klasse aktualisiert!");
}
}
catch (SQLiteException e)
{
MessageBox.Show(e.ToString());
}
}
In the code block for manipulating data you will find the AcceptChanges() method. At this time, there may have been no other changes appeared to my datatable - so after app start, deleting a row may be the users first action.
Also: each entry in my dataset is unique (school classes that are labeled with a unique class name).
Any help will be highly appreciated!
Regards,
Aran
OK - so I succeeded (finally). Debugging showed no issues, except for AcceptChanges() which got a call but did not result in actually deleting the dataRow.
All I can think of right now is that my primary approach to it was part of the problem: I get my DataTable right from the DataBase, do all the manipulations with it, and then send it back to DB via Update (see my update method above). The SQLite CommandBuilder seems not capable of interpreting my DAtaRow which is by then flagged 'Deleted', but kind of rubber-stamps it to the end of the method without throwing an exception.
By doing so I tried the GetChanges-Method:
DataRow[] dr = killTable.Select("" + cmVariables.ClassName + " = '" + cmbClasses.Text + "'");
string indexName = (killTable.Rows.IndexOf(dr[0])).ToString();
int i = Int32.Parse(indexName);
killTable.Rows[i].Delete();
DataTable killItTable = killTable.GetChanges(DataRowState.Deleted);
killClass_Execution(killItTable, cmbClasses.Text, ShortClassNm);
Now it's working - the copy of killTable (killItTable - stupid I know, but first thing I do tomorrow morning is give it better names :) ) provides info for the sql commandbuilder which seems to be recognized by it.
Whatever it is - it now works.
I think this is not supposed to happen - if someone can come up with any good suggestions, on how to improve my approach, I shall be glad.
best regards
I'm writing a windows form that populates a DataTable and I want it to insert into an Oracle Table. I've seen some examples here that use the OracleDataAdapter to do this so I don't have to loop through all the records. The code doesn't have any errors but when I check the Table using Toad(I did refresh) I don't see it. I used the example below
Update and insert records into Oracle table using OracleDataAdapter from DataTable
Here is how my DataTable is made:
public DataTable dtMain = new DataTable();
public void FillTable(DataTable dt)
{
dtMain.Columns.Add("SERIAL", typeof(System.String));
dtMain.Columns.Add("LOCATION", typeof(System.String));
dtMain.Columns.Add("UPC", typeof(System.String));
dtMain.Columns.Add("PRODUCT", typeof(System.String));
dtMain.Columns.Add("CREATED_BY", typeof(System.String));
dtMain.Columns.Add("CREATED_DATE", typeof(System.DateTime));
dtMain.Columns.Add("SKU", typeof(System.String));
dtMain.Columns.Add("MAN_DATE", typeof(System.DateTime));
dtUpload.Columns[0].Unique = true;
dtMain.Merge(dt);
}
This is the how I'm trying to insert into the database
private void btnUpload_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
string strSelect = "SELECT serial, upc, man_date, location, product, created_by, created_date, serial from schema.table where rownum < 2";
string strInsert = "INSERT INTO schema.table (serial, upc, man_date, location, product, created_by, created_date, serial) VALUES (:serial, :upc, :man_date, :location, :product, :created_by, :created_date, :serial)";
string conStr = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
OracleConnection connection = new OracleConnection(conStr);
connection.Open();
if (connection.State != ConnectionState.Open)
{
return;
}
try
{
OracleDataAdapter adapterS = new OracleDataAdapter();
adapterS.SelectCommand = new OracleCommand(strSelect, connection);
adapterS.Fill(dt);
dt.Rows.Remove(dt.Rows[0]);
dt.Merge(dtUpload);
}
catch (Exception ex)
{
string x = ex.Message + ex.StackTrace;
throw;
}
for (int i = 0; dt.Rows.Count > i; i++)
{
OracleDataAdapter adapter = new OracleDataAdapter();
adapter.InsertCommand = new OracleCommand(strInsert, connection);
adapter.InsertCommand.BindByName = true;
OracleParameter pSerial = new OracleParameter(":serial", OracleDbType.Varchar2);
pSerial.SourceColumn = dt.Columns[0].ColumnName;
pSerial.Value = dtUpload.Rows[i][0];
OracleParameter pLocation = new OracleParameter(":location", OracleDbType.Varchar2);
pLocation.SourceColumn = dt.Columns[1].ColumnName;
pLocation.Value = dtUpload.Rows[i][1];
OracleParameter pUPC = new OracleParameter(":upc", OracleDbType.Date);
pUPC.SourceColumn = dt.Columns[2].ColumnName;
pUPC.Value = dtUpload.Rows[i][2];
OracleParameter pProduct = new OracleParameter(":product", OracleDbType.Varchar2);
pProduct.SourceColumn = dt.Columns[3].ColumnName;
pProduct.Value = dtUpload.Rows[i][3];
OracleParameter pCreatedBy = new OracleParameter(":created_by", OracleDbType.Varchar2);
pCreatedBy.SourceColumn = dt.Columns[4].ColumnName;
pCreatedBy.Value = dtUpload.Rows[i][4];
OracleParameter pCreatedDate = new OracleParameter(":created_date", OracleDbType.Varchar2);
pCreatedDate.SourceColumn = dt.Columns[5].ColumnName;
pCreatedDate.Value = dtUpload.Rows[i][5];
OracleParameter pSKU = new OracleParameter(":SKU", OracleDbType.Date);
pSKU.SourceColumn = dt.Columns[6].ColumnName;
pSKU.Value = dtUpload.Rows[i][6];
OracleParameter pManDate = new OracleParameter(":man_date", OracleDbType.Varchar2);
pManDate.SourceColumn = dt.Columns[7].ColumnName;
pManDate.Value = dtUpload.Rows[i][7];
adapter.InsertCommand.Parameters.Add(pSerial);
adapter.InsertCommand.Parameters.Add(pLocation);
adapter.InsertCommand.Parameters.Add(pUPC);
adapter.InsertCommand.Parameters.Add(pProduct);
adapter.InsertCommand.Parameters.Add(pCreatedBy);
adapter.InsertCommand.Parameters.Add(pCreatedDate);
adapter.InsertCommand.Parameters.Add(pserial);
adapter.InsertCommand.Parameters.Add(pManDate);
}
try
{
adapter.Update(dt);
}
catch (Exception ex)
{
string x = ex.Message + ex.StackTrace;
throw;
}
connection.Close();
connection.Dispose();
}
If someone can give me some pointers that would be great, I've been Googling for 2 days and I just can't figure it out. I bet it's something simple
Update:
Thank you for the reply, it took me a bit to get back to this project. When I posted this I didn't realize I forgot to include my select statement.
For the OracleParameter value, I thought using SourceColumn would use that column for the values.
I did update the DataTable with the serial being unique. It still doesn't insert the data. If I included the Parameter.value would I have loop row by row to do this? Above I corrected/updated it with the current code.
Second Update:
Ok, I tried looping through the parameters to add the values from the DataTable, no errors but still not inserting in the database. I know my connectionstring is correct because the select query works. The code above has been updated for the changes I made. If some Oracle guru can shed some light on my problem a virtual high-five is waiting for them.
I never used OracleDataAdapter but I see these possible issues:
I don't think you can use OracleDataAdapter straight away, first you have to select an existing table from Oracle and based on this result you can do Update/Insert/Delete on it. Where is your strSelect string? I don't see it.
You created all the OracleParameter but I don't see that you assign any value to it, they are all empty. I would expect something like pOptoroLP.Value = ...; before you make any insert.
You should define a unique, resp. Primary Key column like dt.Columns["SERIAL"].Unique = true; in order to make Update() or Delete(). Maybe it is not required for Insert(), I don't know.
Did you follow the examples in Data Provider for .NET Developer's Guide
I finally found the problem, the row state in the DataTable needs to in the state of Added for it to work. If someone else has this problem here is my new code and you can compare it to what I was trying to do. Thank you Wernfried Domscheit for the Oracle part but it turned out to be my DataTable was the issue though setting the Unique column was probably an issue as well, I didn't check. The OracleCommandBuilder took care of the insert statements and parameters for me.
private void btnUpload_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
string strSelect = "SELECT serial, upc, man_date, location, product, created_by, created_date, serial from schema.table where rownum < 2";
string strInsert = "INSERT INTO schema.table (serial, upc, man_date, location, product, created_by, created_date, serial) VALUES (:serial, :upc, :man_date, :location, :product, :created_by, :created_date, :serial)";
string conStr = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
OracleConnection connection = new OracleConnection(conStr);
connection.Open();
if (connection.State != ConnectionState.Open)
{
return;
}
OracleDataAdapter adapter = new OracleDataAdapter(strSelect, conStr);
OracleCommandBuilder builder = new OracleCommandBuilder(adapter);
adapter.Fill(dt);
dt.Columns["SERIAL"].Unique = true;
dt.Merge(dtUpload);
dt.Rows.Remove(dt.Rows[0]);
foreach (DataRow row in dt.Rows)
{
row.SetAdded();
}
try
{
adapter.Update(dt);
}
catch (Exception ex)
{
string x = ex.Message + ex.StackTrace;
throw;
}
finally
{
connection.Close();
connection.Dispose();
}
}
Sorry for my spelling, I create so C# form application with local database. I created simple code which worked fine:
SqlCeConnection conn = new SqlCeConnection("Data Source = 4.sdf");
Microsoft.Office.Interop.Excel.Application xls = new Microsoft.Office.Interop.Excel.Application();
Workbook vb = xls.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet vs = (Worksheet)xls.ActiveSheet;
String t = "SELECT d.[regnr], d.[dalisid],d.[kiekis],d.[kaina] FROM [bilietas] AS b, [dalispard] AS d WHERE b.[regnr]=d.[regnr]";
SqlCeCommand cmd = new SqlCeCommand(t, conn);
conn.Open();
SqlCeDataReader rdr = cmd.ExecuteReader();
int i=2;
object aa, bb, cc, dd;
vs.Cells[1, 1] = "Reg. NR.";
vs.Cells[1, 2] = "Dalies ID";
vs.Cells[1, 3] = "Kiekis";
vs.Cells[1, 4] = "Kaina";
try
{
while (rdr.Read())
{
aa = rdr.GetValue(0);
bb = rdr.GetValue(1);
cc = rdr.GetValue(2);
dd = rdr.GetValue(3);
vs.Cells[i, 1] = aa.ToString();
vs.Cells[i, 2] = bb.ToString();
vs.Cells[i, 3] = cc.ToString();
vs.Cells[i, 4] = dd.ToString();
i++;
}
}
finally { conn.Close(); rdr.Close(); }
xls.Visible = true;
it bugged and started write emty cells on excel file when I edited input button for refreshing datagridview when input to table are saved by adding:
string eilute = "SELECT * FROM bilietas";
SqlCeCommand cmdd = new SqlCeCommand(eilute, conn);
conn.Open();
try
{
dt.Load(cmdd.ExecuteReader());
BindingSource bs = new BindingSource();
bs.DataSource = dt;
bilietasDataGridView.DataSource = bs;
MessageBox.Show("Atlikta", "Atlikta", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally { conn.Close(); }
So I really have no idea why it not working anymore.
Using Excel interop is not the best idea in your case - it is slow and requires Excel installed. Try other approach - OleDbConnection way. You can write data to Excel worksheet using plain SQL INSERT command. Create OleDbConnection object with the following connection string:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=SAMPLE.XLSX;Extended Properties=\"Excel 12.0 XML\";"
After that create new OleDbCommand with text like this:
"insert into [YOR_WORKBOOK_NAME$] ([COLUMN_NAME]) values ('Sample text')"
Execute command with ExecuteNonQuery method. Repeat this command with different values to insert many rows to your workbook. This method is much faster than interop approach.
I have tried to use Alter table on an excel spreadsheet to add a new column to existing spreadsheet but found out that I cannot use alter table on excel.
From browsing the net I found that I can use select into to create a duplicate worksheet with new column in it. Here is the code for this.
static private bool CopyAndCreateNewSheet()
{
try
{
DataTable dataTable = new DataTable();
using (OleDbConnection conn = new OleDbConnection(ConfigHelper.ConnectionStringReadWriteWorkBook))
{
conn.Open();
//string selectQuery = "SELECT 0 As IsProcessed, * INTO [Copy] FROM [" + ConfigHelper.WorkSheetName + "$]";
string selectQuery = "SELECT 0 As IsProcessed, * INTO [Excel 12.0;HDR= Yes;DATABASE=c:\\data\\Apr12.xlsx].[copyd] FROM [" + ConfigHelper.WorkSheetName + "$]";
OleDbCommand cmd = new OleDbCommand(selectQuery, conn);
int count = cmd.ExecuteNonQuery();
MessageBox.Show(count.ToString());
conn.Close();
}
}
catch (OleDbException e)
{
MessageBox.Show(e.Message.ToString());
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return true;
}
My config for connectionstring is as follows.
<add name="ReadWriteWorkBook" connectionString='Provider = Microsoft.ACE.OLEDB.12.0; Data Source="c:\data\Apr12.xlsx"; Extended Properties="Excel 12.0;HDR=Yes;READONLY=FALSE"'/>
I have tried with both commented query and uncommented query to run select into but with no luck...
When I open my workbook after above method call I am getting the following error. "Excel found unreadable connect in the file. do you want to recover the contents of this workbook? If you trust the source of this workbook, click yes."
When I click yes, my new tab is there and also new headers are there but no data as excel has removed data from it.
Any help much appreciated.
Thanks in advance.
G'day,
I was able to replicate this and have it work perfectly. The code I used looks like this:
public static void Main(string[] Arguments)
{
try
{
string sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"Test.xlsx\";Extended Properties=\"Excel 12.0;HDR=Yes;READONLY=FALSE\"";
DataTable dataTable = new DataTable();
using (OleDbConnection conn = new OleDbConnection(sConnectionString))
{
conn.Open();
string selectQuery = "SELECT 0 As IsProcessed, * INTO [Excel 12.0;HDR= Yes;DATABASE=Test.xlsx].[copyd] FROM [TestWorkSheet1$]";
OleDbCommand cmd = new OleDbCommand(selectQuery, conn);
int count = cmd.ExecuteNonQuery();
Console.WriteLine(count.ToString());
conn.Close();
}
}
catch (OleDbException e)
{
Console.WriteLine(e.Message.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Note that this code was modified slightly to run inside a console application. This doesn't really help you out at all however. Excel can be a real pain to work with sometimes, have you considered investigating the following:
Permissions
Does the original file open in Excel without issues (i.e., is that file readable by Excel in the first place?)
Has Excel somehow TSR'd and is interfering with your project in some fashion? I've seen this happen before, usually when Excel isn't closed properly
Good luck.
Cheers!
How can I create an Access Database at runtime in C#?
The first thing you need to do is get a COM reference to the Microsoft ADO Ext. X.X for DDL and Security. The X.X represents whatever version you happen to have on your machine. Mine used to be version 2.7, but with Visual Studio 2008, it was updated to 6.0.
alt text http://blog.jrpsoftware.com/content/binary/WindowsLiveWriter/CreateanAccessDatabaseinC_10DDD/AddReference_2.png
Once you have added the reference, ADOX will be added to the using section of your code.
alt text http://blog.jrpsoftware.com/content/binary/WindowsLiveWriter/CreateanAccessDatabaseinC_10DDD/Using_2.png
Next you will want to create the catalog for the database. Insert the filename you wish into the following string and pass it to the CatalogClass.
CatalogClass cat = new CatalogClass();
string tmpStr;
string filename = "Sample.MDB";
tmpStr = "Provider=Microsoft.Jet.OLEDB.4.0;";
tmpStr += "Data Source=" + filename + ";Jet OLEDB:Engine Type=5";
cat.Create(tmpStr);
The next step is to create the table and columns for your database. This is a pretty straight forward operation as shown in the example below.
Table nTable = new Table();
nTable.Name = "PersonData";
nTable.Columns.Append("LastName", DataTypeEnum.adVarWChar, 25);
nTable.Columns.Append("FirstName", DataTypeEnum.adVarWChar, 25);
nTable.Columns.Append("Address 1", DataTypeEnum.adVarWChar, 45);
nTable.Columns.Append("Address 2", DataTypeEnum.adVarWChar, 45);
nTable.Columns.Append("City", DataTypeEnum.adVarWChar, 25);
nTable.Columns.Append("State", DataTypeEnum.adVarWChar, 2);
nTable.Columns.Append("Zip", DataTypeEnum.adVarWChar, 9);
cat.Tables.Append(nTable);
The final step is very important or you will get error when you close your application. Once the all the tables and columns have been added, you will need to release the com objects properly and in the proper order.
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(nTable);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.Tables);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.ActiveConnection);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat);
That is it. You should now have a Access Database that you can write to. Hope this helps.
Reference: John Russell Plant - Create an Access Database in C#
Create a blank access database and store it in your resource files.
Now whenever you want to use it, fetch that database from your resources and copy it to wherever you want, rename it to whatever you want and execute your database setup script to create default tables and load values in them.
Try:
using ADOX; //Requires Microsoft ADO Ext. 2.8 for DDL and Security
using ADODB;
public bool CreateNewAccessDatabase(string fileName)
{
bool result = false;
ADOX.Catalog cat = new ADOX.Catalog();
ADOX.Table table = new ADOX.Table();
//Create the table and it's fields.
table.Name = "Table1";
table.Columns.Append("Field1");
table.Columns.Append("Field2");
try
{
cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + "; Jet OLEDB:Engine Type=5");
cat.Tables.Append(table);
//Now Close the database
ADODB.Connection con = cat.ActiveConnection as ADODB.Connection;
if (con != null)
con.Close();
result = true;
}
catch (Exception ex)
{
result = false;
}
cat = null;
return result;
}
http://zamirsblog.blogspot.com/2010/11/creating-access-database.html
This article from John Russell Plant explains how you'd do it in specific detail with code samples. There are three steps:
Create the catalog.
Create the tables.
Release the relevant COM objects.
static void IF_EXISTS_DELETE_AND_CREATE(string cn)
{
//cn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source =";
//cn += AppDomain.CurrentDomain.BaseDirectory.ToString() + "test.mdb";
try
{
OleDbConnection connection = new OleDbConnection(cn);
object[] objArrRestrict;
objArrRestrict = new object[] { null, null, null, "TABLE" };
connection.Open();
DataTable schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, objArrRestrict);
connection.Close();
string[] list;
if(schemaTable.Rows.Count > 0)
{
list = new string[schemaTable.Rows.Count];
int i = 0;
foreach (DataRow row in schemaTable.Rows)
{
list[i++] = row["TABLE_NAME"].ToString();
}
for ( i = 0; i < list.Length; i++)
{
if(list[i] == "TEMP")
{
string deletedl = "DROP TABLE TEMP";
using (OleDbConnection conn = new OleDbConnection(cn))
{
using (OleDbCommand cmd = new OleDbCommand(deletedl, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
break;
}
}
}
string ddl = "CREATE TABLE TEMP (USERID INTEGER NOT NULL,[ADATE] TEXT(20), [ATIME] TEXT(20))";
using(OleDbConnection conn = new OleDbConnection(cn))
{
using(OleDbCommand cmd = new OleDbCommand(ddl, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
catch (System.Exception e)
{
string ex = e.Message;
}
}