An SqlParameter with ParameterName is not contained by this SqlParameterCollection - c#

Cannot figure out why I keep getting
An SqlParameter with ParameterName is not contained by this
SqlParameterCollection
when I've been pulling and calling procs like this fine in other methods.
The proc does have the one param #EqId in that casing.
List<string> equipTypes = new List<string>();
Database db = DatabaseFactory.CreateDatabase("OurDBName");
DbCommand cmd = db.GetStoredProcCommand("Get_EquipTypes_By_ID");
db.DiscoverParameters(cmd);
cmd.Parameters["#EqId"].Value = equipID;
using (IDataReader objReader = db.ExecuteReader(cmd))
{
while (objReader.Read())
equipTypes.Add(DataUtility.GetStringFromReader(objReader, "Data"));
}

Do your add parameters like this
cmd.Parameters.AddWithValue("#EqId", equipID);
I thinks it's the cleanest way to do it, well kind of :)

First off, I would not discover parameters when you are aware of the parameters. Since you are doing this, examine the parameter collection and make sure the parameter is being discovered. Fater you have that figured out, I would aim for something more like what Greg has suggested.

Related

ORA-01008 Not All Variables Bound on a simple query C#

I am having the hardest time trying to neutralize this oracle not all variables bound. I tried the usual suggestions I got from some Google searches, but nothing seemed to help.
Eventually, for testing purposes, I reduced my query and code to a simple
public override List<DiscountList> GetDiscountList(string name)
{
string cmdText = "select discount from users where name = :Name";
DbParameters prms = new DbParameters(Ado.AdoTemplate.DbProvider);
prms.AddWithValue("Name", name);
List<DiscountList> list = Ado.AdoTemplate.QueryWithRowMapperDelegate<DiscountList>(CommandType.Text, cmdText,
new RowMapperDelegate<DiscountList>((reader, rowNum) =>
{
DiscountList item = new DiscountList();
item.Discount = reader.GetString(0, string.Empty);
return item;
})).ToList();
return list;
}
But I still receive the Oracle error, I even hardcoded the second parameter in AddWithValue to make sure it is not passing a null issue, but still the same error.
EDIT: To include whole function
Not sure why you are using DbParameters instead of OracleParameter like
command.Parameters.Add(New OracleParameter("Name", name));
(OR)
command.Parameters.AddWithValue("Name", name);
Without a bigger code snippet, it's hard to say if what you have done should work or not. To cut to the chase, this should be a working example of what I believe you are trying to do.
Note that the AddWithValue is very convenient and will nearly always result in the proper datatype mapping. If you really want to be iron-clad explicit, you can use the overload that specifies the datatype. If you ever start passing weird datatypes like Blobs, this might become important.
OracleCommand cmd = new OracleCommand("select discount from users where name = :Name",
conn);
cmd.Parameters.Add("Name", OracleDbType.VarChar);
cmd.Parameters[0].Value = name;
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
object discount = reader.GetValue(0);
}
reader.Close();
Turns out it was a silly mistake by me and I forgot an important piece of code:
})).ToList();
should be
}),prms).ToList();
I think the query should be like this:
string cmdText = "select discount from users where name = #Name";

C# adding large bytearray(image) as paramter to dbcommand

