AccessViolationException thrown by OleDbConnection.Open() - c#

I am getting a System.AccessViolationException error when trying to use the .Open() method on my OleDbConnection variable. But, confoundingly, it doesn't seem to happen when I run my code on a different computer.
My code is for a service that I want running on a server. It appears to work correctly when I run it on my personal computer, but it throws the AccessViolationException error when I try running it on the server.
Code Versions:
I am writing in C# using Visual Studios 2019 on Windows 10
OleDbConnection is from "Assembly System.Data, Version=4.0.0.0"
ADOX is from "Assembly Interop.ADOX, Version=2.8.0.0", System.Runtime.InteropServices
ADODB is from "Assembly Interop.ADODB, Version=2.8.0.0", System.Runtime.InteropServices
My code:
internal static bool CreateMDB(MySchemaClass schema, string filePath)
{
OleDbConnection conn = null;
bool status = true;
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}", filePath);
try
{
// Setup new file
catalog.Create(connectionString);
((ADODB.Connection)catalog.ActiveConnection).Close();
conn = new OleDbConnection(connectionString);
conn.Open(); // <-- Error occurs here
// Write to new file
WriteDataToFile(schema, conn);
}
catch (Exception ex)
{
status = false;
}
finally
{
if (conn != null)
conn.Close();
}
return status;
}
StackTrace:
The best lead I have found so far is this post, but I'm a bit hazy about how to proceed from that starting point.

