oledb, visual fox pro and c# - c#

I have visual fox pro database with thousands of rows. I am using oledb to fetch data from fox pro and export(after doing some calculation and fomatting) it to sql server.I have used dataset to populate 2-3 datatable(related table) at a time.
First problem is that the memory use is very high because the dataset are huge.I want to reduce memory footprint.Any suggestion for this.
So i have decided to fetch few rows at a time.How do i fetch rows using oledb command so that i can fetch for eg 1-20 and then 20-40 etc

Based on all the comments and HatSoft's code here is what I think you are looking for. This is pseudo-code, whcih means it will not compile but should give you a good idea of where to go from here.
int NumberOfRecordsToRetrieve = 10000;
int StartRecordNumber = 1;
bool EndOfFile = false;
string queryString = "SELECT OrderID, CustomerID FROM Orders WHERE RECNO() BETWEEN #StartRecordNumber AND #EndRecordNumber";
While (!EndOfFile)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Parameters.Add(new OleDbParameter("#StartRecordNumber", StartRecordNumber));
command.Parameters.Add(new OleDbParameter("#EndRecordNumber", StartRecordNumber + NumberOfRecordsToRetrieve));
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
EndOfFile = true;
while (reader.Read())
{
EndOfFile = false
//Retrieve records here and do whatever process you wish to do
}
reader.Close();
StartRecordNumber += NumberOfRecordsToRetrieve;
}
}

string queryString = "SELECT OrderID, CustomerID FROM Orders WHERE ORDERID >= #StartOrderID AND ORDERID <= #EndOrderID";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Parameters.Add(new OleDbParameter("#StartOrderID", "PASS THE VALUE HERE"));
command.Parameters.Add(new OleDbParameter("#EndOrderID", "PASS THE VALUE HERE"));
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//Retrieve records here
}
reader.Close();
}

Related

Id request from the database

I'm trying to write the id request from the database. This is how I wrote it:
public int QueryId(String query)
{
var temp = this.connection;
MySqlCommand verifica = new MySqlCommand(query, connection);
var queryResult = verifica.ExecuteScalar();
return Convert.ToInt32(verifica.ExecuteScalar());
}
This is how I make use of the function:
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
nomeCorrente = reader.GetString("nome");
cognomeCorrente = reader.GetString("cognome");
idCorrente = db.QueryId("SELECT id FROM thewishlist.user WHERE email='" + user.Text + "'");
}
reader.Close();
db.CloseConnection();
It does not generate errors, but when I run the project and log out the user gives me the following error:
MySql.Data.MySqlClient.MySqlException There is already an open DataReader associated with this Connection which must be closed first.
The error is pretty clear. I suggest you make use of using statement and also since you're only returning one column you and use ExcecuteScalar instead of ExecuteReader. So your code will look something like:
var id = 0;
var query = "SELECT ID FROM thewishlist.user WHERE email = #email";
using (var con = new SqlConnection(this.connection))
{
using (var cmd = new SqlCommand(query, con))
{
con.Open();
cmd.Parameters.Add("#email", SqlDbType.NVarChar).Value = user.Text;
id = (int)cmd.ExecuteScalar();
}
}//connection will auto close here and object will get disposed
return id;
Also to prevent sql injection you should always use paramertised sql queries.
As Jason said that, you should close the reader firstly, then call db.QueryId to execute the new query, I modifed your code as follows:
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
nomeCorrente = reader.GetString("nome");
cognomeCorrente = reader.GetString("cognome");
}
reader.Close();
}
idCorrente = db.QueryId("SELECT id FROM thewishlist.user WHERE email='" + user.Text + "'");
db.CloseConnection();

C# Query MS-Access Table and place read values from column in a text box

