I've got an ado.net code listing:
OleDbConnection oconn = new OleDbConnection();
// oconn.ConnectionString ="Driver={Microsoft Visual FoxPro Driver};Provider=vfpoledb.1;SourceType=DBF;SourceDB=" + pelna_sciezka + ";Exclusive=No; Collate=Machine;NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;";
oconn.ConnectionString = "Provider=vfpoledb.1;Data Source=" + pelna_sciezka + ";Collating Sequence=machine";
oconn.Open();
OleDbCommand ocmd = oconn.CreateCommand();
string na = TBNazwaKonta.Text.Replace("\n","");
na = na.Replace("\r","") ;
string ks2 = ks.Replace("\n","");
ks2 = ks2.Replace("\r", "");
OleDbCommand dbCmdNull = oconn.CreateCommand();
dbCmdNull.CommandText = "SET NULL OFF";
dbCmdNull.ExecuteNonQuery();
string zapytanie = #"insert into " + #pelna_sciezka + #" (rk, Na,Ks) values (0,'" + na + "','" + ks2 +"')";
ocmd.CommandText = zapytanie;
ocmd.ExecuteNonQuery();
oconn.Close();
It's working well without any problems. But the dbf file which I using is using by another program. Why if I execute query and close connection the dbf file is still holding by program? If someone want to open it, the error message is 'file access denied'. Only if I close application, the another can get access
You are not closing your OleDbCommands. Contrary to SqlCommands, where this is de facto optional, this does make a difference for OleDb.
I recommend to use the using keyword; this ensures that all resources are released automatically at the end of the block. As an additional bonus, it ensures that the resources are also released if an exception occurs and, thus, your manual Close command would never be reached.
using (OleDbConnection oconn = new OleDbConnection()) {
oconn.ConnectionString = "Provider=vfpoledb.1;Data Source=" + pelna_sciezka + ";Collating Sequence=machine";
oconn.Open();
using (OleDbCommand ocmd = oconn.CreateCommand()) {
string na = TBNazwaKonta.Text.Replace("\n","");
na = na.Replace("\r","") ;
string ks2 = ks.Replace("\n","");
ks2 = ks2.Replace("\r", "");
using (OleDbCommand dbCmdNull = oconn.CreateCommand()) {
dbCmdNull.CommandText = "SET NULL OFF";
dbCmdNull.ExecuteNonQuery();
} // closes dbCmdNull
string zapytanie = #"insert into " + #pelna_sciezka + #" (rk, Na,Ks) values (0,'" + na + "','" + ks2 +"')";
ocmd.CommandText = zapytanie;
ocmd.ExecuteNonQuery();
} // closes ocmd
} // closes connection
I've solved my problem, there were two points that I performed:
- I've changed all ado.net code for that like Heinzi has written
- I've used the information from support.microsoft.com/kb/260856
and followed them, the problem has now disappeared. Thank you all for help!
Related
My SQLite query hangs then locks during my ExecuteNonQuery() in WriteToDB() below. It only seems to lock during the UPDATE and has no problem with the INSERT. This is only running in a single thread. When it hangs, I can see the journal being created in the SQLite database directory as if it keeps trying to write. It throws a SQLiteException with ErrorCode=5, ResultCode=Busy.
public String WriteToDB()
{
String retString = "";
//see if account exists with this email
String sql = "";
bool aExists = AccountExists();
if (!aExists)
{
sql = "INSERT INTO accounts (email, password, proxy, type, description) VALUES ('" + Email + "', '" + Password + "', '" + Proxy + "', 'dev', '" + Description + "');";
retString = "Added account";
}
else
{
sql = "UPDATE accounts SET password='" + Password + "', proxy='" + Proxy + "', description='" + Description + "' WHERE (email='" + Email + "' AND type='dev');";
retString = "Updated account";
}
using (SQLiteConnection dbconn = new SQLiteConnection("Data Source=" + Form1.DBNAME + ";Version=3;"))
{
dbconn.Open();
using (SQLiteCommand sqlcmd = new SQLiteCommand(sql, dbconn))
{
sqlcmd.ExecuteNonQuery(); //this is where it locks. Only on update.
}
}
return retString;
}
//Test to see if Email exists as account
public bool AccountExists()
{
int rCount = 0;
String sql = "SELECT COUNT(email) FROM accounts WHERE email='" + Email + "' AND type='dev';";
using (SQLiteConnection dbconn = new SQLiteConnection("Data Source=" + Form1.DBNAME + ";Version=3;"))
{
dbconn.Open();
using (SQLiteCommand sqlcmd = new SQLiteCommand(sql, dbconn))
{
rCount = Convert.ToInt32(sqlcmd.ExecuteScalar());
}
}
if (rCount > 0)
return true;
return false;
}
Oh man I feel dumb. I thought I posted all relevant code but all the code I posted works just fine. I had:
SQLiteDataReader dbReader = sqlcmd.ExecuteReader()
instead of
using (SQLiteDataReader dbReader = sqlcmd.ExecuteReader())
In another function. I thought it was an issue with the UPDATE because that was the place where the lock took place. Thanks for the responses and hopefully this reminds reminds everyone to use using() blocks with SQLite the first time!
How would I go about import/inserting a .DAT file into the database by calling a procedure?
Here's what my file would look like and it has to go into the database in this format.
50 4411902304 1 3 441192304 01/02/2013
Would the process be the same for .DAT file as to xml file?
Here's what I have for xml
SqlConnection myConnection = new SqlConnection("user id=name;" +
"password=password;server=servername;" +
"Trusted_Connection=yes;" +
"database=database; " +
"connection timeout=30");
var conn = new SqlConnection();
conn.ConnectionString = "user id=idName;" +
"password=password;" + "server=servername;" + "Trusted_Connection=yes;" + "database=databasename; " + "connection timeout=30";
string filePath = "C:/TestData2.xml";
string xml = File.ReadAllText(filePath);
using (SqlConnection con = new SqlConnection(conn.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("procedureName"))
{
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#x", xml);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("done");
}
}
What happens is that XML is a new technology compared to the old flat file (DAT).
XML is a markup format file and there are functions implemented to make easier the importing tasks.
Flat file are older, so a different approach is needed.
You can use the bcp (bulk copy program) to import files to SQL Server or the SSIS Import options.
Or, you can also use:
System.IO.StreamReader file = new System.IO.StreamReader(#"c:\data\TestData2.dat");
int counter = 0;
while ((line = (file.ReadLine())) != null){...}
And parsing each line using the Split command.
string[] fields= line.Split(' ');
string a = fields[0];
string b = fields[1];
string c = fields[2];
and then execute a command to insert each line:
string sqlCommandtoInsert= "INSERT INTO [Table] (Tablefield1, Tablefield2, Tablefield3) VALUES (" + a + ", " + b + ", '" + c + "');";
cmd.CommandText = sqlCommandtoInsert;
cmd.ExecuteNonQuery();
Inserting each record in your table.
I have a C# program that needs to read record by record from a DB, then it makes some operations on two columns and then writes on a new column.
So far I did like this:
using (SQLiteConnection conn_write = new SQLiteConnection("Data Source=" + path + ";PRAGMA journal_mode=WAL;"))
{
conn_write.Open();
SQLiteCommand cmd_write = new SQLiteCommand(conn_write);
using (SQLiteConnection conn_read = new SQLiteConnection("Data Source=" + path + ";PRAGMA journal_mode=WAL;"))
{
conn_read.Open();
SQLiteCommand cmd_read = new SQLiteCommand(conn_read);
SQLiteDataReader reader;
sql_read = "SELECT ID, ETRF2000_FI, ETRF2000_LA FROM Tutto_NonAbolito";
cmd_read.CommandText = sql_read;
reader = cmd_read.ExecuteReader();
while (reader.Read())
{
MobileKat.ALCoord.ETRF200ToLL84(reader.GetDouble(reader.GetOrdinal("ETRF2000_FI")), reader.GetDouble(reader.GetOrdinal("ETRF2000_LA")), ref lon, ref lat);
sql_write = "UPDATE Tutto_NonAbolito SET LL84_LON = " + lon + ", LL84_LAT = " + lat + " WHERE " + reader.GetInt32(reader.GetOrdinal("ID")) + " = ID;";
cmd_write.CommandText = sql_write;
cmd_write.ExecuteReader();
}
conn_read.Close();
}
conn_write.Close();
}
I also tried to add PRAGMA but it still tells me that the database file is locked.. Is there a way to do that in this way? I wouldn't like to save the columns in an array and then open another connection. I prefer to do it "on-the-run" if it is possible. Thanks!
I have an c# winforms application (.net 2 framework).
I need to backup data bases from my application.
I am trying to do this by executing an SqlCommand asynchronously.
The code is executed with no exceptions but I dont get the .bak file in my destination...
this is the code :
#region backup DB using T-SQL command
string connString = "Data Source=" + ConfigurationManager.AppSettings.Get("localhost_SQLEXPRESS") + ";Initial Catalog=" + db + ";UserID=" + ConfigurationManager.AppSettings.Get("user") + ";Password=" + ConfigurationManager.AppSettings.Get("password");
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connString);
builder.AsynchronousProcessing = true;
using (SqlConnection sqlConnection1 = new SqlConnection(builder.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("BACKUP DATABASE " + db + " TO DISK=" + location + "\\" + ConfigurationManager.AppSettings.Get("DataBaseBackupsFolderName") + "\\" + db + ".bak'", sqlConnection1))
{
sqlConnection1.Open();
IAsyncResult result = cmd.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
Thread.Sleep(100);
}
}
}
#endregion
In your SQL backup line you seem to be missing a single quote at the beginning of the path to the backup file.
using (SqlCommand cmd = new SqlCommand("BACKUP DATABASE " + db + " TO DISK='" + location + "\\" + ConfigurationManager.AppSettings.Get("DataBaseBackupsFolderName") + "\\" +db + ".bak'", sqlConnection1))
Two advices to try to isolate the problem:
1) Get the resulting string (the one you are executing on the SqlCommand and run it manually on SQL Server to make sure the backup commnad is correct.
2) Try a synchronous command with a regular ExecuteNonQuery to see if you are getting a SQL Server exception
You should call EndExecuteNonQuery() on your SqlCommand instance in order to throw any eventual exception and thus understand what is wrong with your SQL statements:
IAsyncResult result = cmd.BeginExecuteNonQuery();
// Wait for the command to complete
result.AsyncWaitHandle.WaitOne();
// End the execution and throw any eventual exception
cmd.EndExecuteNonQuery(result);
As you can see, I have also replaced your original Thread.Sleep() cycle block with a more effective wait on the wait handle of the command.
Quoting MSDN:
For each call to BeginOperationName, the application should also call
EndOperationName to get the results of the operation.
I'm using the following code to update a cell in an Excel file.
public bool WriteChange(string Filename, string SheetName, string Cell, string Value)
{
if(!System.IO.File.Exists(Filename))
{
throw new System.IO.FileNotFoundException("File \"" + Filename + "\" could not be found");
}
bool result = false;
string ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Filename + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=NO;\"";
string SQL = "UPDATE [" + SheetName + Cell + ":" + Cell + "] SET F1='" + Value + "'";
using(OleDbConnection Connection = new OleDbConnection(ConnectionString))
{
Connection.Open();
using(OleDbCommand cmd = new OleDbCommand(SQL,Connection))
{
int value = cmd.ExecuteNonQuery();
if(value > 0)
{
result = true;
}
}
}
return result;
}
Which works fine, unless I try to update the same cell multiple times. Once a cell has been updated using this function, it can never be updated using this function again. If I try to update the cell again; even after restarting the application, I get an OleDbException: System Resource Exceeded.
I know you typically receive this exception if you are creating a bunch of connections to the spreadsheet (in a loop for example), but I am only connecting once per application run. The typical work flow is.
Start application.
Call WriteChange.
Exit application.
Why am I getting this error, when the connection should be long dead by the time I try to connect again?
Use following connection string because Microsoft.Jet.OLEDB.4.0 has this error.
string ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + #Filename + ";Extended Properties=\"Excel 12.0;HDR=No;\"";
I think the error may have occured because you are not closing the OleDbconnection connection.
Close your Dbconnection after completing your update query -- `int value = cmd.ExecuteNonQuery();