To programmatically create an Access database do the following:
Add reference to Microsoft ADO Ext. 6.0 for DDL and Security
In VS menu, click Project
Select Add Reference
Click COM
Check Microsoft ADO Ext. 6.0 for DDL and Security
CreateAccessDatabase
public static string CreateAccessDatabase(string fullyQualifiedAccessFilename, string dbPassword = "")
{
string connectionString = String.Format(#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0}", fullyQualifiedAccessFilename);
if (String.IsNullOrEmpty(fullyQualifiedAccessFilename))
{
throw new Exception("Error (CreateAccessDatabase) - Database filename is null or empty.");
}
if (!String.IsNullOrEmpty(dbPassword))
{
connectionString = String.Format(#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0};Jet OLEDB:Database Password='{1}'", fullyQualifiedAccessFilename, dbPassword);
}
//create new instance
ADOX.Catalog cat = new ADOX.Catalog();
//create Access database
cat.Create(connectionString);
//close connection
cat.ActiveConnection.Close();
//release COM object
System.Runtime.InteropServices.Marshal.ReleaseComObject(cat);
GC.Collect();
cat = null;
return String.Format("Database created '{0}'", fullyQualifiedAccessFilename);
}
Usage:
string result = string.Empty;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Access Database 2000-2003 (*.mdb)|*.mdb|Access Database 2007 (*.accdb)|*.accdb";
if (sfd.ShowDialog() == DialogResult.OK)
{
//create Access database
result = CreateAccessDatabase(sfd.FileName);
}
To programmatically create a table in an Access database:
Add using statement:
using System.Data.OleDb;
CreateTableProduct:
public static int CreateTableProduct(string fullyQualifiedAccessFilename, string dbPassword = "")
{
int result = 0;
string connectionString = String.Format(#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0}", fullyQualifiedAccessFilename);
if (!String.IsNullOrEmpty(dbPassword))
{
connectionString = String.Format(#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0};Jet OLEDB:Database Password='{1}'", fullyQualifiedAccessFilename, dbPassword);
}
string sqlText = string.Empty;
sqlText = "CREATE TABLE Product ";
sqlText += "(ID AUTOINCREMENT not null primary key,";
sqlText += " Name varchar(50) not null,";
sqlText += " Price currency, Quantity integer);";
using (OleDbConnection con = new OleDbConnection(connectionString))
{
//open connection
con.Open();
using (OleDbCommand sqlCmd = new OleDbCommand(sqlText, con))
{
//execute command
result = sqlCmd.ExecuteNonQuery();
}
}
return result;
}
Resources:
ADO Features for each Release
Which Access file format should I use?
CREATE TABLE statement (Microsoft Access SQL)
System.Data.OleDb Namespace

The underwhelming answer to the problem is that my server was lacking some of the files my personal computer had, and only needed the correct files installed.
The missing piece in this case was the Microsoft Access Database Engine 2016 Redistributable, which I ended up finding here. Running that executable on my server got the needed files and everything worked after that.

Related

Some Excel Files not moving from Shared Path to SQL Server

We have an application where the data in Excel file (present in shared path) moves to Database. In case of any error, the files moves to error folder by writing the error in a log file.It uses a windows service for the operation.
Sometimes the file doesn't have any error still moves to error folder by writing log External table is not in the expected format. But the same file uploading again for once or multiple times, its moving to Database without any errors.
The windows service, DB and shared path are present in XP Server. Application was running fine all these years. But in the recent days, above mentioned problem is occurring for almost every file.
We have installed Microsoft 2003, 2007,2012 office components and access engines too. But still the issue still persists.
I am mentioning the Windows service code below. Pls help. Thanks in advance.
using System.IO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data.Common;
namespace Impexp_Service
{
public partial class Service1 : ServiceBase
{
System.Timers.Timer T1 = new System.Timers.Timer();
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
///start
///
{
SqlConnection strconnection = new SqlConnection();
strconnection.ConnectionString = #"Data Source=XXXXXX;Initial Catalog=XXXX;User ID=XX;Password=XXXXXX;";
strconnection.Open();
// To get the all files placed at the shared path
DirectoryInfo directory = new DirectoryInfo(#"D:\Impexp\Data\");
FileInfo[] files = directory.GetFiles("*.xlsx");
foreach (var f in files)
{
string path = f.FullName;
// TO establish connection to the excel sheet
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
//Create Connection to Excel work book
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select * from [Report$]", excelConnection);
DbDataReader dr = cmd.ExecuteReader();
// OleDbDataReader dReader;
// dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strconnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "imp_master_test";
sqlBulk.WriteToServer(dr);
excelConnection.Close();
File.Delete(path);
// To move error files to the error folder
/// end
T1.Interval = 20000;
T1.Enabled = true;
T1.Start();
T1.Elapsed += new System.Timers.ElapsedEventHandler(T1_Elapsed);
}
}
}
void T1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
T1.Enabled = false;
try
{
SqlConnection strconnection = new SqlConnection();
strconnection.ConnectionString = #"Data Source=10.91.XXXXXX;Initial Catalog=XXXXX;User ID=XXXXX;Password=XXXXX;";
strconnection.Open();
// To get the all files placed at the shared path
DirectoryInfo directory = new DirectoryInfo(#"D:\Impexp\Data\");
FileInfo[] files = directory.GetFiles("*.xlsx");
foreach (var f in files)
{
string path = f.FullName;
// TO establish connection to the excel sheet
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
//Create Connection to Excel work book
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
try
{
excelConnection.Open();
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select * from [Report$]", excelConnection);
DbDataReader dr = cmd.ExecuteReader();
// OleDbDataReader dReader;
// dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strconnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "imp_master_prod";
sqlBulk.WriteToServer(dr);
excelConnection.Close();
File.Delete(path);
}
// To move error files to the error folder
catch (Exception exp)
{
excelConnection.Close();
File.Move(path, Path.Combine(#"D:\Impexp\error\", f.Name));
string path1 = #"D:\Impexp\error\error.txt";
if (File.Exists(path1))
{
// Create a file to write to.
using (StreamWriter sw = File.AppendText(path1))
{
sw.WriteLine("File : " + path + " : " + exp.Message);
sw.Flush();
}
}
T1.Enabled = true;
T1.Start();
}
}
strconnection.Close();
// End of TRY 1
}
catch (UnauthorizedAccessException UAEx)
{
string path1 = #"D:\Impexp\error\error.txt";
if (File.Exists(path1))
{
// Create a file to write to.
using (StreamWriter sw = File.AppendText(path1))
{
sw.WriteLine(UAEx.Message);
sw.Flush();
}
}
T1.Enabled = true;
T1.Start();
}
catch (PathTooLongException PathEx)
{
string path1 = #"D:\Impexp\error\error.txt";
if (File.Exists(path1))
{
// Create a file to write to.
using (StreamWriter sw = File.AppendText(path1))
{
sw.WriteLine(PathEx.Message);
sw.Flush();
}
}
T1.Enabled = true;
T1.Start();
}
T1.Enabled = true;
T1.Start();
}
protected override void OnStop()
{
}
}
}
I did some searching regarding the OLEDB coms and newer versions of Excel. It seems as though a great many people are having compatibility issues with them.
Unfortunately, it doesn't look like Microsoft is giving this any attention. Microsoft announced the depreciation of OLEDB functionality many years ago, and they have stopped adding any kind of internal support in their Office products and SQL servers. In fact,
The official shutdown date for MSAccess Web Apps and Web Databases was April 2018. That being the case, an update to the server, the client version of windows, or the client version of Excel may have triggered this, and it doesn't look like there is going to be a fix. I myself have started using 3rd party packages (free ones are available) to handle the interop with office products because I was tired of banging my head against the wall to create workarounds. Honestly, I don't know why Access still exists if they are taking away the ability to programmatically connect to an Access database.
I know this doesn't fix your problem, but it's better to face the truth and move on than to try to fix something that isn't going to fix.
Looking at this question, this appears to be an issue with reading the excel file, not the SQL table. Try changing the Excel connection string.
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
to
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;HDR=Yes;IMEX=1\";
Also, looking at another answer, the root cause could be uploading newer versions of excel.
Are you using an Excel 2007 file with a connection string that uses: Microsoft.Jet.OLEDB.4.0 and Extended Properties=Excel 8.0?
You can change the string to some other as below:
public static string path = #"C:\src\RedirectApplication\RedirectApplication\301s.xlsx";
public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
OR
Change the connection string from the link below:
http://www.connectionstrings.com/excel-2007

Issue attempting to query an Excel file... "The Microsoft Office Access database engine could not find the object 'Sheet1$'.."

I am attempting to query data from within an Excel sheet using my C# application. I seem to be able to connect to the file now but I am getting the following exception...
The Microsoft Office Access database engine could not find the object 'Sheet1$'.
I'm using a connection string similar to that of Excel connection strings
This is my code...
The code is basically a method (tucked away in a class) that uses a parameter variable to return a data from one column based on provided data in another....This same method works for SQL connections in my other applications..this is my first swing at an excel sheet however..
public static string ReturnDefinition(string remCode)
{
string strReturnMessage = "";
string excelConnectString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=MEDICARE.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES""";
OleDbConnection objConn = new OleDbConnection(excelConnectString);
OleDbCommand objCmd = new OleDbCommand("Select * from [Sheet1$] where Code = #remCode", objConn);
objCmd.Parameters.AddWithValue("#remCode", remCode);
try
{
objConn.Open();
OleDbDataReader ExcelDataReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
if (ExcelDataReader.HasRows)
{
while (ExcelDataReader.Read())
{
if (string.IsNullOrEmpty((string)ExcelDataReader["Description"]))
{
strReturnMessage = "** ERROR **";
}
else
{
strReturnMessage = ExcelDataReader["Description"].ToString();
}
}
}
else
{
strReturnMessage = "** ERROR **";
}
ExcelDataReader.Close();
return strReturnMessage;
}
catch (Exception ex)
{
return "** ERROR **: " + ex.Message;
}
finally
{
}
}
5/30
I realize there is literature out there that covers connections to Excel using OLEDB but I think I've boiled the issue down to a read issue in the sheet its self. Again, this is the first time I've tried to connect to Excel. My HDR is set to true, as I intend to treat the sheet like a SQL table.
Changed Excel to v.14.0 in Extended Properties
I may have been targeting the wrong version of excel. Specifically, the excel sheet was created using Office 2010. Using This Article for reference, I changed the version from 12.0 to 14.0.
Now I get Could not find installable ISAM
Well, I think I've got it figured out for now.
At least I can get to the sheet anyway.
I'll just need to sort out whats going on with my data types.
I now get Data type mismatch in criteria expression.
The data being passed from my parameter variable is a string but the column name ("Code") I am trying to reach contains strings in some rows and int32 in others. If it were SQL I would say this column would be of type CHAR(whatever). I don't know in this case.
Anyway, here is my own resolution...it seems all I needed to do was assign the sheet name to a variable and then include that variable in my query.
enter public static string ReturnDefinition(string remCode)
{
string strReturnMessage = "";
string excelConnectString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=MEDICARE.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES""";
string excelSheet = "Sheet1$";
OleDbConnection objConn = new OleDbConnection(excelConnectString);
OleDbCommand excelCmd = new OleDbCommand("Select * from ["+ excelSheet + "] where Code = #remCode", objConn);
excelCmd.Parameters.AddWithValue("#remCode", remCode);
try
{
objConn.Open();
OleDbDataReader ExcelDataReader = excelCmd.ExecuteReader(CommandBehavior.CloseConnection);
if (ExcelDataReader.HasRows)
{
while (ExcelDataReader.Read())
{
if (string.IsNullOrEmpty((string)ExcelDataReader["Description"]))
{
strReturnMessage = "** ERROR **";
}
else
{
strReturnMessage = ExcelDataReader["Description"].ToString();
}
}
}
else
{
strReturnMessage = "** ERROR **";
}
ExcelDataReader.Close();
return strReturnMessage;
}
catch (Exception ex)
{
return "** ERROR **: " + ex.Message;
}
finally
{
}
}

cannot connect to oracle server from C#.net application

I'm trying to connect to remote Oracle server. My connection string -
OdbcConnection con = new OdbcConnection();
con.ConnectionString = #"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= xxxx)(PORT=xxxxx))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=abc.domain.com)));USER ID=user1;Password=pwd;";
I encountered error saying - "ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified" (System.Data.Odbc.OdbcException) Exception Message = "ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified", Exception Type = "System.Data.Odbc.OdbcException", Exception WinRT Data = ""
I specified my connection string according to my TNSNAMES.ora
Entry for my DB in TNSNAMES.ora goes like this:
DB.WORLD=
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP)
(HOST= xxxx)
(PORT=xxxxx)
)
(CONNECT_DATA=
(SERVER=dedicated)
(SERVICE_NAME=abc.domain.com)
)
)
Can someone explain on the error. Please help/suggest if my connection string went wrong and how to connect to Oracle server from my windows application
first install odp.net.managed using nuget packet manager:
Install-Package odp.net.managed
odp.net.managed work without preinstalled Oracle Client
next:
const string connectionString = #"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= xxxx)(PORT=xxxxx))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=abc.domain.com)));USER ID=user1;Password=pwd;";
var connection = new OracleConnection(connectionString);
connection.Open();
if you have tnsnames.ora in application folder:
const string connectionString = #"Data Source=DB.WORLD;USER ID=user1;Password=pwd;";
var connection = new OracleConnection(connectionString);
connection.Open();
or if tnsnames.ora in other folder:
Environment.SetEnvironmentVariable("TNS_ADMIN", #"path_to_tnsadmin.ora");
const string connectionString = #"Data Source=DB.WORLD;USER ID=user1;Password=pwd;";
var connection = new OracleConnection(connectionString);
connection.Open();
you need to use OracleConnection
OracleConnection conn = new OracleConnection(connectionString);
download and install Oracle Data Provider for .NET
Go to Connections Strings for Oracle
Maybe will find some help
Use following Code:
using System;
using Oracle.DataAccess.Client;
class ConnectionSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//using connection string attributes to connect to Oracle Database
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
Source ONE , TWO and THREE
Try something like this class :
public class OracleOperations
{
OracleConnection oraConn = new OracleConnection();
private bool connStatus;
public OracleOperations()
{
connStatus = false;
connect();
}
~OracleOperations()
{
disconnect();
}
public bool getConnStatus()
{
return connStatus;
}
public void connect()
{
string connString = "User Id=xxxx; Password=yyyyy; Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.10)(PORT=1583))(CONNECT_DATA=(SERVER=dedicated)(SID=oracledb)))";
if (oraConn.State != ConnectionState.Open)
{
try
{
oraConn.ConnectionString = connString;
oraConn.Open();
Console.WriteLine("Successful Connection");
connStatus = true;
}
catch (Exception eOra)
{
Console.WriteLine(eOra.Message+ "Exception Caught");
connStatus = false;
throw eOra;
}
}
}
public void disconnect()
{
if (oraConn.State == ConnectionState.Open)
{
try
{
oraConn.Close();
connStatus = false;
Console.WriteLine("Connection Closed");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + "Exception Caught");
}
}
}
}
I would try Tnsping utility to make sure you can connect via tnsnames.ora
Try putting tnsnames.ora and sqlnet.ora in the same folder of the application and see if that addresses the issue.
With Managed ODP.Net there is one catch it does not support LDAP look up (e.g. LDAP.ora)
I'Ve Created an app.config File and configured the DB entry like this
<configuration>
<configSections>
<section name ="Environment" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<Environment>
<add key ="CIT" value ="Password=pwd123;User ID=abc123;Data Source=db1;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="SIT" value ="Password=pwd234;User ID=abc234;Data Source=db2;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="UAT" value ="Password=pwd345;User ID=abc345;Data Source=db3;Persist Security Info=True;Provider=MSDAORA"/>
</Environment>
</configuration>
Reffered that configuration into my form using ConfigurationManager(Need to refer the assembly - system.configuration). Add namespace - using System.Collections.Specialized to avail NameValueCollection. Code goes like this
environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1); dataGridView1.DataSource = ds1.Tables[0];
Using datset, i've populated datagrid using an OleDbDataAdapter. It worked for my Windowsapplication.

How to change size of database

I know how to change size database on SQL (in SQL Server 2005 Express Edition)
ALTER DATABASE Accounting
MODIFY FILE
(NAME = 'Accounting',
SIZE = 25)
How to change size database useing C#?
Submit the DDL via an ExecuteNonQuery command:
mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText =
"ALTER DATABASE Accounting MODIFY FILE (NAME = 'Accounting', SIZE = 25) ";
mySqlConnection.Open();
int result = mySqlCommand.ExecuteNonQuery();
mySqlConnection.Close();
Similar examples can be found here (showing issues related to snapshot isolation, but the ideais basically the same):
http://msdn.microsoft.com/en-us/library/tcbchxcb.aspx
Following example will give you a better overview. Having defined parameters you can pass some stuff that not necessary has to be static. Using using will make sure everything is disposed/closed properly (and or reused if necessary).
public const string sqlDataConnectionDetails = "Data Source=YOUR-SERVER;Initial Catalog=YourDatabaseName;Persist Security Info=True;User ID=YourUserName;Password=YourPassword";
public static void ChangeDatabaseSize(int databaseSize) {
const string preparedCommand = #"
ALTER DATABASE Accounting
MODIFY FILE
(NAME = 'Accounting', SIZE = #size)
";
using (var varConnection = SqlConnectOneTime(sqlDataConnectionDetails))
using (SqlCommand sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
sqlWrite.Parameters.AddWithValue("#size", databaseSize);
sqlWrite.ExecuteNonQuery();
}
}
This is supporting method that makes it easy to establish connection everytime you want to write/read something to database.
public static SqlConnection SqlConnectOneTime(string varSqlConnectionDetails) {
SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails);
try {
sqlConnection.Open();
} catch {
DialogResult result = MessageBox.Show(new Form {
TopMost = true
}, "No connection to database. Do you want to retry?", "No connection (000001)", MessageBoxButtons.YesNo, MessageBoxIcon.Stop);
if (result == DialogResult.No) {
if (Application.MessageLoop) {
// Use this since we are a WinForms app
Application.Exit();
} else {
// Use this since we are a console app
Environment.Exit(1);
}
} else {
sqlConnection = SqlConnectOneTime(varSqlConnectionDetails);
}
}
return sqlConnection;
}

How to create an Access database at runtime in C#?

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;
}
}

Categories