Between dates Oracle from c# using Oracle.dataaccess client - c#

I have used the below query to access the data from Oracle all_objects view. When trying the same from Oracle SQL Developer it work fine and from C# code it is not fetching any data.
SELECT OBJECT_NAME,OBJECT_TYPE,CREATED,LAST_DDL_TIME
FROM sys.all_objects
where object_type='TABLE'
AND OWNER='SYS'
AND LAST_DDL_TIME between to_date('01/01/2013','DD/MM/YYYY')
and to_date('01/10/2016','DD/MM/YYYY')
If I use the below query without any filter it works fine in both Oracle and from C# as well...
SELECT OBJECT_NAME,OBJECT_TYPE,CREATED,LAST_DDL_TIME FROM sys.all_objects
Any idea that why it is not working?
Below are the sample value that is passed in the getDatSet function, Dates are select from c# DateTimepicker
strFromDate - {2/15/2012 12:00:00 AM}
strToDate - {11/15/2016 2:31:48 PM}
public DataSet GetDataSet(DateTime strFromDate, DateTime strToDate, List<string> strObjects)
{
OracleCommand objCmd;
OracleDataAdapter objDA;
DataSet objDS;
string StrSqlObjects = string.Empty; ;
try
{
StrSqlObjects += " SELECT OBJECT_NAME,OBJECT_TYPE,CREATED,LAST_DDL_TIME FROM sys.all_objects where ";
StrSqlObjects += " LAST_DDL_TIME between to_date(:startdate,'DD/MM/YYYY') and to_date(:enddate,'DD/MM/YYYY')";
objCmd = new OracleCommand(StrSqlObjects);
objCmd.Connection = m_Conn;
objCmd.Parameters.Clear();
objCmd.Parameters.Add("startdate", strFromDate);
objCmd.Parameters.Add("enddate",strToDate);
objDA = new OracleDataAdapter();
objDA.SelectCommand = objCmd;
var oracleCommandBindByNameProperty = objCmd.GetType().GetProperty("BindByName");
oracleCommandBindByNameProperty.SetValue(objCmd, true, null);
objDS = new DataSet();
objDS.Tables.Add("AllChange");
objDA.Fill(objDS, "Allchange");
}
catch (System.Exception e)
{
System.Diagnostics.Debug.WriteLine("Error GetDataSet " + e.Message);
throw e;
}
finally
{
CloseConnection();
}
return objDS;
}

Related

Filter data from sql with datetimepicker as "dd-MM-yyyy" format

