I got two problems:
First, i'm trying to connect my windows form app with my embedded database (.dbf) and i keep getting this message no matter what i do to the connection string:
"error isam instalable cant be found"
Second, i would like to make the path relative to the executable.
Thanks, here is the code i'm using to test the whole thing:
private void bGuardar_Click(object sender, EventArgs e)
{
try
{
string cadena = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source =D:\\; Extended Properties = dBASE IV; UserID =; Password =;";
OleDbConnection con = new OleDbConnection();
con.ConnectionString = cadena;
con.Open();
MessageBox.Show("conected");
con.Close();
}
catch (OleDbException exp)
{
MessageBox.Show("Error: " + exp.Message);
}
}
For the second part, you can get the path of your executable using System.IO.Path.GetDirectory(Application.ExecutablePath). There are more ways do this based upon your need (see Best way to get application folder path).
To avoid further difficulties instead of
'OleDbConnection con = new OleDbConnection();'
try
using (OleDbConnection con = new OleDbConnection())
{
; // your command and executes here
}
this way you call the dispose / close method always (using generally wraps up your code so that the part between { and } is wrapped in a try / catch block with finally that calls a dispose() / close() on the OleDbConn object.
Related
I have read the numerous posts on why you should give the using statement preference over manually doing .Open() then .Close() and finally .Dispose().
When I initially wrote my code, I had something like this:
private static void doIt(string strConnectionString, string strUsername)
{
SqlConnection conn = new SqlConnection(strConnectionString);
try
{
conn.Open();
string strSqlCommandText = $"CREATE USER {strUsername} for LOGIN {strUsername} WITH DEFAULT SCHEMA = [dbo];";
SqlCommand sqlCommand = new SqlCommand(strSqlCommandText, conn);
var sqlNonReader = sqlCommand.ExecuteNonQuery();
if (sqlNonReader == -1) Utility.Notify($"User Added: {strUsername}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
conn.Close();
conn.Dispose();
}
}
and this works... no problem. but only ONCE.
so, if I do something like this:
private static void doItLots(string strConnectionString, string strUsername)
{
for(int i=0; i<10; i++)
{
doIt(strConnectionString, $"{strUsername}_{i}");
}
}
it works the FIRST time when i=0, but any subsequent iterations fail with Cannot open database "myDbName" requested by the login. The login failed.
However, if I go back and comment out the conn.Dispose(); line, then it works fine on all iterations.
The problem is simply that if I want to do the .Dispose() part outside of the method, then I am forced to pass a SqlConnection object instead of simply passing the credentials, potentially making my code a bit less portable and then I need to keep the connection around longer as well. I was always under the impression that you want to open and close connections quickly but clearly I'm misunderstanding the way the .Dispose() command works.
As I stated at the outset, I also tried doing this with using like this...
private static void doIt(string strConnectionString, string strUsername)
{
using (SqlConnection conn = new SqlConnection(strConnectionString))
{
try
{
conn.Open();
string strSqlCommandText = $"CREATE USER {strUsername} for LOGIN {strUsername} WITH DEFAULT SCHEMA = [dbo];";
SqlCommand sqlCommand = new SqlCommand(strSqlCommandText, conn);
var sqlNonReader = sqlCommand.ExecuteNonQuery();
if (sqlNonReader == -1) Utility.Notify($"User Added: {strUsername}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
conn.Close();
}
}
}
and this does the exact same thing as the initial code with .Dispose() called manually.
Any help here would be greatly appreciated. I'd love to convert to the using statements but having trouble figuring out how to write reusable methods that way...
UPDATE:
I have narrowed it down a bit. The issue is NOT the iterations or making the calls over-and-over again. But I am still getting an access error. Here is the code:
string strConnectionString = $#"Data Source={StrSqlServerDataSource};Initial Catalog={StrDatabaseName};User id={StrSqlServerMasterUser};Password={StrSqlServerMasterPassword}";
using (SqlConnection connUserDb = new SqlConnection(strConnectionString))
{
try
{
Utility.Notify($"Connection State: {connUserDb.State.ToString()}"); // Responds as 'Closed'
connUserDb.Open(); // <-- throws error
Utility.Notify($"Connection State: {connUserDb.State.ToString()}");
Utility.Notify($"MSSQL Connection Open... Adding User '{strUsername}' to Database: '{strDatabaseName}'");
string sqlCommandText =
//$#"USE {StrDatabaseName}; " +
$#"CREATE USER [{strUsername}] FOR LOGIN [{strUsername}] WITH DEFAULT_SCHEMA = [dbo]; " +
$#"ALTER ROLE [db_datareader] ADD MEMBER [{strUsername}]; " +
$#"ALTER ROLE [db_datawriter] ADD MEMBER [{strUsername}]; " +
$#"ALTER ROLE [db_ddladmin] ADD MEMBER [{strUsername}]; ";
using (SqlCommand sqlCommand = new SqlCommand(sqlCommandText, connUserDb))
{
var sqlNonReader = sqlCommand.ExecuteNonQuery();
if (sqlNonReader == -1) Utility.Notify($"User Added: {strUsername} ({sqlNonReader})");
}
result = true;
}
catch (Exception ex)
{
Utility.Notify($"Creating User and Updating Roles Failed: {ex.Message}", Priority.High);
}
finally
{
connUserDb.Close();
Utility.Notify($"MSSQL Connection Closed");
}
}
return result;
}
The error I am getting here is: Cannot open database requested by the login. The login failed.
One clue I have is that prior to this, I was running this same code with two changes:
1) uncommented the USE statement in the sqlCommandText
2) connected to the Master database instead
When I did that, it didn't work either, and instead I got this error: The server principal is not able to access the database under the current security context.
If I go into SSMS and review the MasterUser they are listed as db_owner and I can perform any activities I want, including running the command included in the code above.
I rewrote all the code to make use of a single connection per the recommendations here. After running into the "server principal" error, I added one more connection to attempt to directly connect to this database rather than the master.
UPDATE 2:
Here is another plot twist...
This is working from my local computer fine (now). But, not (always) working when run from an Azure Webjob that targets an Amazon Web Services (AWS) Relational Database Server (RDS) running MSSQL.
I will have to audit the git commits tomorrow, but as of 5p today, it was working on BOTH local and Azure. After the last update, I was able to test local and get it to work, but when run on Azure Webjob it failed as outlined above.
SqlConnection implements IDisposable. You don't call dispose or close.
try{
using (SqlConnection conn = new SqlConnection(strConnectionString))
{
conn.Open();
string strSqlCommandText = $"CREATE USER {strUsername} for LOGIN {strUsername} WITH DEFAULT SCHEMA = [dbo];";
SqlCommand sqlCommand = new SqlCommand(strSqlCommandText, conn);
var sqlNonReader = sqlCommand.ExecuteNonQuery();
if (sqlNonReader == -1) Utility.Notify($"User Added: {strUsername}");
}}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
It's really odd. I just use the default connection everything, it is the first time i get this error been trying for hours to fix it and find solution online with no success. I have this code:
class DbConnect
{
//get values of name and customerid using the bracelet id ( a equijoin using customer, ticketpurchase and ticket)
//every ticket is assigned a bracelet id - and i have 6 bracelets to add so also 6 dummy profiles in database
//method to look for customerid using bracelet id and return only one string
public int CustomerId(string braceletId)
{
String str = #"server=localhost;database=dbi340001;userid=xxxxxxxxxxx;password=xxxxxxxxxxxxxxx;";
MySqlConnection con = new MySqlConnection(str);
try
{
con.Open(); //open the connection
MessageBox.Show("welcome");
return 1;
}
catch (MySqlException err) //We will capture and display any MySql errors that will occur
{
Console.WriteLine("Error: " + err.ToString());
}
finally
{
if (con != null)
{
con.Close(); //safely close the connection
}
} //remember to safely close the connection after accessing the database
return 0;
It's a really simple code which i call from another class and i just wrote it to see if the connection will happen with default code. The error is null refference exceptions on conn.isPasswordExpired and conn.ServerThread adn conn.ServerVersion which are all parameters with only get from the mysqlconnection object so it really doesn't make any sence.
Any help would be appreciated!
con.IsPasswordExpired; is called right after MySqlConnection con = null;
Obviously, con is still null when you call con.IsPasswordExpired;
You should consider moving that statement anywhere AFTER con = new MySqlConnection(str);
You should try
MySqlConnection con = new MySqlConnection();
So that it will initialize the object con, then It will not be null.
Connection string that my app is using to connect to DB is the following:
private const string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST="
+ "(ADDRESS=(PROTOCOL=TCP)(HOST=host.name)(PORT=1521)))"
+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=service.name)));"
+ "User Id=myusername;Password=mypass;";
In all DB access points of my app I am using the following pattern:
OracleConnection conn = new OracleConnection(oradb);
try
{
Console.WriteLine("Opening DB Connection...");
conn.Open();
string queryString = string.Format(#"SELECT ...");
using (OracleCommand command = new OracleCommand(queryString, conn))
{
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
...
}
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception occured during DB access: {0}", e.Message);
dbr.Error = e.Message;
}
finally
{
Console.WriteLine("Closing DB connection");
conn.Close();
conn.Dispose();
}
For sure I am properly handling exceptions and in try/catch/finally closing AND disposing connection object. However, often I am receiving oracle service message that I am holding oracle sessions. Moreover, if I just leave my app open and next day try to make operation, I am getting ora-12537 network session end of file exception first time, then second attempt is going through. After some reading it looks like I have to disable connection pool. If this is the right way to solve, how to disable pool? If not, then what other thing can be wrong?
You could add Pooling=False in the connection string, but this means a new connection is created each time.
+ "User Id=myusername;Password=mypass;Pooling=False;";
Take a look at this article, it might help with your issue. Also, take a look at this website page, specifically the Using Connection Pooling section
i am using VS.NET 2008 with MS SQL server 2005 to develop a window form application but everytime i got new error in connection or after conected,
in my current code the connection opened but doesnt work after that in transaction of queries. maybe i have problem while making new DB or new datasource also m not that satisfy how to get Connecting String
this is my code....
/////////
private void button1_Click(object sender, EventArgs e)
{
try
{
//setData();
string ConnectingString = #"Data Source=SERVER1\SQLEXPRESS;Initial Catalog=Alkawthar;Integrated Security=True;Pooling=False";
qry = "SELECT * FROM Table1";
//reader = db.select_data(qry);
ds1 = new DataSet();
conn = new SqlConnection(ConnectingString);
conn.Open();
MessageBox.Show("connection opened");
da.Fill(ds1,"Workers");
NavigateRecords();
MaxRows = ds1.Tables["Workers"].Rows.Count;
string sql = "SELECT * From tblWorkers";
da = new System.Data.SqlClient.SqlDataAdapter(sql, conn);
conn.Close();
MessageBox.Show("connection closed");
conn.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("exception");
MessageBox.Show(ex.Message);
}
}
/////////////////
Fill throws an exception also when i use reader it return null although there is data in DB
thanks
The most obvious problem here is that you access the SqlDataAdapter before initializing it. That will cause a null reference exception.
Try to move the line da = new SqlDataAdapter(...) to the line before you do the da.Fill(...).
Edit:
No, wait! I see that you do two queries and two fills in there. You need to initialize the SqlDataAdapter before doing the first fill. Then you should get rid of the null reference exception.
Edit again:
Also, as commented, you don't need call both the SqlConnection.Close and SqlConnection.Dispose methods. As long as you use the SqlDataAdapter you don't even need to do the SqlConnection.Open on the connection, for the Fill method will do all that for you. As long as the connection starts out being closed, the Fill method will close it again for you when it is done.
A few points of advice;
Like Turrau and Rune say, your stuff is in the wrong order. Open connection, Execute SQL - Get raw data, close connection. Then do your counting, etc.
Don't put message box or logging calls anywhere in between the connection opening and closing. This has burned me before, where the those calls can affect the SQL call because they fudge the exception details and make it difficult to trace. This is also applicable when using a SQL data reader.
Put the SQL stuff in a using block.
Try this...
string _connStr = #"Data Source=SERVER1\SQLEXPRESS;Initial Catalog=Alkawthar;Integrated Security=True;Pooling=False";
string _query = "SELECT * FROM Workers";
DataSet _ds = new DataSet();
try
{
using (SqlConnection _conn = new SqlConnection(_connStr))
{
SqlDataAdapter _da = new SqlDataAdapter(_query, _conn);
_conn.Open();
_da.Fill(_ds);
}
// insert null dataset or invalid return logic (too many tables, too few columns/rows, etc here.
if (_ds.Tables.Count == 1)
{ //There is a table, assign the name to it.
_ds.Tables[0].TableName = "tblWorkers";
}
//Then work with your tblWorkers
}
catch (Exception ex)
{
Console.Write("An error occurred: {0}", ex.Message);
}
Seems to me, that you use your DataAdapter before initialization. Do you get a NullReferenceException?
da.Fill(ds1,"Workers");
// ...
da = new System.Data.SqlClient.SqlDataAdapter(sql, conn);
I'm using asp.net c# and upload a SqLite database to a server and then I do some inserting and updating. The problem is that sometimes (I think it's when somethings go wrong with the updating or so) the database gets locked. So the next time I try to upload a file again it's locked and I get an error saying "The process cannot access the file because it is being used by another process". Maybe the database file isn't disposed if something goes wrong during the transaction? The only thing to solve this problem is restarting the server.
How can I solve it in my code so I can be sure it's always unlocked even if something goes wrong?
This is my code:
try
{
string filepath = Server.MapPath("~/files/db.sql");
//Gets the file and save it on the server
((HttpPostedFile)HttpContext.Current.Request.Files["sqlitedb"]).SaveAs(filepath);
//Open the database
SQLiteConnection conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;");
conn.Open();
SQLiteCommand cmd = new SQLiteCommand(conn);
using (SQLiteTransaction transaction = conn.BeginTransaction())
{
using (cmd)
{
//Here I do some stuff to the database, update, insert etc
}
transaction.Commit();
}
conn.Close();
cmd.Dispose();
}
catch (Exception exp)
{
//Error
}
You could try placing the Connection in a using block as well, or calling Dispose on it:
//Open the database
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;")) {
conn.Open();
using (SQLiteCommand cmd = new SQLiteCommand(conn)) {
using (SQLiteTransaction transaction = conn.BeginTransaction()) {
//Here I do some stuff to the database, update, insert etc
transaction.Commit();
}
}
}
This will ensure that you're disposing of the connection object's correctly (you're not at the moment, only closing it).
Wrapping them in using blocks ensures that Dispose is called even if an exception happens - it's effectively the same as writing:
// Create connection, command, etc objects.
SQLiteConnection conn;
try {
conn = new SQLiteConnection("Data Source=" + filepath + ";Version=3;");
// Do Stuff here...
}
catch (exception e) {
// Although there are arguments to say don't catch generic exceptions,
// but instead catch each explicit exception you can handle.
}
finally {
// Check for null, and if not, close and dispose
if (null != conn)
conn.Dispose();
}
The code in the finally block is going to be called regardless of the exception, and helps you clean up.
An asp.net application is multithreaded in the server.
You can't do simultaneous writing (insert, select, update...) because the whole db is locked. Simultaneously selecting is allowed when no writing is happening.
You should use the .NET ReaderWriterLock class: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx
Shouldn't you do cmd.Dispose() before conn.Close()? I don't know if it makes any difference, but you generally want to clean things up in the opposite of initialization order.
In short, SQLite handles unmanaged resources slightly differently than other providers. You'll have to explicitly dispose the command (which seems to work even if you are working with the reader outside of the using() block.
Read this thread for more flavor:
http://sqlite.phxsoftware.com/forums/p/909/4164.aspx