C# Core, OracleDataReader with hasRows as false while select all rows in a table that has data - oracle

I am testing Oracle database. I wrote some code but my datareader has no rows, why? My "carros" table has data and I am selecting all of them but I am getting an empty result set it seems.
string constr = "Data Source=localhost:1521/XE;User Id=System;Password=password;";
OracleConnection con = new OracleConnection(constr);
OracleCommand oracleCommand = new OracleCommand();
oracleCommand.Connection = con;
oracleCommand.CommandText = "select preco from carro";
con.Open();
OracleDataReader oracleDataReader = oracleCommand.ExecuteReader();
string resultado = String.Empty;
//My test, I got hasRows as false
if (oracleDataReader.HasRows == false)
{
resultado = "no results";
}
//never enters this loop.
while (oracleDataReader.Read())
{
resultado += (string)oracleDataReader["preco"];
}
// Close and Dispose OracleConnection
con.Close();
con.Dispose();
return resultado;

If HasRows is false after ExecuteReader, the problem is simply that the query is returning no rows so Read will return false as well. Perhaps the someValue variable is not set correctly.
From you description, it seems that your table is named carros while your query has used carro. Try to use
oracleCommand.CommandText = "select preco from carros";

A path towards solving this can include a scattering of logging commands that write to the file system.
System.IO.File.AppendAllText(#"\\server\\C\\log.txt", "put error message here" + "\r\n");
Or for printing a variable:
System.IO.File.AppendAllText(#"\\server\\C\\log.txt", ex.ToString() + "\r\n");
Pepper variations of this command throughout your script to see where failures are happening and to validate variable values.

Related

Wrong number or types of arguments when calling a procedure in WCF service

I'm sort of having a hard time with this one. Well ok, I have two different solutions (solution1 has a WebApplication Project; solution2 has a Website Project). Inside the two solutions, there's a WCF service structure. I have the exact same code in both services (in their respective solutions). My code compiles just fine. From the service I do a simple call to a procedure that returns a cursor. When I execute the service from the WebApplication it works just fine; when I do the same from the Website I get error: "wrong number or types of arguments". They both call the same procedure, in the same DB. And I triple check my code, and is the same in both services. Any ideas or suggestions? My code is as follows in both solutions:
Service.cs
public List<A1001310> SearchClient_A1001310()
{
DataTable dataTable = new DataTable();
dataTable = DataManager.SearchClient();
List<A1001310> list = new List<A1001310>();
list = (from DataRow dr in dataTable.Rows
select new A1001310()
{
Id = Convert.ToInt32(dr["CLIENT_ID"]),
//ClientName = dr["NOM_CLIENTE"].ToString()
}).ToList();
return list;
}
DataManager.cs
public static DataTable SearchClient()
{
try
{
using (OleDbCommand cmd = new OleDbCommand(packetName + ".select_A1001310"))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlManager sqlManager = new SqlManager();
return sqlManager.GetDataTable(cmd);
}
}
catch (Exception ex)
{
//TODO; Handle exception
}
return null;
}
The call to DataTable is:
public DataTable GetDataTable(OleDbCommand cmd)
{
using (DataSet ds = GetDataSet(cmd))
{
return ((ds != null && ds.Tables.Count > 0) ? ds.Tables[0] : null);
}
}
public DataSet GetDataSet(OleDbCommand cmd)
{
using (DataSet ds = new DataSet())
{
this.ConvertToNullBlankParameters(cmd);
using (OleDbConnection conn = new OleDbConnection(cmd.Connection == null ? _dbConnection : cmd.Connection.ConnectionString))
{
cmd.Connection = conn;
cmd.CommandTimeout = _connTimeout;
conn.Open();
//cmd.ExecuteScalar();
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
da.Fill(ds);
}
return ds;
}
}
The procedure is as follow:
PROCEDURE select_A1001310(io_cursor OUT lcursor_data)
AS
BEGIN
OPEN io_cursor FOR
--
SELECT client_id
FROM a1001310
WHERE status = 'A'
--
EXCEPTION
WHEN OTHERS THEN
IF io_cursor%ISOPEN THEN
CLOSE io_cursor;
END IF;
--REVIRE: EXCEPTION HANDLER
END select_A1001310;
So if it helps anyone, I resolved my issue by specifying the OUT parameter declared in the procedure. This resulted in me changing from Oledb to OracleClient as follow:
public static DataTable SearchClient()
{
string connection = ConfigurationManager.ConnectionStrings["DBConnection_Oracle"].ToString();
string procedure = packetName + ".p_search_client";
OracleParameter[] parameters = new OracleParameter[1];
parameters[0] = new OracleParameter("io_cursor", OracleType.Cursor, 4000, ParameterDirection.Output, true, 0, 0, "", DataRowVersion.Current, String.Empty);
DataTable dt = new DataTable();
dt = DataManager_Oracle.GetDataTable_(connection, procedure, parameters);
return dt;
}
It seems that on the Website environment it didn't like leaving out the OUT parameter; whereas on the WebApplication I did not specify it, and it worked just fine... If some one know the why , PLEASE let me know :)

Permission to enable certain fields depends on CurrentUserID Epicor ERP10

I need help. I need to enable certain fields depends on CurrentUserID. There is one field which is UltraCombo contains of Employee's name. When the Employee's Name is selected, the other fields should be enabled if the CurrentUserID is matched with the selected Employee's name. Otherwise, the other fields should be locked. I tried to use the CanView method in the code but I don't know how to call in SQL command. Plese help me T-T
private bool CanView(string field)
{
bool result = true;
EpiDataView edv = oTrans.EpiDataViews["CallContextClientData"] as EpiDataView;
string CurrentUser = edv.dataView[edv.Row]["CurrentUserId"].ToString();
string ConnectionString = "Data Source=RWNAERP;Initial Catalog=ERP10TESTRWNA;Persist Security Info=True;User ID=sa;Password=Epicor10";
string CompanyId = ((Ice.Core.Session)(oTrans.Session)).CompanyID;
string UserID = ((Ice.Core.Session)(oTrans.Session)).UserID;
using (SqlConnection connection1 = new SqlConnection(ConnectionString))
{
DataTable dt = new DataTable();
connection1.Open();
SqlCommand cmd = new SqlCommand("SELECT DcdUserID FROM dbo.UserFile WHERE Name=#Name AND EmpID=#EmpID", connection1);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("DcdUserID", SqlDbType.NVarChar).Value = UserID;
SqlDataAdapter sqlDa = new SqlDataAdapter(cmd);
sqlDa.Fill(dt);
if (dt.Rows.Count > 0)
{
result = false;
}
if (CurrentUser != "")
{
result = true;
}
connection1.Close();
connection1.Dispose();
}
What you are trying to do is on the client, but the client only connects to the AppServer and never to the SQL Database. Only the AppServer should connect to the database.
Assuming you are adding this code as a customisation script, it's much easier to get the current user info from the Session variable i.e.
var session = (Ice.Core.Session)oTrans.Session;
var userId = session.UserID;
var userName = session.UserName;
var userEmail = session.UserEmail;
In the Epicor.exe client disabling fields is best done with a RowRule, i.e.
var callContextClientData = oTrans.Factory("CallContextClientData");
var disableFieldsForUser = new RowRule("CurrentUserId", RuleCondition.Equals, ((Ice.Core.Session)trans.Session).UserID);
disableFieldsForUser.AddAction(RuleAction.AddControlSettings(stockDtlEpiDataView, "CallContextClientData.ShortChar01", SettingStyle.Disabled));
callContextClientData.AddRowRule(disableFieldsForUser);
It's not clear which fields you are matching or which you want to disable, but hopefully this should get you started.

how to execute multiple oracle query c#

i am trying to execute multiple oracle select query as explain at that post answer here but I am getting exception as show at image
the same way explained at oracle site here
btw is ther anyway to handle the no rows found from one of these queries ?
string cmdstr = #"begin open :1 for
SELECT a.column1,
a.olumn2
b.column3
FROM table1 A,table2 B
WHERE A.column1=B.column1
AND A.column2 = NVL(:P_para, 0)
AND B.column3='1';
open :2 for select column1,
column2,
column3,
From dual; end;";
using (OracleConnection conn = new OracleConnection(connstr))
using (OracleCommand cmd = new OracleCommand(cmdstr, conn))
{
try
{
cmd.Parameters.Add(new OracleParameter(":P_para", OracleDbType.Int64)).Value = Convert.ToInt64(Textbox.Text);
cmd.Parameters.Add("p_cr1", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
cmd.Parameters.Add("p_cr2", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
cmd.CommandText = cmdstr;
conn.Open();
OracleTransaction trans = conn.BeginTransaction();
OracleDataReader oraReder;
oraReder = cmd.ExecuteReader();
while (oraReder.Read())
{
textbox1.Text = oraReder.GetString(0).ToString();
textbox2.Text = oraReder.GetValue(1).ToString();
textbox3.Text = oraReder.GetValue(2).ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Erorr Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Although you're using names for your parameters, your driver is treating them positionally. You can kind of tell because it's (almost) matching :1 with the name p_cr1 - '1' isn't a valid name. It doesn't complain since it matches positionally - but that means it's trying to use the P_para for :1, and as the type of that is wrong, that explains the error you see.
There may well be a way to change the driver's behaviour, but for now you can just swap the order you bind them - so the binds occur in the same order (position) the variables appear in the query. So:
cmd.Parameters.Add("p_cr1", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
cmd.Parameters.Add(new OracleParameter(":P_para", OracleDbType.Int64)).Value = Convert.ToInt64(Textbox.Text);
cmd.Parameters.Add("p_cr2", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);

ORA-01840: input value not long enough for date format when executing a query with a timestamp parameter

I am trying to execute a query on Oracle database table with a TimeStamp(6) column, using odp.net
I am using below code, which throws this exception: "ORA-01840: input value not long enough for date format".
OracleConnection con = new OracleConnection(connStr");
using (con)
{
con.Open();
OracleCommand command = con.CreateCommand();
command.CommandText = "SELECT * FROM Logs WHERE LOGDATE > :logDate";
command.CommandType = System.Data.CommandType.Text;
command.Parameters.Add(new OracleParameter("logDate", OracleDbType.TimeStamp, DateTime.Now.AddMonths(-1), ParameterDirection.Input));
using (command)
{
OracleDataReader rdr = command.ExecuteReader(); //ORA-01840 exception is thrown here
}
}
What is wrong about this query and it's parameters? I also tried OracleDbType.Date, instead of OracleDbType.TimeStamp but i got the same error.
I solved the problem by passing an OracleTimeStamp object instead of DateTime object. Below code works good:
OracleConnection con = new OracleConnection(connStr");
using (con)
{
con.Open();
OracleCommand command = con.CreateCommand();
command.CommandText = "SELECT * FROM Logs WHERE LOGDATE > :logDate";
command.CommandType = System.Data.CommandType.Text;
command.Parameters.Add(new OracleParameter("logDate", OracleDbType.TimeStamp, new OracleTimeStamp(DateTime.Now.AddMonths(-1)), ParameterDirection.Input));
using (command)
{
OracleDataReader rdr = command.ExecuteReader(); //ORA-01840 exception was thrown here
}
}

Problem with cmd.ExecuteNonQuery()

I am inserting values in to Database from a Webform using ADO.NET, C#. DB I am using is Oracle Database. Values are not being inserted and the program gets struck at the cmd.ExecuteNonquery()
Here is my Code below, Please let me know If I am doing any mistake.. I am using some Static Methods will that be any problem ?..
public Boolean AddDivCo(Int32 UserNo,String ID, String Role, String DivName )
{
Boolean ret = false;
OracleCommand cmd = new OracleCommand();
OracleConnection conn = new OracleConnection();
int i = 0;
try
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["Conn_RIS"].ConnectionString;
conn.Open();
cmd.Connection = conn;
String mySQL = "INSERT INTO R4CAD_ADMIN (AdminUserNo, AdminID, AdminRole, AdminDivName)VALUES(:AdminUserNo,:AdminID,:AdminRole,:DivName)";
OracleParameter p1 = new OracleParameter("AdminUserNo", OracleType.Number);
p1.Value = UserNo;
cmd.Parameters.Add(p1);
OracleParameter p2 = new OracleParameter("AdminID", OracleType.VarChar);
p2.Value = ID;
cmd.Parameters.Add(p2);
OracleParameter p3 = new OracleParameter("AdminRole", OracleType.VarChar);
p3.Value = Role;
cmd.Parameters.Add(p3);
OracleParameter p4 = new OracleParameter("DivName", OracleType.VarChar);
p4.Value = DivName;
cmd.Parameters.Add(p4);
cmd.CommandText = mySQL;
i = cmd.ExecuteNonQuery();
if (i != 0)
{
ret = true;
}
else
{
ret = false;
}
}
catch (Exception err)
{
Console.WriteLine(err.Message.ToString());
}
finally
{
cmd.Dispose();
//cmd = null;
//conn = null;
conn.Close();
}
return ret;
}
Is there a primary key defined on this table? If so, then my guess is that you have another session that already has inserted a record with this key, but has not yet terminated the transaction with a commit or rollback. I don't see a commit as part of your code - I assume you're doing that somewhere else?
Execute your code above once more, and while it's hung run the following query from another session:
SELECT
(SELECT username FROM v$session WHERE sid=a.sid) blocker,
a.sid,
' is blocking ',
(SELECT username FROM v$session WHERE sid=b.sid) blockee,
b.sid
FROM v$lock a JOIN v$lock b ON (a.id1 = b.id1 AND a.id2 = b.id2)
WHERE a.block = 1
AND b.request > 0;
This should tell you if you're being blocked by another session and what the SID is of that session.

Resources