I'm trying to filter data from datagirdview by using 2 datetimepicker. Everything goes well when I call a query at SQL server, but when I try to call the same query at c# winform app. I get this error "Conversion failed when converting date and/or time from chracter string."
Here is my sql query for test purposes:
select*from order where CONVERT(datetime, orderDate, 105) between convert(datetime,'01.07.2021',105) and CONVERT(datetime,'15.12.2021',105)
Everything works fine here
Here is my c# filtering code:
private void button23_click(object sender, EventArgs e)
{
try
{
using (SqlConnection con = new SqlConnection(UygulamaAyarlari.ConnectionString()))
{
Datepicker1.Format = DateTimePickerFormat.Custom;
Datepickler1.FormatCustom = "dd-MM-yyyy";
Datepicker2.Format = DateTimePickerFormat.Custom;
Datepicker2.FormatCustom = "dd-MM-yyyy";
MessageBox.Show(bunifuDatepicker1.Value.ToString());
SqlDataAdapter sdf = new SqlDataAdapter("select* from order Where CONVERT(datetime, orderDate, 105) between convert(datetime,'" + bunifuDatepicker1.Value.ToString()+ "',1905) and convert(datetime,'" + bunifuDatepicker2.ToString() + "',1905)", con);
DataTable sd = new DataTable();
sdf.Fill(sd);
DatagridView1.DataSource = sd;
}
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
Can somebody help me?
Name your controls after you drop them on a form. For you to even have a button handler called button23_Click, implying you have a UI with at least 23 buttons named only numerically, is crazy
Your database orderDate should be a datetime2 column. Let's assume you make it a datetime2(3)
Your code should then look like this:
//button name and click handler name updated
private void GetOrdersCreatedBetweenButton_click(object sender, EventArgs e)
{
try
{
using (SqlConnection con = new SqlConnection(UygulamaAyarlari.ConnectionString()))
{
SqlDataAdapter sdf = new SqlDataAdapter("select * from order Where orderDate between #f and #t", con);
sdf.SelectCommand.Parameters.Add(new SqlParameter("#f", SqlDbType.DateTime2) { Scale = 3, Value = Datepicker1.Value });
sdf.SelectCommand.Parameters.Add(new SqlParameter("#t", SqlDbType.DateTime2) { Scale = 3, Value = Datepicker2.Value });
DataTable sd = new DataTable();
sdf.Fill(sd);
DatagridView1.DataSource = sd;
}
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
If you make orderDate a datetime, or a datetime2 with a different scale (number of milliseconds precision) adjust the Scale = x in the parameters accordingly

Call MySql stored procedure which take 2 parameters from asp.net core 2.2 web API controller

What is a proper way of calling a stored procedure with 2 parameters and getting result back which contain 10 columns and 403 records.
Below is the code I have written.
try
{
string startDate = procedureResource.StartDate.ToString("yyyy-MM-dd") + " 00:00:00";
string endDate = procedureResource.EndDate.ToString("yyyy-MM-dd") + " 23:59:59";
var FromDate = new MySqlParameter("#FromDate", startDate);
var ToDate = new MySqlParameter("#ToDate", endDate);
var financial = context.Query<FinancialResource>().FromSql("EXECUTE GetChargesFromToDate #FromDate,#ToDate", FromDate, ToDate).ToList();
return financial;
}
catch(Exception ex) { Console.Write(ex);throw ex; }
and here is the exception
{"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 ''2019-09-28 00:00:00','2019-10-04 23:59:59'' at line 1"}
Try declaring the startDate and endDate variables as DateTime instead of string. You might be sending a date\time format not acceptable by your SQL provider.
You could try something like this (i assume that procedureResource.StartDate/EndDate are of DateTime types):
DatetTime startDate = procedureResource.StartDate.Date;
DateTime endDate = procedureResource.EndDate.Date.Add (new TimeSpan (23, 59, 59));
change EXECUTE to CALL in query
`try
{
var fromDate = resource.StartDate.ToString("yyyy-MM-dd") + " 00:00:00";
var toDate = resource.EndDate.ToString("yyyy-MM-dd") + " 23:59:59";
string connectionstring = "Server=dbwithriderinstance.crefat3b9j9c.ap-southeast-1.rds.amazonaws.com;Database=dborderstage;User=stagging_su_production_s;Password=85s2!892Stfe7";
using (MySqlConnection con = new MySqlConnection(connectionstring))
{
using (MySqlCommand cmd = new MySqlCommand("GetChargesFromToDateV2", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#FromDate", fromDate);
cmd.Parameters.AddWithValue("#ToDate", toDate);
using (MySqlDataAdapter dbr = new MySqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
dbr.Fill(dt);
return dt;
}
}
}
}
catch (Exception ex) { Console.Write(ex); throw ex; }
}`

2 DataGridViews with same result?

need some help with a simple code
This is for Visual Studio c# Win Forms
dgvScad.DataSource =
dataProvider.getAttestatiByScad(DateTime.Today.AddDays(dayScad),
DateTime.Today);
dgvProve.DataSource =
dataProvider.getAziendaliByScad(DateTime.Today.AddDays(dayScad),
DateTime.Today);
a
public DataTable getAttestatiByScad(DateTime scadenza1, DateTime scadenza2)
{
string sql = "SELECT CONCAT(Dipendenti.cognome, ' ', Dipendenti.nome) AS Nome, Attestati.nome AS Attestato, AssAttestati.scadenza AS Scadenza " +
" FROM Attestati INNER JOIN(AssAttestati INNER JOIN Dipendenti" +
" ON AssAttestati.matricola=Dipendenti.matricola) " +
" ON Attestati.ID=AssAttestati.attestato " +
" WHERE AssAttestati.scadenza<=#scadenza1 AND AssAttestati.scadenza>=#scadenza2;";
DataTable dt = db.EseguiQueryWithParams
(
sql,
new SqlParameter("#scadenza1", scadenza1),
new SqlParameter("#scadenza2", scadenza2)
);
return dt;
}
public DataTable getAziendaliByScad(DateTime scadenza1, DateTime scadenza2)
{
string sql = "SELECT Aziendali.nome, Aziendali.scadenza FROM Aziendali WHERE Aziendali.scadenza<=#scadenza1 AND Aziendali.scadenza>=#scadenza2";
DataTable dt = db.EseguiQueryWithParams
(
sql,
new SqlParameter("#scadenza1", scadenza1),
new SqlParameter("#scadenza2", scadenza2)
);
return dt;
}
public DataTable EseguiQueryWithParams(string sql, params SqlParameter[] parameters)
{
apriConnessione();
string nometab = "dump";
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddRange(parameters);
try
{
adp = new SqlDataAdapter(cmd);
if (dset.Tables[nometab] != null)
dset.Tables[nometab].Clear();
adp.Fill(dset, nometab);
DataTable d = dset.Tables[nometab];
//d.Columns;
return d;
}
catch (Exception e)
{
throw e;
//throw new System.Exception("Errore nella lettura della tabella");
}
finally
{
adp.Dispose();
cmd.Dispose();
ChiudiConnessione();
}
}
I excpect the output to be different results, but all I see its the same for one DataGridView and the other DataGridView.
Hope you understand what I wronte I'm not so good in English.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.?

How to get values from table valued function in C#

I have a program where i have to display
The Event Description (OpisDogodka)
Location (Lokacija)
Time (ura)
My table valued function:
[dbo].[DobiDogodek](
#Ime nvarchar(100), #Datum date)
RETURNS TABLE AS RETURN (SELECT OpisDogodka AS 'Opisdogodka',Lokacija, Ura FROM Dogodek WHERE Ime=#Ime AND Datum=#Datum)
My method to connect to the server:
public string Dobi_dogodek(string ime,string datum)
{
string a="";
cmd = new SqlCommand("SELECT * FROM dbo.DobiDogodek(#Ime,#Datum)",povezava); //povezava = connectio and it succeeds to connect to the server.
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Ime", ime);
cmd.Parameters.AddWithValue("#Datum", datum); //how to pass date only?
try
{
SqlDataReader Reader = cmd.ExecuteReader();
while(Reader.Read())
{
a = Reader.GetString(0)+" "+Reader.GetString(1)+" "+Reader.GetString(3).ToString(); // get what?
}
Uspeh = true;
}
catch (Exception e)
{
ex = e;
}
finally
{
povezava.Close();
}
return a;
}
I tried also using Datatable and datarow. I am also unsure how to work with Date. I know how to work with DateTime, but I need Date and Time separate. What I am doing wrong?
4.6.2017 (11.40 am CET)Update:
It seems I get the desired result
public List<string> Dobi_dogodek(string ime,string datum)
{
s = new List<string>();
cmd = new SqlCommand("SELECT * FROM dbo.DobiDogodek(#Ime,#Datum)",povezava);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Ime", ime);
cmd.Parameters.AddWithValue("#Datum", Convert.ToDateTime(datum));
dt = new DataTable();
da = new SqlDataAdapter(cmd);
da.Fill(dt);
try
{
foreach (DataRow dr in dt.Rows)
{
s.Add(dr["Opis dogodka"].ToString() + "\\" + dr["Lokacija"].ToString() + "\\" + dr["Ura"].ToString());
}
Uspeh = true;
}
catch (Exception e)
{
ex = e;
}
finally
{
povezava.Close();
}
return s;
}
Now I just need to split the strings according to my requirements, but is the a better (not necessarily an easy) way?
Try this:
cmd.Parameters.AddWithValue("#Datum", Convert.ToDateTime(datum));
See also https://msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx .
what is happening when you run it? are you getting an error message? is it getting it as an int? did you see what the sql server is getting from application by using sql profiler?
I will double check but I think your problem is you are not putting quotes around your variables in our statement so when it runs it is evaluating them as ints. try "SELECT * FROM dbo.DobiDogodek('#Ime','#Datum')". It been a long time since I havnt used something like EF...

C# ASP.Net Processing Issue - Reading Table While Deleting Rows

Simply, I have an application that has one page that deletes and then re-adds/refreshes the records into a table every 30 seconds. I have another page that runs every 45 seconds that reads the table data and builds a chart.
The problem is, in the read/view page, every once in a while I get a 0 value (from a max count) and the chart shows nothing. I have a feeling that this is happening because the read is being done at the exact same time the delete page has deleted all the records in the table but has not yet refreshed/re-added them.
Is there a way in my application I can hold off on the read when the table is being refreshed?
Best Regards,
Andy
C#
ASP.Net 4.5
SQL Server 2012
My code below is run in an ASP.Net 4.5 built Windows service. It deletes all records in the ActualPlot table and then refreshes/adds new records from a text file every 30 seconds. I basically need to block (lock?) any user from reading the ActualPlot table while the records are being deleted and refreshed. Can you PLEASE help me change my code to do this?
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
// Open the SAP text files, clear the data in the tables and repopulate the new SAP data into the tables.
var cnnString = ConfigurationManager.ConnectionStrings["TaktBoardsConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(cnnString);
SqlConnection conndetail = new SqlConnection(cnnString);
SqlConnection connEdit = new SqlConnection(cnnString);
SqlCommand cmdGetProductFile = new SqlCommand();
SqlDataReader reader;
string sql;
// Delete all the records from the ActualPlot and the ActualPlotPreload tables. We are going to repopulate them with the data from the text file.
sql = "DELETE FROM ActualPlotPreload";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Delete Error:";
msg += ex.Message;
Library.WriteErrorLog(msg);
}
finally
{
conn.Close();
}
sql = "DELETE FROM ActualPlot";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Delete Error:";
msg += ex.Message;
Library.WriteErrorLog(msg);
}
finally
{
conn.Close();
}
// Read the SAP text file and load the data into the ActualPlotPreload table
sql = "SELECT DISTINCT [BoardName], [ProductFile], [ProductFileIdent] FROM [TaktBoards].[dbo].[TaktBoard] ";
sql = sql + "JOIN [TaktBoards].[dbo].[Product] ON [Product].[ProductID] = [TaktBoard].[ProductID]";
cmdGetProductFile.CommandText = sql;
cmdGetProductFile.CommandType = CommandType.Text;
cmdGetProductFile.Connection = conn;
conn.Open();
reader = cmdGetProductFile.ExecuteReader();
string DBProductFile = "";
string DBTischID = "";
string filepath = "";
string[] cellvalues;
DateTime dt, DateCheckNotMidnightShift;
DateTime ldSAPFileLastMod = DateTime.Now;
string MyDateString;
int FileRecordCount = 1;
while (reader.Read())
{
DBProductFile = (string)reader["ProductFile"];
DBTischID = (string)reader["ProductFileIdent"];
filepath = "c:\\inetpub\\wwwroot\\WebApps\\TaktBoard\\FilesFromSAP\\" + DBProductFile;
FileInfo fileInfo = new FileInfo(filepath); // Open file
ldSAPFileLastMod = fileInfo.LastWriteTime; // Get last time modified
try
{
StreamReader sr = new StreamReader(filepath);
FileRecordCount = 1;
// Populate the AcutalPlotPreload table from with the dates from the SAP text file.
sql = "INSERT into ActualPlotPreload (ActualDate, TischID) values (#ActualDate, #TischID)";
while (!sr.EndOfStream)
{
cellvalues = sr.ReadLine().Split(';');
if (FileRecordCount > 1 & cellvalues[7] != "")
{
MyDateString = cellvalues[7];
DateTime ldDateCheck = DateTime.ParseExact(MyDateString, "M/dd/yyyy", null);
DateTime dateNow = DateTime.Now;
string lsDateString = dateNow.Month + "/" + dateNow.Day.ToString("d2") + "/" + dateNow.Year;
DateTime ldCurrentDate = DateTime.ParseExact(lsDateString, "M/dd/yyyy", null);
string lsTischID = cellvalues[119];
if (ldDateCheck == ldCurrentDate)
{
try
{
conndetail.Open();
SqlCommand cmd = new SqlCommand(sql, conndetail);
cmd.Parameters.Add("#ActualDate", SqlDbType.DateTime);
cmd.Parameters.Add("#TischID", SqlDbType.VarChar);
cmd.Parameters["#TischID"].Value = cellvalues[119];
MyDateString = cellvalues[7] + " " + cellvalues[55];
dt = DateTime.ParseExact(MyDateString, "M/dd/yyyy H:mm:ss", null);
cmd.Parameters["#ActualDate"].Value = dt;
// Ignore any midnight shift (12am to 3/4am) units built.
DateCheckNotMidnightShift = DateTime.ParseExact(cellvalues[7] + " 6:00:00", "M/dd/yyyy H:mm:ss", null);
if (dt >= DateCheckNotMidnightShift)
{
cmd.ExecuteNonQuery();
}
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert Error:";
msg += ex.Message;
Library.WriteErrorLog(msg);
}
finally
{
conndetail.Close();
}
}
}
FileRecordCount++;
}
sr.Close();
}
catch
{ }
finally
{ }
}
conn.Close();
// Get the unique TischID's and ActualDate from the ActualPlotPreload table. Then loop through each one, adding the ActualUnits
// AcutalDate and TischID to the ActualPlot table. For each unique TischID we make sure that we reset the liTargetUnits to 1 and
// count up as we insert.
SqlCommand cmdGetTischID = new SqlCommand();
SqlDataReader readerTischID;
int liTargetUnits = 0;
string sqlInsert = "INSERT into ActualPlot (ActualUnits, ActualDate, TischID) values (#ActualUnits, #ActualDate, #TischID)";
sql = "SELECT DISTINCT [ActualDate], [TischID] FROM [TaktBoards].[dbo].[ActualPlotPreload] ORDER BY [TischID], [ActualDate] ASC ";
cmdGetTischID.CommandText = sql;
cmdGetTischID.CommandType = CommandType.Text;
cmdGetTischID.Connection = conn;
conn.Open();
readerTischID = cmdGetTischID.ExecuteReader();
DBTischID = "";
DateTime DBActualDate;
string DBTischIDInitial = "";
while (readerTischID.Read())
{
DBTischID = (string)readerTischID["TischID"];
DBActualDate = (DateTime)readerTischID["ActualDate"];
if (DBTischIDInitial != DBTischID)
{
liTargetUnits = 1;
DBTischIDInitial = DBTischID;
}
else
{
liTargetUnits++;
}
try
{
conndetail.Open();
SqlCommand cmd = new SqlCommand(sqlInsert, conndetail);
cmd.Parameters.Add("#ActualUnits", SqlDbType.Real);
cmd.Parameters.Add("#ActualDate", SqlDbType.DateTime);
cmd.Parameters.Add("#TischID", SqlDbType.VarChar);
cmd.Parameters["#TischID"].Value = DBTischID;
cmd.Parameters["#ActualDate"].Value = DBActualDate;
cmd.Parameters["#ActualUnits"].Value = liTargetUnits;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert Error:";
msg += ex.Message;
Library.WriteErrorLog(msg);
}
finally
{
conndetail.Close();
}
}
conn.Close();
Library.WriteErrorLog("SAP text file data has been imported.");
}
If the data is being re-added right back after the delete (basically you know what to re-add before emptying the table), you could have both operation within the same SQL transaction, so that the data will be available to the other page only when it has been re-added.
I mean something like that :
public bool DeleteAndAddData(string connString)
{
using (OleDbConnection conn = new OleDbConnection(connString))
{
OleDbTransaction tran = null;
try
{
conn.Open();
tran = conn.BeginTransaction();
OleDbCommand deleteComm = new OleDbCommand("DELETE FROM Table", conn);
deleteComm.ExecuteNonQuery();
OleDbCommand reAddComm = new OleDbCommand("INSERT INTO Table VALUES(1, 'blabla', 'etc.'", conn);
reAddComm.ExecuteNonQuery();
tran.Commit();
}
catch (Exception ex)
{
tran.Rollback();
return false;
}
}
return true;
}
If your queries don't take too long to execute, you can start the two with a difference of 7.5 seconds, as there is a collision at every 90 seconds when the read/write finishes 3 cycles, and read/view finishes 2 cycles.
That being said, it's not a fool-proof solution, just a trick based on assumptions, in case you wan't to be completely sure that read/view never happens when read/write cycle is happening, try considering having a Read Lock. I would recommend reading Understanding how SQL Server executes a query and Locking in the Database Engine
Hope that helps.
I would try a couple of things:
Make sure your DELETE + INSERT operation is occurring within a single transaction:
BEGIN TRAN
DELETE FROM ...
INSERT INTO ...
COMMIT
If this isn't a busy table, try locking hints your SELECT statement. For example:
SELECT ...
FROM Table
WITH (UPDLOCK, HOLDLOCK)
In the case where the update transactions starts while your SELECT statement is running, this will cause that transaction to wait until the SELECT is finished. Unfortunately it will block other SELECT statements too, but you don't risk reading dirty data.
I was not able to figure this out but I changed my code so the program was not deleting all the rows in the ActualPlot table but checking to see if the row was there and if not adding the new row from the text file.

Categories