Below is a snapshot of my code. I am trying to access the only column in the customer table and place the values into a textbox on the form. I keep getting the error with my code "InvalidOperationException was unhandled" at the line declaring dr as a OleDbDataReader object.
What do I have wrong with the below code that would be giving me this error?
Should I do a list to pick out the text I want from the database?
How can I return the column values from access into a list in C# so that I can search the list for a particular value?
string strsql = "Select * from Customer";
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
textBox1.Text += dr["Customer"].ToString();
}
conn.Close();
A command carries the info to be executed, a connection carries the info to reach the database server. The two objects should be linked together to produce any result. You miss that line
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
cmd.Connection = conn; // <= here
conn.Open();
Remember also that disposable objects like a command, a reader and a connection should be disposed immediately after usage. For this pattern exists the using statement
So you should write
string cmdText = "Select * from Customer";
using(OleDbConnection conn = new OleDbConnection(.....constring...))
using(OleDbCommand cmd = new OleDbCommand(cmdText, conn))
{
conn.Open();
using(OleDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
.....
}
}
Here is some sample code.
try
{
using (OleDbConnection myConnection = new OleDbConnection())//make use of the using statement
{
myConnection.ConnectionString = myConnectionString;
myConnection.Open();//Open your connection
OleDbCommand cmdNotReturned = myConnection.CreateCommand();//Create a command
cmdNotReturned.CommandText = "someQuery";
OleDbDataReader readerNotReturned = cmdNotReturned.ExecuteReader(CommandBehavior.CloseConnection);
// close conn after complete
// Load the result into a DataTable
if (readerNotReturned != null) someDataTable.Load(readerNotReturned);
}
}
After that you have a Datatable containing your data. Ofcourse you can afterwards search for records in the Datatable any way you like.

Get value from database not behaving as expected

