SQLITE - Open two connections (read and write) at once - c#

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!

Related

MySQL SELECT INTO Variable, Getting 'Fatal Error encountered during command execution.'

I have tried MANY suggested solutions from here but nothing seems to work for this problem. I just keep getting this error message when it hits the 'mdr = command.ExecuteReader();' line. Any thoughts please?
try
{
MySqlConnection connection = new MySqlConnection("SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";");
MySqlCommand command;
MySqlDataReader mdr;
connection.Open();
string ThePID = tbPID.Text;
string TheRound = tbRound.Text;
string CurrentPage = tbCurrentPage.Text;
// SELECT #myvar:= myvalue
string query = "SELECT ImageURL, ProofingText " +
"INTO #ImageURL, #ProofingText " +
"FROM Rounds " +
"WHERE ProjectID = " + ThePID + " " +
"AND CurrentRound = " + TheRound + " " +
"AND Page = " + CurrentPage + ";";
command = new MySqlCommand(query, connection);
mdr = command.ExecuteReader();
mdr.Read();
rtProofing.Text = mdr.GetString("#PRoofingText");
tbURL.Text = mdr.GetString("#ImageURL");
tbImagePage.Text = Path.GetFileName(tbURL.Text);
PageBox.Image = Image.FromFile(tbURL.Text);
connection.Close();
connection.Dispose();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
If you use MySqlConnector, you will get a helpful exception message that explains the problem:
Parameter '#ImageURL' must be defined. To use this as a variable, set 'Allow User Variables=true' in the connection string.
By default, MySQL queries (executed from .NET) can't use user-defined variables. You can relax this limitation by adding Allow User Variables=true to your connection string.
However, this won't fix your underlying problem, which is that this isn't the right way to select data from MySQL.
Firstly, your query is susceptible to SQL injection; you should rewrite it to use parameters as follows:
using (var command = connection.CreateCommand())
{
command.CommandText = #"SELECT ImageURL, ProofingText
FROM Rounds
WHERE ProjectID = #ThePID
AND CurrentRound = #TheRound
AND Page = #CurrentPage;";
commands.Parameters.AddWithValue("#ThePID", ThePID);
commands.Parameters.AddWithValue("#TheRound", TheRound);
commands.Parameters.AddWithValue("#CurrentPage", CurrentPage);
Then, you can retrieve the values with a slight variation on your current code. You must retrieve the values by their column names, which do not have a leading #. You should also check that a row was retrieved by examining the return value of Read():
if (mdr.Read())
{
rtProofing.Text = mdr.GetString("ProofingText");
tbURL.Text = mdr.GetString("ImageURL");
}
Finally, string concatenation is also not the right way to build a connection string. The MySqlConnectionStringBuilder class exists for this purpose; use it.
var builder = new MySqlConnectionStringBuilder
{
Server = server,
Database = database,
UserID = uid,
Password = password,
};
using var connection = new MySqlConnection(csb.ConnectionString);

SELECT ODBC table and INSERT into SQL Server

I have an ODBC connection to a database of which I need one table of data with 10 columns.
I need to insert this table into SQL Server database. I´ve tried to many ways to do it but still with any results.
OdbcConnection OCon = new OdbcConnection("Dsn=" + DbSource.SelectedItem.ToString());
SqlConnection SCon = new SqlConnection("Data Source=" + SrvrDD.SelectedItem.ToString() + ";database=" + DdDestiny.SelectedItem.ToString() + ";User ID=id;Password=pass");
OCon.Open();
SCon.Open();
String QrySelect ="SELECT * FROM " + GridCon.Rows[x].Cells[1].Value;
OdbcCommand commandC = new OdbcCommand(QrySelect, OCon);
String QryInsert = "INSERT INTO " + DdDestiny.SelectedItem.ToString() + ".dbo." + GridCon.Rows[x].Cells[2].Value + " VALUES (#Sql)";
SqlCommand commandD = new SqlCommand(QryInsert, SCon);
OdbcDataReader Oreader = commandC.ExecuteReader();
commandD.Parameters.Add("#Sql",SqlDbType.NVarChar, 5);
while (Oreader.Read())
{
string s = Oreader[0].ToString();
commandD.Parameters["#Sql"].Value = s;
commandD.ExecuteNonQuery();
}
Everything works fine but when commandB.ExecuteNonQuery(); get in, an error appears:
"The column name or the specified values do not correspond to the definition of the table."
Is the translation.

I am able to retrieve the artist, name and genre from the database but not the price. What should the code be to retrieve the price?

This is an example of one of the buttons. [I am able to retrieve the artist, name and genre from the database but not the price. What should the code be to retrieve the price? I have set the price datatype to varchar(50) in the database then tried the decimal and int and non of them work
protected void btnSong6_Click(object sender, EventArgs e)
{
string Name = "In the end";
Product Music = new Product();
string constr = ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(constr);
con.Open();
string SelectCommand = "select Genre,Name,Artist, Price from Music WHERE name = '" + Name + "' ";
SqlCommand cmd = new SqlCommand(SelectCommand, con);
SqlDataReader read = cmd.ExecuteReader();
read.Read();
Music.Artist = read["artist"].ToString();
Music.Name = read["name"].ToString();
Music.Genre = read["genre"].ToString();
Music.Price= read["price"].ToString();
//ADD PRICE!!
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name);
}
Your code looks fine, you are not using 'price' for anything though. Not exactly sure what you would like to do with 'price, maybe add it to 'listMusic'?
If 'Music.Price'is a decimal you will need to convert it:
Music.Price = Convert.ToDecimal(read["price"]);
Then add it to 'listMusic':
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name + " $" + Music.Price);
You should also consider changing your database 'price' column to Decimal. Above code should work either way.
To reduce the amount of type conversions required when retrieving column values have a look at this article. DataReader provides a series of methods allowing you to access column values in their native data types.
Something like:
using (SqlConnection con = new SqlConnection(constr))
{
string SelectCommand = "select Genre,Name,Artist, Price from Music WHERE Name = '" + Name + "' ";
SqlCommand cmd = new SqlCommand(SelectCommand, con);
con.Open();
SqlDataReader read = cmd.ExecuteReader();
if (read.HasRows)
{
while (read.Read())
{
Music.Genre = read.GetString(0);
Music.Name = read.GetString(1);
Music.Artist = read.GetString(2);
Music.Price = read.GetDecimal(3);
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name + " $" + Music.Price);
}
}
}

Importing .DAT file to Database?

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.

c# application holding file even I've finished work with it

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!

Categories