using Oracle Exadata and C#: Paging data from Oracle to retrieve in datatable - c#

I am using Oracle Exadata as database and using that in a ASP.NET C# Web application.
I am trying to query the data from the database and fetch the data in data table. The data is too huge as I am using a select * option. The data table errors out with memory issues and would not be the right approach as well.
I am trying to check if a paging model can be applied.
I have used the below code model with MS SQL, which works. I am not sure how this can be applied in Oracle query. Below is the code for MS SQL.
public List<DataTable> GetDataSet()
{
var dataTables = new List<DataTable>();
var totalRecords = 0;
var tableIndex = 1;
using (var cn = new SqlConnection {ConnectionString = ConnectionString})
{
using (var cmd = new SqlCommand {Connection = cn})
{
var selectStatement =
#"SELECT Cust.CustomerIdentifier,
Cust.CompanyName,
Cust.ContactName,
C.[Name] AS Country
FROM dbo.Customers AS Cust
INNER JOIN dbo.Countries AS C
ON Cust.CountryIdentifier = C.CountryIdentifier
ORDER BY Cust.CustomerIdentifier
OFFSET #Offset ROWS
FETCH NEXT 25 ROWS ONLY;";
var countStatement = "SELECT COUNT(Cust.CustomerIdentifier) FROM dbo.Customers AS Cust";
cmd.CommandText = countStatement;
cn.Open();
totalRecords = Convert.ToInt32(cmd.ExecuteScalar());
cmd.CommandText = selectStatement;
cmd.Parameters.Add("#OffSet", SqlDbType.Int);
for (var index = 0; index < totalRecords; index++)
{
if (index % 25 == 0)
{
cmd.Parameters["#OffSet"].Value = index;
var dt = new DataTable() {TableName = $"Table{tableIndex}"};
dt.Load(cmd.ExecuteReader());
dataTables.Add(dt);
tableIndex += 1;
}
}
}
}
return dataTables;
}
I am trying to achieve the same functionality with Oracle. How to query the Oracle to get the data in this same way. Thanks

Related

How to return a data from while c# using oracle 11g

I need to return all values from my table. How to write a code inside while?
var stringConnection = "Data Source = X; User Id = X; Password = X";
var sql = "SELECT * FROM TABLE";
OracleConnection _oracleConnection = new OracleConnection(stringConnection);
_oracleConnection.Open();
OracleCommand cmd = new OracleCommand(sql, _oracleConnection);
var dr = cmd.ExecuteReader();
var list = new List<dynamic>();
while(dr.Read())
{
// my doubt is here
}
return list;
var stringConnection = "Data Source = X; User Id = X; Password = X";
var sql = "SELECT * FROM TABLE";
OracleConnection _oracleConnection = new OracleConnection(stringConnection);
_oracleConnection.Open();
OracleCommand cmd = new OracleCommand(sql, _oracleConnection);
var dr = cmd.ExecuteReader();
var list = new List<dynamic>();
while(dr.Read())
{
// **** read column name data from table ****
string Id = (string)dr["Id"];
string company = (string)dr["company"];
string city = (string)dr["City"];
var objItem = new { Id = Id, company = company, city = "city" };
list.Add(objItem);
}
return list;
You have several options. 1 - load DataSet from OracleDataReader. There you will have all your data.
2 - you can still use select *... but you need a model. Then create List<SomeModel> instead of List<dynamic> with
while (reader.Read())
{
model.Property = reader["columnName"]; // will need convert type and take care of DB null. Can use existing extnsions
. . . .
}
3 - For arbitrary number of columns use OracleDataReader.FieldCount and some storage like List<object[]>
var data = new List<object[]>();
var fCnt = reader.FieldCount;
while (reader.Read())
{
var arr = new Object[fCnt];
for(int i = 0; i < fCnt; i++)
arr[i] = reader[i];
data.Add(arr);
}
The unfortunate part with #3 is that in the end you can get jagged array and not 2-dimentional one but you now have enough info to convert it. But I don't remember when I needed to do #3. So think about #1 and #2
And one more thing - absolutely no need for dynamic here. Stay away.

How do I return a table from a SQL query as a List in C#?

I have a Xamarin app that connects to a SQL Server (*), and I want to insert the data from the SQL Server's tables into a local SQLite database. My approach is to execute a query like
select * from Table1
retrieve the results of the query as a List, then insert that List into my SQLite table. That said I'm very new at using SqlClient, so please share if there are better ways to do this. Thanks.
Edit: the smallest number of columns these tables have is 5. Don't know if that disqualifies Lists as the best option.
My code:
private void LoadData()
{
string cs = #"connection string here";
using (SqlConnection sconn = new SqlConnection(cs))
{
sconn.Open();
SqlDataReader reader = null;
SqlCommand aml = new SqlCommand("select * from Table1");
reader = aml.ExecuteReader();
while (reader.Read())
{
// get result of query as List somehow?
}
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
// insert the list object
}
}
}
}
(*) The app does not use a web service as the app is intended for onsite use only and will not be distributed publicly.
A better alternative way to do it more easier is to use a ORM like dapper
With the help of dapper, all you need to do is
using (var connection = new SqlConnection(_sqlConnectionString))
{
var results = connection.Query<YourTableModel>(query).ToList();
return results;
}
You can get data from the SQL Server as DataTable or convert it to a list as you prefer.
public DataTable GetDataTable(string connectionString, string tableName)
{
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
string query = $'SELECT * FROM [{tableName}]';
SqlCommand cmd = new SqlCommand(query, conn);
DataTable t1 = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
a.Fill(t1);
}
return t1;
}
Then use this table or list returned from the above method to insert in the SQLite table.
string cs = #"Data Source=datasource;Initial Catalog=databasename;User ID=user;Password=password";
DataTable table = GetDataTable(cs, "Table1");
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
foreach(DataRow row in table.Rows)
{
//Access values of each row column row["columnName"]
// insert the list object
}
}
}
Refer to this one:
Inserting Data from SQL Server to Sqlite