I'm making an asp.net application, I'm trying to read data from sql tables, but data just wont compare, as I don't get the message "You don't have a bank account, you can't register to our website"
SqlConnection connection = new SqlConnection(#"Data Source=SHKELQIM\SQLEXPRESS;Initial Catalog=E-Banking;Integrated Security=True");
connection.Open();
SqlDataReader reader = null;
SqlCommand command = new SqlCommand("SELECT * FROM ACCOUNTS WHERE Accountnumber='" + accountnumber1.Text + "'", connection);
reader = command.ExecuteReader();
if (reader.Read())
{
string getAccountNumber = reader[0].ToString();
reader.Close();
if (getAccountNumber != accountnumber1.Text)
{
lblaccountnumber.Visible = true;
lblaccountnumber.Text = "You don't have a bank account, you can't register to our website";
}
}
The best way to find this issue is to put a break point on the line:
if (getAccountNumber != accountnumber1.Text)
and see why the values do not match.
My guess is that account number is not the first column in your SELECT * query, thus reader[0].ToString() is not really the account number, but another value. Instead get the column index via the column name, like this:
string getAccountNumber = reader.GetString(reader.GetOrdinal("Accountnumber"));
It would also be a great idea to use a parameterized query so you do not get a visit from Little Bobby Tables.
Here is your code using a parameterized query:
string theQuery = "SELECT * FROM ACCOUNTS WHERE Accountnumber=#AccountNumber";
SqlCommand command = new SqlCommand(theQuery, connection);
command.Parameters.AddWithValue("#AccountNumber", accountnumber1.Text);
reader = command.ExecuteReader();
I would check reader.HasRows property and show the message
using (SqlConnection connection = new SqlConnection(#"Data Source=SHKELQIM\SQLEXPRESS;Initial Catalog=E-Banking;Integrated Security=True"))
using(SqlCommand command = new SqlCommand("SELECT * FROM ACCOUNTS WHERE Accountnumber= #Accountnumber", connection))
{
command.Parameters.AddWithValue("Accountnumber", accountnumber1.Text);
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
if (!reader.HasRows)
{
lblaccountnumber.Visible = true;
lblaccountnumber.Text = "You don't have a bank account, you can't register to our website";
}
}
}

Database gets stuck on SELECT operation

I'm using MS Sql database in my application and when I do SELECT operation from database it stucks for a few minutes.
And it happens a few times per day. All other SELECTS take several seconds only.
Also I noticed if I close app while SELECT operation is in progress. It will not work at all on any next app starts UNTIL I restart database engine...
Why could it be?
Here is the code snippet:
using (SqlConnection myConnection = new SqlConnection(connString))
{
myConnection.Open();
SqlCommand command = myConnection.CreateCommand();
SqlTransaction transaction;
transaction = myConnection.BeginTransaction("LockTransaction");
command.Connection = myConnection;
command.Transaction = transaction;
try
{
int recordsAtOnce = maxToLock;
command.CommandText =
"SELECT TOP 1000 id, productName from Parts WHERE part_used is NULL;";
List<string> idList = new List<string>();
SqlDataReader myReader = command.ExecuteReader(CommandBehavior.Default);
while (myReader.Read())
{
string id = myReader.GetString(1);
string name = myReader.GetInt32(0).ToString();
idList.Add(id);
}
myReader.Close();
string idsStr = "";
for(int i = 0; i < idList.Count; i++)
{
if (i != 0)
{
idsStr += ", ";
}
idsStr += idList[i];
}
// lock record
command.CommandText = "UPDATE Parts SET part_used=\'rt\' WHERE id in (" + idsStr + ")";
command.Parameters.Clear();
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
I think your reader values are being assigned to the wrong variables.
Try changing:
string id = myReader.GetString(1);
string name = myReader.GetInt32(0).ToString();
idList.Add(id);
To:
string id = myReader.GetInt32(0);
string name = myReader.GetString(1).ToString();
idList.Add(id);
This is most probably because of a lock. If another transaction is writing into the Parts table, your select needs to wait.
How big is the Parts table? That could cause performance problems. Or it could be another transaction locking before you.
Other things:
Call dispose on your connection, command and reader when done with them via using
Parameterize the second query rather than string concating. It's more secure and significantly more performant because of how Sql Server works internally.
minor: If you're looking at thousands of items, use StringBuilder instead of concatenating.

Select a data from MS SQL Server 2005

I have a table named t_Student in Microsoft SQL Server 2005 database. In that table there are three columns named student_regiNo, student_Name, student_Email.
I'm using following code segment to retrieve "student_Name". But instead of showing "student_Name" it shows "System.Data.SqlClient.SqlDataReader". Whats the problem?
private void GetDatabaseConnection()
{
string connectionString = #"server=RZS-F839AD139AA\SQLEXPRESS; Integrated Security = SSPI; database = StudentCourseInformation";
connection = new SqlConnection(connectionString);
connection.Open();
}
public string GateStudentName(string selectedStudentRegiNo)
{
GetDatabaseConnection();
string selectedStudentQuery = #"SELECT student_Name FROM t_Student WHERE (
student_regiNo =
'" +selectedStudentRegiNo+ #"'
)";
SqlCommand command = new SqlCommand(selectedStudentQuery, connection);
SqlDataReader reader = command.ExecuteReader();
string selectedStudentName = Convert.ToString(reader);
return selectedStudentName;
}
Use
return (string)command.ExecuteScalar();
as far as you have to return "the first column of the first row in the result set returned by the query" (from MSDN)
Also use parametrized query:
var command = new connection.CreateCommand()
command.CommandText = "SELECT student_Name FROM t_Student WHERE student_regiNo = #number";
command.Parameters.AddWithValue(#number, selectedStudentRegiNo);
ExecuteReader returns a SqlDataReader. You need to use the SqlDataReader API to read the data from it. Don't forget that a query can return multiple rows, with multiple columns in each row. For example:
while (reader.Read())
{
string name = reader.GetString(0);
Console.WriteLine("Read name: {0}", name);
}
Further note that you should use a parameterized query rather than including the ID directly into the SQL - otherwise you leave yourself open to SQL injection attacks. See the docs for SqlCommand.Parameters for more information.
Finally, you should use using statements for the SqlConnection, SqlCommand and SqlDataReader so that you dispose of them appropriately. Otherwise you're going to leak database connections.
if (reader.Read())
{
string selectedStudentName = reader.GetString(0);
}
SqlCommand command = new SqlCommand(selectedStudentQuery, connection);
SqlDataReader reader = command.ExecuteReader();
if(reader.Read())
{
return reader["student_Name"];
}
return "not exist";

Categories