I'm currently in the process of creating a manual DB layer for a project. I've stumbled over a problem when I tried to store byte arrays (images) larger than 8k.
Normally I use the following to do create the commands and fill the parameters:
DbCommand cmd = new SqlCommand("INSERT INTO test1 VALUES (#mail, #picture)");
i=cmd.DeclareParameter(cmd, "mail", DbType.String, "mail");
if (i>0)
{
cmd.Parameters[i].Value = mailData;
}
(The above is cut together from multiple methods I use).
Now when I try to add the picture (which is the byte[]) I get the problem that I need to use SqlDbType.VarBinary there.
I've seen a few solutions that use .Parameters.Add but the Add I have only takes 1 (and not 2 parameters like in the examples I saw). Then when I try to create my own parameter with cmd.CreateParameter the DbType only takes a DbType and does not want an SqlDbType.
What would I have to do here to be able to add the byte[] as parameter (for byte arrays larger than 8k)?
tnx
Would SqlDbType.Image be more appropriate?
If not, consider Row Overflowing
You're telling it to use DbCommand rather than SqlDbCommand.
Try this:
using(var command = new SqlCommand(#"INSERT INTO test1 VALUES (#mail, #picture)"))
{
command.Parameters.Add(#"mail", SqlDbType.Image);
if (i > 0)
{
command.Parameters[i].Value = mailData;
}
}
(I'd add this as a comment, but I can't so I shant.)
when I try to create my own parameter with cmd.CreateParameter the DbType only takes a DbType and does not want an SqlDbType
That's because you declared the command as a DbCommand instead of a SqlCommand. If you declare it as a SqlCommand it should work:
|------
V
SqlCommand cmd = new SqlCommand("INSERT INTO test1 VALUES (#mail, #picture)");
cmd.Parameters.AddWithValue("#mail", mailData);
SqlParameter p = cmd.Parameters.Add("#picture", SqlDbType.VarBinary);
p.Value = {picture data};
If your files are really large you can consider streaming into the BLOB (image) column. See http://msdn.microsoft.com/en-us/library/hh556234(v=vs.110).aspx.
You need to specify the length -1 for the parameter. Otherwise it will be VARBINARY(8000). With an explicit length of -1 it will be VARBINARY(MAX), which is what you need.

Is a cursor parameter really to be declared differently than a "regular" parameter?

OK, nobody seems to know how to solve the problem I'm having looping through a cursor/result set for storage into a List, so I'm going to break it down into pieces and try to slog through it that way. So, first of all:
I add SQL Parameters to an OracleCommand object this way (works fine):
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
IOW, when I add the param, I pass the name of the parameterized portion of the SQL ("ABCID" above) and a value to give it (_ABCID is a variable that has been assigned, let's say, "42").
However, when adding a Cursor (output) param, it seems to want, not a value (such as an initialized cursor object), but simply the data type:
cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
(I tried both ways, and neither one works, so...?)
Verily/thus, my question is: Is this really the correct way of declaring a Cursor parameter to be outputted back for traversal/access?
I'm using the brand new version of DevArt DotConnect components (6.80.332), VS 2010, .NET 4
Updated:
Here's the code in more context:
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("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
//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 following is from the Oracle Data Provider for .NET Developer's Guide. yes, I know, "Devart". Nonetheless, It suggests the following:
Be careful with your parameter typing declaration.
add that cursor/output parameter to the Parameters collection before
any others.
As a long shot... my guide shows a OracleDbType.RefCursor but not a OracleDbType.Cursor. If DevArt has RefCursor, try that. In visual studio, what type does .NET think that parameter is? This question is not as dumb as I used to think.
... On the other hand, if the parameter is set as an OracleDbType.Char type by setting the OracleDbType property, the output data is returned
as an OracleString type. If both DbType and OracleDbType properties
are set before the command execution, the last setting takes affect.
. . .
"An application should not bind a value for output parameters; it is
the responsibility of ODP.NET to create the value object and populate
the OracleParameter Value property with the object. When binding by
position (default) to a function, ODP.NET expects the return value to
be bound first, before any other parameters."
EDIT:
Based on #Clay's self-answer... so there is no parameter specified for the output, rather one simply does this: OracleDataReader odr = cmd.ExecuteReader();
Straight from the horse's mouth (the DevArt folks):
_UserName = AUserName;
// From the DevArtisans:
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;
Devart.Data.Oracle.OracleDataReader odr = cmd.ExecuteReader();
while (odr.Read()) {
ACurrentUserRoles.Add(odr.GetString(0));
}
To quote Casey and the Sonshine Banned, "That's the way, Uh huh Uh huh, I like it, Uh huh Uh huh"; actually, I can't stand that crap, but I do kind of relate to that sentiment right about now.

ASP.net c# simple query paramter question

// Add into DB
using (tblArtworkTemplatesTableAdapter tblAdapter = new tblArtworkTemplatesTableAdapter())
{
tblAdapter.Insert(DateTime.Now, "#specID");
"#specID" = int.Parse(lstChooseSpec.SelectedValue)
}
I know the code is wrong, just for illustration of my objective, how do I paramatise the input?
Generally it depends. If You are using any kind of ORM like LINQ to SQL or NHibernate, it will do it for You no questions asked. If YOu are doing it using Plain ADO objects (which I suppose is the case) then You will have to comeup with the Command (or SQLCommand or any other ICommand implementation) object and use SQLParameter class (or other parameter classes).
ICommand has the collection of parameters that You can arbitralily edit.
SqlCommand cmd = new SqlCommand(
"select * from STH where column = #SpecID", conn);
//it might be useful to specify a type as well
SqlParameter param = new SqlParameter();
param.ParameterName = "#SpecID";
//I woudl use the TryParse method though
param.Value = int.Parse(lstChooseSpec.SelectedValue);
cmd.Parameters.Add(param);
This line
"#specID" = int.Parse(lstChooseSpec.SelectedValue)
Is incorrect. You can't assign a value to a constant. You might mean something like
specId = int.Parse(lstChooseSpec.SelectedValue);
The rest of the code is confusing. Why are you parsing lstChooseSpec.SelectedValue to an integer, then trying to add it to the adapter as a DateTime? C# is strongly-typed: something is either an int or a DateTime, but cannot be both.
It might help if you could post the rest of the method.
Also, have a look at this overview on MSDN.

ADO.NET parameters from TextBox

I'm trying to call a parameterized stored procedure from SQL Server 2005 in my C# Winforms app. I add the parameters from TextBoxeslike so (there are 88 of them):
cmd.Parameters.Add("#CustomerName", SqlDbType.VarChar, 100).Value = CustomerName.Text;
I get the following exception:
"System.InvalidCastException: Failed to convert parameter value
from a TextBox to a String. ---> System.InvalidCastException:
Object must implement IConvertible."
The line throwing the error is when I call the query:
cmd.ExecuteNonQuery();
I also tried using the .ToString() method on the TextBoxes, which seemed pointless anyway, and threw the same error. Am I passing the parameters incorrectly?
It's probable that you forgot to specify the Text property when assigning one of your parameter values.
For example, instead of:
CustomerName.Text
You may have done just:
CustomerName
This would be an easy thing to miss if there are 88 of them.
I suspect you have missed a .Text somewhere, but you say you did a ToString on all the parameter values so that seems strange. Anyway, you can use the following piece of code to dump the parameter names and the type name of the value, this might help spot the problematic parameter.
foreach (SqlParameter param in cmd.Parameters)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", param.ParameterName, param.Value == null ? "NULL" : param.Value.GetType().Name));
}
You should get something like the following in the debug window, in this case CustomerSurname is the parameter that has a Textbox and not a string as an example.
#CustomerName:String
#CustomerSurname:TextBox
...
try something like this:
SqlParameter sqlParam= new SqlParameter();
sqlParam.ParameterName = "#customerName";
sqlParam.Direction = ParameterDirection.Input;
sqlParam.SqlDbType = SqlDbType.VarChar;
sqlParam.Size = 100;
sqlParam.Value = customername.Text;
cmd.Parameters.Add(sqlParam);

Categories