Import text file collection into SQL Server table

I am trying to collect data from a text file in order to populate a table in Sql Server. The collection part is working but at "ExecuteNonQuery" I get the "No mapping exists from object type System.Collections.Generic.List" error. I've researched this error here and at other sites and from what I can gather, the error is caused by trying to populate a table with an array or there is something wrong with my parameters. I've tried various adjustments to the code which populates the table. Haven't touch the collection code as I hate to fix what isn't broken. Here is my code:
var mbrNbr = new List<string>();
var sPages = new List<int>();
var ePages = new List<int>();
var startPage = 0;
var endPage = 0;
using (var sr = new StreamReader(#"\\path\textFile.txt"))
{
while (sr.Peek() > 0)
{
var line = sr.ReadLine();
var memberNumber = line.Substring(698,11);
var passThru = line.Substring(698,11);
var oceMax = Convert.ToInt32(line.Substring(910, 3));
if (passThru.Equals(memberNumber))
{
mbrNbr.Add(memberNumber);
startPage = endPage + 1;
endPage += oceMax * 2;
ePages.Add(endPage);
sPages.Add(startPage);
}
}
}
var sqlConn = new SqlConnection("server/db conneciton");
sqlConn.Open();
var updateSql = #"update myTable
set MemberNbr = #memberNumber,
StartPage = #startPage, EndPage = #endPage";
using (SqlCommand cmd = new SqlCommand(updateSql, sqlConn))
{
cmd.CommandTimeout = 6000;
cmd.Parameters.AddWithValue("#memberNumber", mbrNbr);
cmd.Parameters.AddWithValue("#startPage", sPages);
cmd.Parameters.AddWithValue("#endPage", ePages);
cmd.ExecuteNonQuery();
}
sqlConn.Close();
In an effort to construct a specific question, here goes: Does SQL Server not accept an array or is it a parameter issue or both?

Retrieve Data From DataTable

I am running a SQL Query which will return a count the query is
Select Count(numstudents) from classA
I am using C# to connect to SQL Server and execute this query, but my issue is, how do I get the actual number returned? My current method returns the number of rows in the DataTable which by default will always be 1. I need to get the Count() returned.
Here is full C# syntax:
private void GetData()
{
DataSet ds = new DataSet()
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("RunAStoredProc", con))
{
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandType = CommandType.StoredProcedure;
da.Fill(ds);
}
}
}
DataTable table1 = new DataTable();
table1 = ds.Tables[0];
DataTable table2 = new DataTable();
table2 = ds.Tables[1];
string numberreturned = table1.Rows.Count.ToString();
Console.WriteLine(numberreturned);
Console.ReadKey();
}
Stored procedure reads like such:
Alter Procedure [dbo].[GetData]
As
Select Count(*) FROM classA
Select studentfirstname, studentlastname FROM classA
Where enrolled = 'Yes'
You don't need an SqlDataAdapter and all the infrastructure required to work with if you just have a single value returned by your Stored Procedure. Just use ExecuteScalar
int count = 0;
using (var con = new SqlConnection(connectionString))
using (var cmd = new SqlCommand("RunAStoredProc", con))
{
cmd.CommandType = CommandType.StoredProcedure;
count = (int)cmd.ExecuteScalar();
}
Console.WriteLine(count);
Console.ReadKey();
However if your really want to use an adapter and a dataset then you can find the result of your query reading the value from the first row and first column from the returned table
int count = Convert.ToInt32(table1.Rows[0][0]);
or even (without declaring the table1 variable)
int count = Convert.ToInt32(ds.Tables[0].Rows[0][0]);
To discover the difference between the result of the first select statement and the count of rows returned in the second select statement you could write
int allStudents = Convert.ToInt32(ds.Tables[0].Rows[0][0]);
int enrolledStudents = ds.Tables[1].Rows.Count;
int notEnrolledStudents = allStudents - enrolledStudents;

Get SQL query result in Datatable using Servicestack ormlite

I am new to Servicestack Ormlite.
I want to execute the SQL query on database using Servicestack Ormlite and get the results in datatable.
SQL query will be generated randomly, containing different tables, columns each time. So I can't use poco class for the same.
We are using SQL Server as the database.
OrmLite doesn't support or have any dependencies on DataTables or DataSets which as a code-first POCO ORM is strictly opposed against the use of.
See the Dynamic Result Set docs for examples of querying untyped structures, either in a object List:
db.Select<List<object>>(db.From<Poco>()
.Select("COUNT(*), MIN(Id), MAX(Id)"));
Or Dictionary:
db.Select<Dictionary<string,object>>(db.From<Poco>()
.Select("COUNT(*) Total, MIN(Id) MinId, MAX(Id) MaxId"));
you can use CreateCommand method to get a datareader, like this:
var dt = new DataTable();
using (var db = dbFactory.Open())
using (var cmd = db.CreateCommand())
{
cmd.CommandText = "select * from [table]";
cmd.CommandType = CommandType.Text;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var row = dt.NewRow();
for (int i = 0; i < reader.FieldCount; i++)
{
if (dt.Columns == null || dt.Columns.Count == 0)
{
for (int j = 0; j < reader.FieldCount; j++)
{
dt.Columns.Add(reader.GetName(j), reader.GetFieldType(j));
}
}
var cell = reader.GetValue(i);
row[i] = cell;
}
dt.Rows.Add(row);
}
}
}

Categories