Opening Different Tables in a Database - c#

So I have 3 different tables in a MySQL Database called "MyDB", the tables inside are table1, table2, table3. Here is my code to query the 3 tables in the database but it keeps breaking and I can't figure out why. Creating this for a Google Maps Javascript API v3.
private static IEnumerable<HeatMapDataElement> QueryHeatMapDataFromDatabase(string reqDate, string reportType)
{
const string connectionString = "connection_credentials";
var ds = new DataSet();
var elements = new List<HeatMapDataElement>();
var conn = new MySqlConnection(connectionString);
MySqlCommand cmd;
var da = new MySqlDataAdapter();
conn.Open();
try
{
cmd = conn.CreateCommand();
cmd.CommandTimeout = 30;
cmd.CommandText =
"select RequestHour, longitude, latitude, count(requesttime) as Weight from MyDB.table1 || MyDB.table2 || MyDB.table3 where method=#ReportType and requestdate = date(#RequestDate) and longitude is not null and latitude is not null and requesthour is not null group by RequestHour, longitude, latitude";
cmd.Parameters.AddWithValue("#ReportType", reportType);
cmd.Parameters.AddWithValue("#RequestDate", reqDate);
da.SelectCommand = cmd;
da.Fill(ds);
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
elements.AddRange(from DataRow dr in ds.Tables[0].Rows
select new HeatMapDataElement()
{
Latitude = Double.Parse(dr["latitude"].ToString()), Longitude = Double.Parse(dr["longitude"].ToString()), Hour = int.Parse(dr["RequestHour"].ToString()), Weight = int.Parse(dr["Weight"].ToString())
});
}
}
catch (Exception ex)
{
throw ex; //breaks here <-------
}
finally
{
conn.Close();
da = null;
cmd = null;
}
return elements.AsEnumerable();
}
Error is: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '|| MyDB.table2 where method='Table 2' and requestdate =' at line 1

You're mixing up C# code and SQL code. AFAIK pipe operator can only be used in mysql to join columns not tables, and even then, it's disabled by default, so I think that you need to use INNER JOIN
If you're reading from 3 tables you would do an inner join between the 3 tables, something like this:
select * from table1 inner join table2 on table1.key = table2.key

Related

C# How to get all data in Oracle database

