Im trying to do a COUNT using C# 'Prepared Statements' but I get error: :
SqlCommand.Prepare method requires all variable length parameters to
have an explicitly set non-zero Size
Below is my code:
public int PreparedCheck(String email)
{
SqlCommand cmd = new SqlCommand();
cmd = new SqlCommand("SELECT COUNT(*) FROM [dbo].[AspNetUsers] WHERE Email=#val1", conn);
cmd.Parameters.Add("#val1", SqlDbType.VarChar);
cmd.Prepare();
Int32 count = (Int32) cmd.ExecuteScalar();
return count;
}
Looks like you didn't specify your parameter value.
cmd.Parameters.Add("#val1", SqlDbType.VarChar).Value = email;
I write email as a value because you pass it as a parameter to your PreparedCheck method but you never use it.
Two errors. You don't set the value for the parameter, but you also don't set the size of the parameter as required by the Prepare method
SqlParameter p1 = cmd.Parameters.Add("#val1", SqlDbType.VarChar);
p1.Value = email;
p1.Size = 255; // This should be the size of the column EMail on the datatable
cmd.Prepare();
Simply setting the value of the parameter seems not to be enough for the Prepare method.
While the property size is changed to the string length passed as value, the error is still there and doesn't go away until you explicitly set the Size property to valid value.
This is from the REMARKS section on SqlCommand.Prepare
Before you call Prepare, specify the data type of each parameter in
the statement to be prepared. For each parameter that has a variable
length data type, you must set the Size property to the maximum size
needed. Prepare returns an error if these conditions are not met.
You need to set the value for your parameter:
cmd.Parameters.Add("#val1", SqlDbType.VarChar).Value = email;
Related
i have two methods having
getlisting(string url,int ID)
i want to pass this ID to another method in another class,
class cc=new class();
cc.updatevalue(ID);
now i want to pass this int value to that updatevalue method and assign it a 0 value. and every time getlisting having different ID and passing it to update method. i have tried if else condition as well. so my question is can anyone help me in assigning that default 0 value to every coming int value.
after assigning i want to update that in my DataTable
SqlCommand cmd = new SqlCommand("UPDATE Paging SET Status='1' WHERE ID ='ID'", obj.openConnection());
and ID is throwing an error of cannot convert varchar into data type, tell me the condition with which i can give default value to every int and makes it equal to ID. thanks
I suspect the problem is with your SQL, also I suggest using parameterized query , so your code should be...
SqlCommand cmd = new SqlCommand("UPDATE Paging SET Status=#status WHERE ID =#id", obj.openConnection());
cmd.Parameters.Add("#status", SqlDbType.Int).Value = 1; // modify this to varchar if status is string
cmd.Parameters.Add("#id", SqlDbType.Int).Value = ID;
On the side note, we could specify default value for parameters take a look at Named and Optional Arguments.
SqlCommand cmd = new SqlCommand("UPDATE Paging SET Status='1' WHERE ID ='" . ID . "'", obj.openConnection());
You were passing ID as the string 'ID' instead of your variable.
This error has me very confused. I have a stored procedure with two output parameters as defined below
#agentNumber int OUTPUT,
#currentAgentNum int OUTPUT,
They are then populated using the SELECT statements below
SELECT #agentNumber = AgentNumber
FROM AgentIdentification
WHERE AgentTaxId = #ssn
SELECT #currentAgentNum = AgentNumber
FROM UniqueAgentIdToAgentId
WHERE AgentId = #agentId
In the database, AgentNumber is defined in both tables, as an int. However, when I call this stored procedure in my C# code, I get a SQL exception stating:
Error converting data type int to nvarchar.
If I change the data types of the output parameters to nvarchar, the code will execute, however it will only return nothing more than the first digit of the whole number. Below is how the variables are defined in the C# code
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", "");//Output parameter - leave blank
SqlParameter outCurrentAgentNumber = new SqlParameter("#currentAgentNum", "");//Output parameter - leave blank
outNewAgentNumber.Direction = ParameterDirection.Output;
outCurrentAgentNumber.Direction = ParameterDirection.Output;
I add these parameters to a SqlCommand object, specify the appropriate database and commandType, then use .ExecuteNonQuery() to call the procedure. Again, what has me really confused is the error message stating that I'm using nvarchar as a data type, which could only (to the best of my knowledge) be referring to something on the database side. However, as I said I've double/triple checked and both AgentNumber columns are of type int.
EDIT
Changing the sqlParameter declarations to a starting value of 0 has solved this issue. I'm now running into the same problem with two other parameters.
SqlParameter outOperator = new SqlParameter("#operator", "");//Output parameter - leave blank
SqlParameter outDate = new SqlParameter("#date", "");//Output parameter - leave blank
Change
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", "");//Output parameter - leave blank
SqlParameter outCurrentAgentNumber = new SqlParameter("#currentAgentNum", "");//Output parameter - leave blank
to
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", 0);//Output parameter - leave blank
SqlParameter outCurrentAgentNumber = new SqlParameter("#currentAgentNum", 0);//Output parameter - leave blank
In your code, you're initially specifying the value as a string because you are passing it a string, which maps to a varchar when going from the CLR type to the SQL Data Type.
Once the runtime sees it as a string, it retains the same type throughout code, so if you assign a numeric (int) value, it still sees it as a string. The trick is to assign it the correct data type in the first place.
These two lines are the culprits:
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", "");
SqlParameter outCurrentAgentNumber = new SqlParameter("#currentAgentNum", "");
By specifying an empty string ("") as the second parameter, the ADO.NET runtime assumes it's a string paramter. And since you didn't specify any lengths - it probably defaults to just one character length (that's why it's returning only the first digit).
So, my recommendation would be to always explicitly define the datatype (and if it's a string - also define a length!) for your SQL parameters:
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", SqlDbType.Int);
outNewAgentNumber.Direction = ParameterDirection.Output;
outNewAgentNumber.Value = 0;
or
SqlParameter outNewAgentNumber = new SqlParameter("#agentNumber", SqlDbType.NVarChar, 50);
outNewAgentNumber.Direction = ParameterDirection.Output;
outNewAgentNumber.Value = "";
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.
I have the following parameter for SqlCommand. How do I make it to both in and out the paramter value for the Stored Procedure.
SqlCommand mySqlCommand = new SqlCommand("aspInsertZipCode", mySqlConnection);
mySqlCommand.CommandType = CommandType.StoredProcedure;
mySqlCommand.Parameters.Add("#DataRows", dataStringToProcess.ToString());
var pInOut = mySqlCommand.Parameters.Add("#DataRows", dataStringToProcess.ToString());
pInOut.Direction = ParameterDirection.InputOutput;
And then to read the output value after you've executed the command:
// assumes that the parameter is a string and that it could possibly be null
string value = Convert.IsDBNull(pInOut.Value) ? null : (string)pInOut.Value;
SqlParameter has a Direction enumeration. Set this value.
Then use the SqlCommand.Parameters.Add that takes a SqlParameter.
Parameter direction:
http://msdn.microsoft.com/en-us/library/system.data.parameterdirection.aspx
You then pull the value out after having called ExecuteNonQuery (for example), by getting the Value from the parameter out of the command collection:
myCommand.Parameters["#paramName"].Value
Can't remember, but I think there is a string indexer on that.
Alternatively, there is this one liner:
myCommand.Parameters.AddWithValue("#paramName", value).Direction = ParameterDirection.InputOutput;
One of the attributes of a SQL Command Parameter is the Direction. You would want to use (going off of memory)
SqlCommand mySqlCommand = new SqlCommand("aspInsertZipCode", mySqlConnection);
mySqlCommand.CommandType = CommandType.StoredProcedure;
mySqlCommand.Parameters.Add("#DataRows", dataStringToProcess.ToString());
mySqlCommand.Parameters("#DataRows").Direction = ParameterDirection.InputOutput;
SqlParameter DataRows = new SqlParameter("#DataRows", SqlDbType.Text)
{ Value = dataStringToProcess.ToString(), Direction = ParameterDirection.InputOutput};
mySqlCommand.Parameters.Add(DataRows);
I'm trying to get output value from DB via ADO.NET. There's a client code:
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("pDoSomethingParamsRes", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#i", 1);
var outParam = new SqlParameter("#out", SqlDbType.VarChar);
outParam.Direction = ParameterDirection.Output;
command.Parameters.Add(outParam);
command.ExecuteNonQuery();
Console.WriteLine(command.Parameters["#out"].Value.ToString());
}
When I run this I get the following exception:
the Size property has an invalid size of 0
According to manual SqlParameter.Size Property I might omit size. Why do I get this exception?
How to make it work without passing size?
VarChar and NVarChar are variable width character fields (thus var+char). You have to set the length, otherwise the default is zero.
Parameter Size is required for variable size Output parameters. Generally ADO.NET decides the size of the parameter based on the Value assigned to the parameter (hence it is optional), but in output parameter since no value is Set, you need provide the size required for the parameter
Set the Parameter size to size of the output variable from the DB... Say 50
outParam.Size = 50;
Incidentally, setting the size property of an output parameter is necessary even if it isn't a string-type parameter. For example, if you are using a System.Data.SqlDbType.Int, you should set the size to be 4.
Check MSDN : SqlParameter.Size Property
For bidirectional and output parameters, and return values, you must set the value of Size. This is not required for input parameters, and if not explicitly set, the value is inferred from the actual size of the specified parameter when a parameterized statement is executed.
Everyone's answer was about as clear as mud to me. Maybe this will help someone now that I found what worked.
Need to add size to the parameter
DynamicParameters Params = new DynamicParameters();
Params.Add("#ProfileID", ProfileID);
Params.Add("#CategoryName", CategoryName);
Params.Add("#Added", dbType: DbType.String, direction: ParameterDirection.Output,size:10);
db.Execute(sql, Params, commandType: CommandType.StoredProcedure, commandTimeout: 60);
var Added = Params.Get<string>("#Added");
I'm not sure if this is the same problem i've had before, but using a byte for a parameter can sometimes lead to this error.
Try this. Explicitly declare the i parameter as a variable.
THEN assign it's value with the Value property.
Also, you can get the actual size of the parameters by inspecting the sproc with this little command:
SqlCommandBuilder.DeriveParameters(yourCommand)
and then just foreach your way through the parameters collection.
I had this error occur, supplying a value that had a non-string, but nullable, type. In my case, an int?. I fixed it by passing in a non-nullable int instead.
you have to set Size for parameter output
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("pDoSomethingParamsRes", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#i", 1);
var outParam = new SqlParameter("#out", SqlDbType.VarChar);
outParam.Direction = ParameterDirection.Output;
outParam.Size = 50; // this is example
command.Parameters.Add(outParam);
command.ExecuteNonQuery();
Console.WriteLine(command.Parameters["#out"].Value.ToString());
}
I had the same error and below is my code that works
cmd.Parameters("#ProjectKey").SqlDbType = SqlDbType.NVarChar
cmd.Parameters("#ProjectKey").Size = 150
cmd.Parameters("#ProjectKey").Direction = ParameterDirection.InputOutput
cmd.ExecuteNonQuery()