I have two radio boxes. One true, the other false. I have a flag set up,
but it didn't work. Here is my code right now
string sqlStatement;
SqlConnection cnn = new SqlConnection(Properties.Settings.Default.cnnString);
cnn.Open();
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandType = CommandType.Text;
sqlStatement = string.Format("UPDATE Results SET Finish = '{0}', Place = '{1}', FinishTime = {2}, Winnings = '{3}' Where ResultsId = '{4}' " + (rdoDidFinish.Checked ? 1 : 0), txtPlace.Text, txtTime.Text, txtWinnings.Text);
cmd.CommandText = sqlStatement;
cmd.ExecuteNonQuery();
cnn.Close();
The error I am getting is:
"Index (zero based) must be greater than or equal to zero and less than the size of the argument list."
I see a few problems here.
NEVER EVER build a SQL Statement by piecing together a string and values, doesn't matter if it is stringbuilder or string.format, or what not. This is language agnostic; DON'T do it in any language. For more information on the dangers, please Google "SQL Injection"
The best thing to do is use paramaterized queries. Sample will follow.
Your problem is actually in your string.Format line. There are 2 errors here
Error 1: I believe the + should be a , here: '{4}' " + (rdoDidFinish.Checked ? 1 : 0)
Error 2 You have 5 placeholders, and only 3 values. 4 if the above (Err 1) statement is corrected
Here is a simple mock up assuming Err 1 fixed.. Need to know what the ResultID value is.
string sqlStatement = "UPDATE Results SET Finish = #Finish, Place = #Place, FinishTime = #FinishTime, Winnings = #Winnings WHERE ResultsId = #ResultID";
using (SqlConnection cnn = new SqlConnection(Properties.Settings.Default.cnnString)) {
SqlCommand cmd = cnn.CreateCommand(sqlStatement, cnn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Finish", (rdoDidFinish.Checked ? 1 : 0)); // I think this belongs here.
cmd.Parameters.AddWithValue("#Place", txtPlace.Text);
cmd.Parameters.AddWithValue("#FinishTime", txtTime.Text);
cmd.Parameters.AddWithValue("#Winnings", txtWinnings.Text);
// cmd.Parameters.AddWithValue("#ResultID", ); ? What belongs here ?
cnn.Open();
cmd.ExecuteNonQuery();
cnn.Close();
}
Please use parameters in a prepared statement!
Example:
var myParam = new SqlParameter();
myParam.ParameterName = "#myParam";
myParam.Value = 1;
comm.Parameters.Add(myParam);
You can use the parameter in your SQL-Statement like
Select * from table where abc = #myparam
Your Where ResultsId = '{4}' does not currently have any values being inserted into it.
Add another parameter after txtWinnings.txt providing the ResultsId and replace the + with a , before (rdoDidFinish.Checked ? 1 : 0) so that it is recognized as its own parameter.
The correct statement should look something like this, where resultId is whatever id you want to search for:
sqlStatement = string.Format("UPDATE Results SET Finish = '{0}', Place = '{1}', FinishTime = {2}, Winnings = '{3}' Where ResultsId = '{4}' ", (rdoDidFinish.Checked ? 1 : 0), txtPlace.Text, txtTime.Text, txtWinnings.Text, resultId);
One final note, in line with the comments on your question, you should always prepare your parameters. So your final result should be something along the lines of:
cmd.CommandText = #"UPDATE Results SET Finish = #finished, Place = #place, FinishTime = #time, Winnings = #winnings Where ResultsId = #resultId ";
cmd.Parameters.Add(new SqlParameter("#finished", System.Data.SqlDbType.Bit).Value = rdoDidFinish.Checked);
cmd.Parameters.Add(new SqlParameter("#place", System.Data.SqlDbType.VarChar).Value = txtPlace.Text);
cmd.Parameters.Add(new SqlParameter("#time", System.Data.SqlDbType.VarChar).Value = txtTime.Text);
cmd.Parameters.Add(new SqlParameter("#winnings", System.Data.SqlDbType.VarChar).Value = txtWinnings.Text);
cmd.Parameters.Add(new SqlParameter("#resultId", System.Data.SqlDbType.Int).Value = resultId);
Related
string s = "select idviagem from tbviagem where dia like '" + idatxt.Text + "'";
cmd = new SqlCommand(s, con);
I need the idviagem from the table tbviagem to put in idviagem from tbpassageiro (it's FK on tbpassageiro) , but i need the get idviagem from idatxt.Text it's a DateTime format, but doing the insert (look down) gives me the error:
Conversion failed when converting the nvarchar value 'select idviagem from tbviagem where dia like '06/12/2018 00:00:00'' to data type int.'
but idviagem is a int, of course .
string q = "insert into tbpassageiro (nome,cc,fotocc,idviagem) values(#n,#cc,#p,#iv)";
cmd = new SqlCommand(q, con);
con.Open();
cmd.Parameters.AddWithValue("#p", data);
cmd.Parameters.AddWithValue("#n", nometxt.Text);
cmd.Parameters.AddWithValue("#cc", cctxt.Text);
cmd.Parameters.AddWithValue("#iv", s);
cmd.ExecuteNonQuery();
You should never execute SQL statements like that but use parameters. You are using parameters for your second statement but not doing it for the first one.
Having said that, you are trying to use the query string s as the parameter value for #iv. Instead you should ExecuteScalar in first and use the result of it in second.
However, you can both get the idviagem value and do the insert in one single statement like this:
string q = #"insert into tbpassageiro
(nome,cc,fotocc,idviagem)
select #n,#cc,#p,idViagem from tbviagem where dia like #dia";
SqlCommand cmd = new SqlCommand(q, con);
cmd.Parameters.AddWithValue("#p", data);
cmd.Parameters.AddWithValue("#n", nometxt.Text);
cmd.Parameters.AddWithValue("#cc", cctxt.Text);
cmd.Parameters.Add("#dia", SqlDbType.VarChar).Value = idatxt.Text;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Note: I don't suggest using AddWithValue, prefer Add instead.
EDIT: For sampling with a Datetime dia field:
DateTime dt;
cmd.Parameters.Add("#dia", SqlDbType.DateTime);
if (DateTime.TryParse(idatxt.Text, out dt))
{
cmd.Parameters["#dia"].Value = dt;
}
else
{
cmd.Parameters["#dia"].Value = DBNull.Value;
}
If idatxt is for getting a date\datetime value it would be much easier to use DateTimePicker to get a valid DateTime value.
It looks like you are passing the query string s as the parameter value for #iv instead of the result of that query.
I suggest executing your command cmd and passing the result value to #iv:
string s = "select idviagem from tbviagem where dia like '" + idatxt.Text + "'";
cmd = new SqlCommand(s, con);
con.Open();
Int32 resultValue = (Int32) cmd.ExecuteScalar();
string q = "insert into tbpassageiro (nome,cc,fotocc,idviagem) values(#n,#cc,#p,#iv)";
cmd = new SqlCommand(q, con);
cmd.Parameters.AddWithValue("#p", data);
cmd.Parameters.AddWithValue("#n", nometxt.Text);
cmd.Parameters.AddWithValue("#cc", cctxt.Text);
cmd.Parameters.AddWithValue("#iv", resultValue);
cmd.ExecuteNonQuery();
I have a program that has 11 variable that need to be inserted into a SQL 2008 Express DB. All works until the variables that can be NULL are NULL. Then the SQL does not get the data. Here is my code and appreciate all that can help:
private void PostDatatoServer()
{
String connectionString = #"Data Source=LUCKYTIGER\SQLEXPRESS;Initial Catalog=John;Integrated Security=True";
SqlConnection con = new SqlConnection(connectionString);
con.Open();
textBox1.Text = "Connection made";
SqlCommand cmd = con.CreateCommand();
string str = "";
str += "INSERT INTO Parsed(Date, Gal, Sys, Sl, ST, PN, PlayN, Sym, Rk, All, Rel)";
str += "VALUES(#Date, #Gal, #Sys, #Sl, #ST, #PN, #PlayN, #Sym, #Rk, #All, #Rel)";
SqlCommand cmd = new SqlCommand(str, con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("#Date", uegParser.strTime));
cmd.Parameters.Add(new SqlParameter("#Gal", Convert.ToInt16(uegParser.strGalaxyNum)));
cmd.Parameters.Add(new SqlParameter("#Sys", Convert.ToInt16(uegParser.strSystemNum)));
cmd.Parameters.Add(new SqlParameter("#Sl", uegParser.intSlot));
cmd.Parameters.Add(new SqlParameter("#ST", uegParser.intSlotType));
if (uegParser.strPlanetName == "")
cmd.Parameters.Add(new SqlParameter("#PN", SqlDbType.NVarChar).Value = DBNull.Value);
else
cmd.Parameters.Add(new SqlParameter("#PN", uegParser.strPlanetName));
if (uegParser.strPlayerName == "")
{
cmd.Parameters.Add(new SqlParameter("#PlayN", DBNull.Value));
TextBox2.Text = "Null player name";
}
else
{
cmd.Parameters.Add(new SqlParameter("#PlayN", uegParser.strPlayerName));
}
if (uegParser.strSymbols == "")
cmd.Parameters.Add(new SqlParameter("#Sys", DBNull.Value));
else
cmd.Parameters.Add(new SqlParameter("#Sym", uegParser.strSymbols));
if (uegParser.strRank == "")
cmd.Parameters.Add(new SqlParameter("#Rk", DBNull.Value));
else
cmd.Parameters.Add(new SqlParameter("#Rk", uegParser.strRank));
if (uegParser.strAlliance == "")
cmd.Parameters.Add(new SqlParameter("#All", DBNull.Value));
else
cmd.Parameters.Add(new SqlParameter("#All", uegParser.strAlliance));
cmd.Parameters.Add(new SqlParameter("#Rel", uegParser.intRelationship));
cmd.ExecuteNonQuery();
con.Close();
TextBox2.Text = "Connection closed";
}
The following is not an answer to your question but an example of all the places your code is abusing Ado.Net. Try to restructure any ado.net code you have in this manner. I do agree with the comments, your general approach is probably wrong however these are general pointers that you could probably benefit from in the rest of your code. Pointers are.
Always wrap SqlConnections in using blocks
Always use parameterized queries
Always specify the parameter SqlDbType (when using SqlServer obviously)
Always use the correct parameter types instead of adding string values
Refactored ado.net code
protected void btn_insert_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
// i would not use Session unless necessary but that is out of scope for the question
// also do not forget to dispose the datatabale when finished and remove it from the session
ds = (DataSet)Session["DTset"];
// always wrap your SqlConnection in a using block
// it ensures the connection is always released
// also there is no reason to have this inside the loop
// there is no reason to close/reopen it every time
using(SqlConnection con = new SqlConnection(connStr))
{
con.Open(); // open once
for (int i = 1; i < ds.Tables[0].Rows.Count; i++)
{
// do not convert everything to strings, pick the correct type as it is in the table or convert it to the correct type if the table contains only strings
string Id = ds.Tables[0].Rows[i][0].ToString();
string Name = ds.Tables[0].Rows[i][1].ToString();
cmd = new SqlCommand("insert into tbl1(ID,Name) values (#ID,#Name)";
cmd.Parameters.AddWithValue("#ID", Id).SqlDbType = SqlDbType.; // pick the correct dbtype
cmd.Parameters.AddWithValue("#Name", Name).SqlDbType = SqlDbType.; // pick the correct dbtype
int j= cmd.ExecuteNonQuery();
// do not convert everything to strings, pick the correct type as it is in the table or convert it to the correct type if the table contains only strings
string Id1 = ds.Tables[0].Rows[i][2].ToString();
string Name1 = ds.Tables[0].Rows[i][3].ToString();
string VehicleTypeId = ds.Tables[0].Rows[i][4].ToString();
string VehicleType = ds.Tables[0].Rows[i][5].ToString();
string Capacity = ds.Tables[0].Rows[i][6].ToString();
string InsQuery = "insert into tbl2(Id,Name,Subject,status,review) values (#Id,#Name,#Subject,#status,#review)";
cmd = new SqlCommand(InsQuery,con);
cmd.Parameters.AddWithValue("#id", Id1).SqlDbType = SqlDbType.; // pick the correct dbtype
cmd.Parameters.AddWithValue("#Name", name1).SqlDbType = SqlDbType.; // pick the correct dbtype
// add the rest of your parameters here
int k= cmd.ExecuteNonQuery();
}
}
}
You should reconsider how you read your data from spreadsheet. Apparently you put the whole sheet into one big DataTable and then iterate over this. You should split your datareading, such that you only read the first two columns into one DataTable and the remaining five columns into a second DataTable. Then iterate over the two DataTables separately and save the contained rows into database.
If you really just want to prohibit to create rows with null values, you could simply check your values for null before you do the insert.
if (!String.IsNullOrEmpty(Id) && !String.IsNullOrEmpty(Name)) {
cmd = new SqlCommand( ....);
cmd.ExecuteNonQuery();
}
Additionally some hints:
Take a look at parametrized and prepared queries, they make your code a lot more secure.
You do not need to open and close your sql connection for every single command. You can open it before your loop, create and execute some commands, and close it after the loop, when your are finished.
You are missing the first row of your data. The vast majority of collections in c# start at index 0.
EDIT
For your request, I added the null checks into your code. But I really don't think you should do it this way! Like I mentionioned above, you should split your datatable into two tables, such that each of them only contains the relevant rows. And you should have a look at Igor's answer on how to create parameterized queries! And take into account the other hints from above. And finally, I don't mean to be rude, but you really should grab a good book or some tutorials from the web and learn the basics, so you will be able to understand the anwswers to your question.
protected void btn_insert_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ds = (DataSet)Session["DTset"];
for (int i = 1; i < ds.Tables[0].Rows.Count; i++)
{
string Id = ds.Tables[0].Rows[i][0].ToString();
string Name = ds.Tables[0].Rows[i][1].ToString();
SqlConnection con = new SqlConnection(connStr);
SqlCommand cmd;
if (!string.IsNullOrEmpty(Id) && !string.IsNullOrEmpty(Name)) {
cmd = new SqlCommand("insert into tbl1(ID,Name) values ('" + Id + "','" + Name + "')", con);
con.Open();
int j= cmd.ExecuteNonQuery();
con.Close();
}
string Id1 = ds.Tables[0].Rows[i][2].ToString();
string Name1 = ds.Tables[0].Rows[i][3].ToString();
string VehicleTypeId = ds.Tables[0].Rows[i][4].ToString();
string VehicleType = ds.Tables[0].Rows[i][5].ToString();
string Capacity = ds.Tables[0].Rows[i][6].ToString();
if (!string.IsNullOrEmpty(Id1) && !string.IsNullOrEmpty(Name1) && !string.IsNullOrEmpty(VehicleTypeId) && !string.IsNullOrEmpty(VehicleType) && !string.IsNullOrEmpty(Capacity)) {
string InsQuery = "insert into tbl2(Id,Name,Subject,status,review) values ('" + Id1 + "','" + Name1 + "','" + Subject+ "','" + status+ "','" + review+ "')";
cmd = new SqlCommand(InsQuery,con);
con.Open();
int k= cmd.ExecuteNonQuery();
con.Close();
}
}
}
Fool-proof solution: use SQL Stored procedure.
--sql
create procedure dbo.Parsed_i
#Date datetime,
#Gal int,
--so on
#PN nvarchar(100) = null --default value
--so on
as
INSERT INTO Parsed(Date, Gal, Sys, Sl, ST, PN, PlayN, Sym, Rk, All, Rel)
VALUES(#Date, #Gal, #Sys, #Sl, #ST, #PN, #PlayN, #Sym, #Rk, #All, #Rel)
//C#
//...
SqlCommand cmd = new SqlCommand("dbo.Parsed_i", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ST", SqlDbType.Int).Value = uegParser.intSlotType;
if (!string.IsNullOrEmpty(uegParser.strPlanetName))
cmd.Parameters.Add("#PN", SqlDbType.NVarChar).Value = uegParser.strPlanetName;
//note: no **else** part
//so on
I am getting the exception "Must declare the scalar variable"#strAccountID"
string #straccountid = string.Empty;
sSQL =
"SELECT GUB.BTN,
GUP.CUST_USERNAME,
GUP.EMAIL
FROM GBS_USER_BTN GUB,
GBS_USER_PROFILE GUP
WHERE GUB.CUST_UID = GUP.CUST_UID
AND GUB.BTN = '#straccountID'
ORDER BY
CREATE_DATE DESC"
#straccountid = strAccountID.Substring(0, 10);
Code For running the query against the DB
try
{
oCn = new SqlConnection(ConfigurationSettings.AppSettings["GBRegistrationConnStr"].ToString());
oCn.Open();
oCmd = new SqlCommand();
oCmd.Parameters.AddWithValue("#strAccountID", strAccountID);
oCmd.CommandText = sSQL;
oCmd.Connection = oCn;
oCmd.CommandType = CommandType.Text;
oDR = oCmd.ExecuteReader(CommandBehavior.CloseConnection);
I already declared the variable. Is there any flaw in my query?
First off the bat get rid of these two lines:
string #straccountid = string.Empty;
#straccountid = strAccountID.Substring(0, 10);
and then try this code:
string strAccountID = "A1234"; //Create the variable and assign a value to it
string AcctID = strAccountID.Substring(0, 10);
oCn = new SqlConnection(ConfigurationSettings.AppSettings["GBRegistrationConnStr"].ToString());
oCn.Open();
oCmd = new SqlCommand();
oCmd.CommandText = sSQL;
oCmd.Connection = oCn;
oCmd.CommandType = CommandType.Text;
ocmd.Parameters.Add("straccountid", AcctID); //<-- You forgot to add in the parameter
oDR = oCmd.ExecuteReader(CommandBehavior.CloseConnection);
Here is a link on how to create Parametized Query: http://www.dotnetperls.com/sqlparameter
You've declared #straccountid but not as part of the SQL. The SQL server only sees what you send to it. You'd be better off using SQLCommand and parameters to build your select statement safely. This post has examples.
In my app I capture a "Timestamp". This timestamp I later use when I call a stored procedure. At the moment I'm getting the error :
ORA-01830: date format picture ends before converting entire input
string ORA-06512: at line 2
I need hour,min and sec because the column in the table must be unique.
Here is how i get my datetime:
private void getDate()
{
conn.Open();
string query;
query = "select to_char(sysdate, 'dd/mon/yyyy hh24:mi:ss') as CurrentTime from dual";
OracleCommand cmd = new OracleCommand(query, conn);
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
text = dr[0].ToString();
dr.Close();
conn.Close();
}
This is how I call the procedure:
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
conn.Open();
OracleTransaction trans = conn.BeginTransaction();
cmd.CommandTimeout = 0;
cmd.CommandText = "dc.hhrcv_insert_intrnl_audit_scn";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("pn_pallet_id", OracleDbType.Number).Value = palletid;
cmd.Parameters.Add("pn_emp_id_no", OracleDbType.Number).Value = empid;
cmd.Parameters.Add("pd_intrnl_audit_scan_datetime", OracleDbType.VarChar).Value = text;
cmd.Parameters.Add("pn_company_id_no", OracleDbType.VarChar).Value = companyIdNo2;
cmd.Parameters.Add("pn_order_no", OracleDbType.Number).Value = orderNo2;
cmd.Parameters.Add("pn_carton_code", OracleDbType.Number).Value = carton_Code2;
cmd.Parameters.Add("pn_no_of_full_carton", OracleDbType.Number).Value = txtNoOfCartons.Text;
cmd.Parameters.Add("pn_no_of_packs", OracleDbType.Number).Value = txtNoOfPacks.Text;
cmd.Parameters.Add(new OracleParameter("pv_error", OracleDbType.VarChar));
cmd.Parameters["pv_error"].Direction = ParameterDirection.Output;
string pv_error;
cmd.ExecuteNonQuery();
pv_error = cmd.Parameters["pv_error"].Value.ToString();
if (pv_error.ToString() == "")
{
trans.Commit();
frmMsgAudit ms = new frmMsgAudit(empid,palletid,orderno,text);
ms.Show();
this.Hide();
}
else
{
trans.Rollback();
MessageBox.Show("" + pv_error, "Error");
}
conn.Close();
Getting the error on:
cmd.ExecuteNonQuery();
ORA-01830: date format picture ends before converting entire input
string ORA-06512: at line 2
Thanks in advance.
Thanks for all the quick responses!
grrr.. I really need to sit and walk through everything step by step! Anyways, this was the issue:
In stored procedure i had:
...
begin
insert into dc_internal_audit_scan (pallet_id_no,
internal_audit_scan_emp,
internal_audit_scan_datetime,
company_id_no,
order_no,
carton_code,
no_of_full_cartons,
no_of_packs,
last_update_datetime,
username)
values (ln_pallet_id_no,
pn_emp_id_no,
**pd_intrnl_audit_scan_datetime,**
pn_company_id_no,
pn_order_no,
pv_carton_code,
pn_no_of_full_cartons,
pn_no_of_packs,
sysdate,
lv_emp_username);
end;
now:
...
begin
insert into dc_internal_audit_scan (pallet_id_no,
internal_audit_scan_emp,
internal_audit_scan_datetime,
company_id_no,
order_no,
carton_code,
no_of_full_cartons,
no_of_packs,
last_update_datetime,
username)
values (ln_pallet_id_no,
pn_emp_id_no,
**TO_DATE(pd_intrnl_audit_scan_datetime,'dd/mon/yyyy hh24:mi:ss'),**
pn_company_id_no,
pn_order_no,
pv_carton_code,
pn_no_of_full_cartons,
pn_no_of_packs,
sysdate,
lv_emp_username);
end;
TO_DATE(pd_intrnl_audit_scan_datetime,'dd/mon/yyyy hh24:mi:ss')
thanks
Looks like this line is wrong;
query = "select to_char(sysdate, 'dd/mon/yyyy hh24:mi:ss')
What 24 doing here?
Try with;
query = "select to_char(sysdate, 'dd/mon/yyyy hh:mi:ss AM')
FROM ORA-01830 Error
You tried to enter a date value, but the date entered did not match
the date format.
EDIT: Since A.B.Cade warned me, hh24 is a valid oracle format, but still I believe your sysdate's format and 'dd/mon/yyyy hh24:mi:ss' are different formats.
With the code below I get, "ORA-01036: illegal variable name/number" on the call to ExecuteReader:
cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
Devart.Data.Oracle.OracleCursor oraCursor =
(Devart.Data.Oracle.OracleCursor)cmd.Parameters["cur"].Value;
Devart.Data.Oracle.OracleDataReader odr = cmd.ExecuteReader();
while (odr.Read()) {
ACurrentUserRoles.Add(odr.GetString(0));
}
What I want to do is populate a List with the result of the query. I don't see any examples for that in DevArt's documentation (or googling). I had it working with Oracle's ODP components with:
OracleDataReader odr = cmd.ExecuteReader();
while (odr.Read())
{
ACurrentUserRoles.Add(odr.GetString(0));
}
...but can't find the parallel working with DotConnect components.
Updated:
Okay, here's the entire method (ACurrentUserRoles is a List of Strings):
public void PopulateCurrentUserRoles(String AUserName, List<String> ACurrentUserRoles) {
_UserName = AUserName;
String query = "select roleid from ABCrole where ABCid = :ABCID";
Devart.Data.Oracle.OracleCommand cmd = new Devart.Data.Oracle.OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
int _ABCID = GetABCIDForUserName();
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
//cmd.ExecuteNonQuery(); blows up: "illegal variable name/number"
//cmd.ExecuteCursor(); " "
//cmd.ExecuteReader(); " "
Devart.Data.Oracle.OracleCursor oraCursor =
(Devart.Data.Oracle.OracleCursor)cmd.Parameters["cur"].Value;
Devart.Data.Oracle.OracleDataReader odr = oraCursor.GetDataReader(); // "Object reference not set to an instance of an object"
while (odr.Read()) {
ACurrentUserRoles.Add(odr.GetString(0));
}
}
The err msgs I'm getting are appended as comments to the lines where they occur.
First, why are you adding a cursor type parameter and then totally ignore it?.
Second, I have never seen this use of cursor with the ExecuteReader but with the ExecuteNonQuery.
For example:
string cmdText = "begin open :cur for select * from dept; end;";
OracleCommand oraCommand = new OracleCommand(cmdText, oraConnection);
oraCommand.Parameters.Add("cur", OracleDbType.Cursor);
oraCommand.Parameters["cur"].Direction = ParameterDirection.Output;
oraCommand.ExecuteNonQuery();
OracleCursor oraCursor = (OracleCursor)oraCommand.Parameters["cur"].Value;
oraDataAdapter.Fill(dataSet, "Table", oraCursor);
So probably your exception derives from the use of ExecuteReader
This is another example taken directly from the site of DevArt:
string cmdText = "begin open :cur1 for select * from dept;" +
"open :cur2 for select * from emp; end;";
OracleCommand oraCommand = new OracleCommand(cmdText, oraConnection);
oraCommand.Parameters.Add("cur1", OracleDbType.Cursor);
oraCommand.Parameters["cur1"].Direction = ParameterDirection.Output;
oraCommand.Parameters.Add("cur2", OracleDbType.Cursor);
oraCommand.Parameters["cur2"].Direction = ParameterDirection.Output;
oraDataAdapter.SelectCommand = oraCommand;
oraDataAdapter.Fill(dataSet);