I have 21 tables in Oracle 11g, and I need to display them using JOIN clauses. But the query is too slow and throws an System.OutOfMemoryException
My current code:
try
{
//string ConString;
using (OracleConnection con = new OracleConnection(ConString))
{
//string query = "SELECT PAX.CREATION_DATE,PAX.PNR,PAX.PAX_NMBR,PAX.UPDATE_LEVEL_MOD,PAX.PAX_NAME,PAX.CHANGE_OR_CANCEL_IND,PAX_SEATS.LEG_NMBR,PAX_SEATS.INSTANCE_NMBR,pax_seats.ssr_cd,pax_seats.carrier_cd,pax_seats.seat_nmbr,pax_seats.previous_status_codes FROM PAX INNER JOIN PAX_SEATS ON PAX.PNR = PAX_SEATS.PNR";
string query1 = "SELECT PNR FROM HISTORY_LEGS";
string query2 = "SELECT PAX.CREATION_DATE,PAX.PNR,PAX.PAX_NMBR,PAX.UPDATE_LEVEL_MOD,PAX.PAX_NAME,PAX.CHANGE_OR_CANCEL_IND,PAX_SEATS.LEG_NMBR,PAX_SEATS.INSTANCE_NMBR,pax_seats.ssr_cd,pax_seats.carrier_cd,pax_seats.seat_nmbr,pax_seats.previous_status_codes,PAX_SSRS.SSR_NMBR,PAX_TKT.TKTNMBR,PAX_TKT.ISSUING_AIRLINE, PAX_TKT.ISSUING_OFFC_NMBR, PAX_TKT.ISSUING_COUNTER_CD, PAX_TKT.ISSUING_AGNT_NMBR, PAX_TKT.TKT_IND, PAX_TKT.TKT_STATUS, PAX_TKT.TARIFICATION_IND,PAX_TKT.S_IND,PAX_TKT.ISSUANCE_DATE FROM PAX INNER JOIN PAX_SEATS ON PAX.PNR = PAX_SEATS.PNR RIGHT JOIN PAX_SSRS ON PAX.PNR = PAX_SSRS.PNR RIGHT JOIN PAX_TKT ON PAX.PNR = PAX_TKT.PNR";
//string query4 = "SELECT * FROM PAX";
//string query3 = "SELECT PAX.PAX_NMBR,PAX.PAX_NAME,RES_LEGS.ARNK_IND,RES_LEGS.CARRIER_CD1,RES_LEGS.CARRIER_CD2,RES_LEGS.FLT_NMBR,RES_LEGS.CLASS_CD,RES_LEGS.DAY_OF_WEEK,RES_LEGS.FLT_DATE,RES_LEGS.LEG_ORIGIN_CD,RES_LEGS.LEG_DES_CD,RES_LEGS.CURRENT_STATUS_CD,RES_LEGS.NUMBER_IN_PARTY,RES_LEGS.DP_TIME,RES_LEGS.AR_TIME,RES_LEGS.DATE_CHANGE_IND,RES_LEGS.FLT_IRREGULARITY_IND,RES_LEGS.LEG_TXT,RES_LEGS.PREVIOUS_STATUS_CODES,RES_LEGS.MESSAGE FROM RES_LEGS INNER JOIN PAX ON RES_LEGS.PNR = PAX.PNR";
OracleCommand cmd = new OracleCommand(query2, con);
OracleDataAdapter oda = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
oda.Fill(ds);
//dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
//dataGridView1.RowHeadersVisible = false;
if (ds.Tables.Count > 0)
{
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Questions:
How to get all data?
How to prevent System.OutofMemory?
How to speed up query execution performance?
You can look at indexes on your key fields to speed up the query a bit perhaps, but if you are getting a lot of rows back you'll be hitting some memory caps somewhere.
If you can, I would suggest implementing some paging: Paging with Oracle.
This will let you bring back smaller chunks of your data making it quicker and less likely to hit any memory limits.

Column 'RecordsDate.StartDateTime' is invalid in the HAVING clause because it is

*sorry the title cannot be too long so I have to cut it down.
hi, I would like to get the total duration from my database table where the
dateID is 1 and the year of the datetime is 2016 using SQL Query in asp.net c#. I tried using the codes below but it does not work. It says 'Additional information: Column 'RecordsDate.StartDateTime' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.' Can anyone tell me what's wrong with my SQL Query please? Thanks a lot :)
float totalDuration = 0f;
string sQuery = "SELECT sum(Duration) AS TotalDuration FROM RecordsDate WHERE DateID='1' HAVING DATEPART(yyyy, StartDateTime) = '2016'";
SqlConnection conn = new SqlConnection(_connStr);
SqlCommand cmd = new SqlCommand(sQuery, conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
totalDuration = float.Parse(dr["TotalDuration"].ToString());
}
conn.Close();
dr.Close();
Provide group by with some column name from the table:
select sum(duration) as totalduration from recordsdate
where dateid='1' having datepart(yyyy, startdatetime) = '2016'
group by ?

C# How to Retrieve DateSet Value in SqlDataAdapter?

In the development, I intent to retrieve the Index Key from SQL Server Database and apply to the local.sdf database. However, I failed to retrieve the Index Key from SQL Server Database. So, how could i retrieve the value stored in DataSet?
E.g: tableName = "ProductTable", indexName = "IX_product".
Or my SqlDataAdapter doesn't return any value?
P/s: I understand that there are numerous of working tutorial in forum and stackoverflow, unfortunately, i couldn't get it worked.
private void btnGetSchema_Click(object sernder, RoutedEventArgs e)
{
SyncDbSchema();
}
private void SyncDbSchema()
{
// setIndexSchema();
DataSet dsIndex = getIndexSchema();
MessageBox.Show("Table Row Count : " + dsIndex.Tables["tbIndex"].Rows.Count);
for (int i = 0; i < dsIndex.Tables[0].Rows.Count; i++)
{
string tableName = dsIndex.Tables[0].Rows[i]["TableName"].ToString();
string indexName = dsIndex.Tables[0].Rows[i]["IndexName"].ToString();
string indexType = dsIndex.Tables[0].Rows[i]["IndexType"].ToString();
}
}
public DataSet getIndexSchema()
{
SqlConnection conn = new SqlConnection(lblServerCon.Content.ToString());
DataSet dataSet = new DataSet();
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
conn.Open();
sqlDataAdapter = new SqlDataAdapter(String.Format(#"USE SyncServer SELECT T.[name] AS [TableName], I.[name] AS [IndexName],
COL_NAME(T.[object_id], IC.[column_id]) AS [ColumnName], I.[type] AS [IndexType], I.[is_unique] AS [Unique]
FROM sys.tables T INNER JOIN [sys].[indexes] I ON I.[object_id] = T.[object_id]
AND I.[is_primary_key] = '0'
INNER JOIN [sys].[index_columns] IC ON IC.[object_id] = T.[object_id]
AND IC.[index_id] = I.[index_id]"), conn);
sqlDataAdapter.FillSchema(dataSet, SchemaType.Source,"tbIndex");
conn.Close();
return dataSet;
}
The query is perfect working in T-SQL and get the result that i intent to retrieve.
TableName IndexName ColumnName IndexType Unique
tbReport IX_tbReport_SID SalesID 2 0
tbReport IX_tbReport_RID ReportID 2 0
Are you sure that you want to use FillSchema?
Why not just?
adapter.Fill(dataSet);
Of course you can combine them first FillSchema (but why you need it?), next data (just Fill)

SQL LIKE % NOT SEARCHING

I want to perform a simple search using the SQL LIKE function. Unfortunately for some reason , it doesn't seem to be working. Below is my code.
private void gvbind()
{
connection.Open();
string sql = "";
if (txtSearch.Text.Trim() == "")
{
sql = "SELECT a.cname,[bid],b.[bname],b.[baddress],b.[bcity],b.[bstate],b.[bpostcode],b.[bphone],b.[bfax],b.[bemail] FROM [CLIENT] a INNER JOIN [BRANCH] b ON a.clientID=b.clientID ORDER BY a.[clientID]";
}
else
{
sql = "SELECT a.cname,[bid],b.[bname],b.[baddress],b.[bcity],b.[bstate],b.[bpostcode],b.[bphone],b.[bfax],b.[bemail] FROM [CLIENT] a INNER JOIN [BRANCH] b ON a.clientID=b.clientID WHERE b.[bname] LIKE '%#search%' ORDER BY a.[clientID]";
}
SqlCommand cmd = new SqlCommand(sql,connection);
cmd.Parameters.AddWithValue("#search", txtSearch.Text.Trim());
cmd.CommandType = CommandType.Text;
SqlDataAdapter adp = new SqlDataAdapter();
adp.SelectCommand = cmd;
DataSet ds = new DataSet();
adp.Fill(ds);
connection.Close();
if (ds.Tables[0].Rows.Count > 0)
{
gvBranch.Enabled = true;
gvBranch.DataSource = ds;
gvBranch.DataBind();
}
else
{
ds.Tables[0].Rows.Add(ds.Tables[0].NewRow());
ds.Tables[0].Rows.Add(ds.Tables[0].NewRow());
gvBranch.DataSource = ds;
gvBranch.DataBind();
int columncount = gvBranch.Rows[0].Cells.Count;
gvBranch.Rows[0].Cells.Clear();
gvBranch.Rows[0].Cells.Add(new TableCell());
gvBranch.Rows[0].Cells[0].ColumnSpan = columncount;
gvBranch.Rows[0].Cells[0].Text = "No Records Found";
}
ds.Dispose();
}
the above method is called in the Page_Load() method using
if((!Page.IsPostBack))
{
gvBind();
}
it is called on button search click aslo. However, it return No record found when ever i perform the search.
Use
LIKE '%' + #search + '%'
instead of
LIKE '%#search%'
Full query;
...
else
{
sql = "SELECT a.cname,[bid],b.[bname],b.[baddress],b.[bcity],b.[bstate],b.[bpostcode],b.[bphone],b.[bfax],b.[bemail] FROM [CLIENT] a INNER JOIN [BRANCH] b ON a.clientID=b.clientID WHERE b.[bname] LIKE '%' + #search + '%' ORDER BY a.[clientID]";
}
And actually, you don't need to use square brackets ([]) every column in your query. Use them if your identifiers or object names are a reserved keyword.
Thanks. It works , but any explanation for that?
The main problem is here, your query parameter is inside quotes. In quotes, SQL Server will recognize it as a string literal and never sees it as a parameter.

Error: Invalid attempt to call Read when reader is closed after the while loop?

Hello i have a method which reads some data from the sql and saves them to arrays.
to find out how many rows the sql result has i wrote this:
DataTable dt = new DataTable();
dt.Load(rdr);
count = dt.Rows.Count;
after that, the sqldatareader saves the results to arrays.
here is my complete code:
public BookingUpdate[] getBookingUpdates(string token)
{
String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
SqlConnection connection = new SqlConnection(GetConnectionString());
BookingUpdate[] bookingupdate = new BookingUpdate[1];
connection.Open();
try
{
SqlCommand cmd = new SqlCommand(command, connection);
SqlDataReader rdr = null;
int count = 0;
int c = 0;
rdr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rdr);
count = dt.Rows.Count;
bookingupdate = new BookingUpdate[count];
while (rdr.Read()) // <--- HERE COMES THE ERROR
{
bookingupdate[c] = new BookingUpdate();
bookingupdate[c].bookingID = Convert.ToInt32(rdr["ID"]);
bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
bookingupdate[c].newStart = (DateTime)rdr["VON"];
bookingupdate[c].newEnd = (DateTime)rdr["BIS"];
bookingupdate[c].newSubject = rdr["THEMA"].ToString();
bookingupdate[c].newlocation = rdr["BEZEICHNUNG"].ToString();
if (rdr["STORNO"].ToString() != null)
{
bookingupdate[c].deleted = true;
}
else
{
bookingupdate[c].deleted = false;
}
c++;
}
}
catch (Exception ex)
{
log.Error(ex.Message + "\n\rStackTrace:\n\r" + ex.StackTrace);
}
finally
{
connection.Close();
}
return bookingupdate;
}
the exeption is : Invalid attempt to call Read when reader is closed
The Load-Method closes the DataReader, hence a following call to Read() fails (well, that's excatly what the exception tells you).
Once you read the data into your DataTable, you could simply query it and use a Select projection to create your BookingUpdate instances (no need for the while-loop/BookingUpdate[]). So your code can basically trimmed down to
String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
SqlCommand cmd = new SqlCommand(command, new SqlConnection(GetConnectionString()));
connection.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
var bookingupdate = dt.Rows.OfType<DataRow>().Select (row =>
new BookingUpdate
{
bookingID = Convert.ToInt32(row["ID"]),
fullUserName = row["VERANSTALTER"].ToString(),
newStart = (DateTime)row["VON"],
newEnd = (DateTime)row["BIS"],
newSubject = row["THEMA"].ToString(),
newlocation = row["BEZEICHNUNG"].ToString(),
deleted = row["STORNO"].ToString() != null // note that this line makes no sense. If you can call `ToString` on an object, it is not 'null'
}).ToArray();
return bookingupdate;
(Note: I omited the try-block for readability)
You may also want to look into the DataRowExtensions, especially the Field method, to make your code more readable.
DataTable.Load(IDataReader) closes reader after loading data from it. Use DataTable to get data you loaded.
You have already processed the reader at the following line due to which reader is at EOF/Closed:
dt.Load(rdr);
If you want to process the records after above method call, you should make use of your created DataTable object dt by above line unsing for loop with dt.Rows.Count instead of while (rdr.Read())
Checkout this topic from MSDN

Categories

Resources