Cannot Pass Parameter in DbCommand in Entity Framework - c#

I have error when I try to pass parameter to stored procedure using DbCommand
Error returned:
Procedure or function 'Procedure_Name' expects parameter '#TEID', which was not supplied.
These are my procedure parameters:
#PageNumber INT = 1,
#PageSize INT = 50,
#StartTime nvarchar(max) = -1 ,
#EndTime nvarchar(max) = -1 ,
#Month NVARCHAR(2) = -1,
#Year NVARCHAR(4) = -1,
#Day NVARCHAR(2) = -1,
#Hour NVARCHAR(2)=-1,
#TEID nvarchar(max) ,
#IgnoreIdlingTime int=120,
#DrivingTime int=300,--5 minutes by default
#CalculationFactor nvarchar(10)='speed'
My code to execute procedure and pass parameters:
using (var context = new GPSModel())
{
context.Database.Initialize(force: false);
// Create a SQL command to execute the stored procedure
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandText = "Procedure_Name";
DbParameter TEIDParam = cmd.CreateParameter();
TEIDParam.ParameterName = "#TEID";
TEIDParam.DbType = System.Data.DbType.String;
TEIDParam.Direction = ParameterDirection.Input;
TEIDParam.Value = TEID;
cmd.Parameters.Add(TEIDParam);
context.Database.Connection.Open();
var reader = cmd.ExecuteReader();
}
I tried to remove # sign and send SqlParameter instead of DbParameter but still I have the same issue.
Is there any other way to do that where my stored procedure is very complex and contains multi sets
Thanks...

You can use the following code to solve the error. I have added cmd.CommandType = CommandType.StoredProcedure;. Now it works properly.
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Procedure_Name";
DbParameter TEIDParam = cmd.CreateParameter();
TEIDParam.ParameterName = "#TEID";
TEIDParam.DbType = System.Data.DbType.String;
TEIDParam.Direction = ParameterDirection.Input;
TEIDParam.Value = TEID;
cmd.Parameters.Add(TEIDParam);
When you are using stored procedure you have to set CommandType property to StoredProcedure, and then you should set the CommandText property to the name of the stored procedure. The command executes this stored procedure when you call one of the Execute methods.

FOR EF core it can be done using fromSQL()
var tbl = new DataTable();
tbl.Columns.Add("id", typeof(string));
foreach (var item in imageChunkRequest.ChunkNames)
{
tbl.Rows.Add(item);
}
SqlParameter Parameter = new SqlParameter();
Parameter.ParameterName = "#udt";
Parameter.SqlDbType = SqlDbType.Structured;
Parameter.Value = tbl;
Parameter.TypeName = "dbo.StringList";
_dbContext.Set<T>().FromSql("EXEC dbo.FindChunks #udt",Parameter);

Related

Calling stored procedure from c# returns "?????" in varchar response

When I call a stored procedure on a SQL-Server from C#, using ADO.NET, I receive following response in my output-parameter:
Literally ?????? as a VarChar.
My stored procedure looks like this:
ALTER Procedure [sp_getEncryptedPassword]
(#PublicKey nvarchar(128), #UserId uniqueidentifier, #PasswordClearText varchar(255) OUTPUT, #resOUT int OUTPUT, #rowsOUT int OUTPUT)
AS
SET NOCOUNT On
DECLARE #LinkIsValid bit = 0;
set #rowsOUT=0
while (#LinkIsValid=0)
begin
SELECT CONVERT(nvarchar, DecryptByPassphrase(#PublicKey, UserpasswordEncrypted, 1, CONVERT(varbinary, #UserId))) AS PassWordClearText
Into #TEMP1
from UserLogin
WHERE Userid = #UserId
set #rowsOUT=##ROWCOUNT
SET #LinkIsValid=1
end
if #rowsOUT=0
SET #resOUT=1
select 'RStestPwd' as 'PasswordClearText', #resOUT as 'resOUT', #rowsOUT as 'rowsOUT'
I have removed some lines, but I hope you get the point.
As part of debugging, I have hardcoded a response - just to see if I get anything. And I do:
My C# code:
SqlConnection con = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(spName, con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter pubKey = cmd.Parameters.Add("#PublicKey", SqlDbType.UniqueIdentifier);
pubKey.Direction = ParameterDirection.Input;
pubKey.Value = publicKey;
SqlParameter IdIn = cmd.Parameters.Add("#UserId", SqlDbType.UniqueIdentifier);
IdIn.Direction = ParameterDirection.Input;
IdIn.Value = userid;
SqlParameter pwdOUT = cmd.Parameters.Add("#PasswordClearText", SqlDbType.VarChar, 255);
pwdOUT.Direction = ParameterDirection.Output;
SqlParameter resOUT = cmd.Parameters.Add("#resOUT", SqlDbType.Int);
resOUT.Direction = ParameterDirection.Output;
SqlParameter rowsOUT = cmd.Parameters.Add("#rowsOUT", SqlDbType.Int);
rowsOUT.Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
result.Password = pwdOUT.Value.ToString();
Is it a part of the formatting between the SQL-server and my application?
Is it a setting in my SQL-server, my ADO.NET Command instance or my conntection string?
EDIT:
Thanks for your comments. I have reviewed my code, and modyfied places with (N)VarChar and so on.
Neither before or after these modifications, I get any exceptions - just the questionmarks. So the SP is working - but loose/modify data between database and application...

ExecuteNonQuery with return value in a stored procedure [duplicate]

I am trying to call a stored procedure from my C# windows application. The stored procedure is running on a local instance of SQL Server 2008. I am able to call the stored procedure but I am not able to retrieve the value back from the stored procedure. This stored procedure is supposed to return the next number in the sequence. I have done research online and all the sites I've seen have pointed to this solution working.
Stored procedure code:
ALTER procedure [dbo].[usp_GetNewSeqVal]
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
Code calling the stored procedure:
SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();
SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter();
param = cmd.Parameters.Add("#SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";
SqlDataReader reader = cmd.ExecuteReader();
I have also tried using a DataSet to retrieve the return value with the same result. What am I missing to get
the return value from my stored procedure? If more information is needed, please let me know.
You need to add a ReturnValue-direction parameter to the command:
using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = parameterStatement.getQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");
// #ReturnVal could be any name
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
Setting the parameter's direction to ParameterDirection.ReturnValue instructs the SqlCommand to declare it as a variable and assign the stored procedure's return value to it (exec #ReturnValue = spMyProcedure...), exactly like you would write it in SQL.
I know this is old, but i stumbled on it with Google.
If you have a return value in your stored procedure say "Return 1" - not using output parameters.
You can do the following - "#RETURN_VALUE" is silently added to every command object. NO NEED TO EXPLICITLY ADD
cmd.ExecuteNonQuery();
rtn = (int)cmd.Parameters["#RETURN_VALUE"].Value;
The version of EnterpriseLibrary on my machine had other parameters.
This was working:
SqlParameter retval = new SqlParameter("#ReturnValue", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
db.ExecuteNonQuery(cmd);
object o = cmd.Parameters["#ReturnValue"].Value;
I had a similar problem with the SP call returning an error that an expected parameter was not included. My code was as follows.
Stored Procedure:
#Result int OUTPUT
And C#:
SqlParameter result = cmd.Parameters.Add(new SqlParameter("#Result", DbType.Int32));
result.Direction = ParameterDirection.ReturnValue;
In troubleshooting, I realized that the stored procedure was ACTUALLY looking for a direction of "InputOutput" so the following change fixed the problem.
r
Result.Direction = ParameterDirection.InputOutput;
This is a very short sample of returning a single value from a procedure:
SQL:
CREATE PROCEDURE [dbo].[MakeDouble] #InpVal int AS BEGIN
SELECT #InpVal * 2; RETURN 0;
END
C#-code:
int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
"Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
sqlCon.Open();
retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";",
sqlCon).ExecuteScalar().ToString();
sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal);
//> 11 * 2 = 22
ExecuteScalar(); will work, but an output parameter would be a superior solution.
You can try using an output parameter. http://msdn.microsoft.com/en-us/library/ms378108.aspx
Or if you're using EnterpriseLibrary rather than standard ADO.NET...
Database db = DatabaseFactory.CreateDatabase();
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
{
db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);
db.ExecuteNonQuery(cmd);
var result = (int)cmd.Parameters["RetVal"].Value;
}
I see the other one is closed. So basically here's the rough of my code. I think you are missing the string cmd comment. For example if my store procedure is call:DBO.Test. I would need to write cmd="DBO.test". Then do command type equal to store procedure, and blah blah blah
Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;

Call to stored procedure returning 1 of 30 characters

I am programmatically calling a SQL Server stored procedure which should return 30 random characters. Instead, it is only returning 1 char. What am I missing?
The stored procedure is working as it should when I execute it in SQL Server, but in the C#, its not working correctly.
var messageId = "";
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString))
{
conn.Open();
using (SqlCommand command = new SqlCommand("GenerateMessageId", conn))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#msgid", messageId);
command.Parameters[0].Direction = ParameterDirection.Output;
command.ExecuteNonQuery();
messageId = (string)command.Parameters[0].Value;
}
}
}
Stored procedure:
ALTER PROCEDURE [dbo].[GenerateMessageId]
#msgid varchar(30) OUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
EXEC dbo.GenerateRandomString 1, 1, 1, null, 30, #msgid OUT
END
Try to add:
command.Parameters[0].Size = 30;
or
command.Parameters.Add("#msgid", SqlDbType.VarChar, 30).Direction = ParameterDirection.Output;
or use explicit declaration:
SqlParameter msgid= new SqlParameter {
ParameterName = "#msgid",
IsNullable = true,
Direction = ParameterDirection.Output,
DbType = DbType.String,
Size = 30,
Value = messageId,
} ;
command.Parameters.Add(msgid);

How can I obtain a value from an output parameter while also providing a value as an input?

I am using my code in C# below
cn = new SqlConnection(connetionString);
using (SqlCommand cmd = new SqlCommand("sp_Get_Cur", cn))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parm = new SqlParameter("#cur", SqlDbType.VarChar);
parm.Size = 3;
parm.Value = s_cur;
parm.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm);
SqlParameter parm2 = new SqlParameter("#val", SqlDbType.Decimal);
parm2.Direction = ParameterDirection.Output;
parm2.Value = val;
cmd.Parameters.Add(parm2);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
return (decimal)cmd.Parameters["#val"].Value;
}
my SP is:
ALTER PROCEDURE sp_Get_Cur
#cur VARCHAR(3),
#val decimal(16,2) OUTPUT
AS
BEGIN
DECLARE #rate decimal(16,2)
SELECT #rate = rate FROM exchange_rate WHERE code = #cur
SET #val = #val / #rate
END
But I am getting the error: {"Specified cast is not valid."}
I wanted to get the result of a currency from my exchange rate table.
Is there a better way of getting results simplier than doing output parameter direction type?
TEST RESULTS in SQL:
DECLARE #val decimal(16,2)
SET #val = 5
EXECUTE sp_Get_Cur 'EUR', #val output
SELECT #val
Result = 6.76
in Code Watch, my cmd.Parameters["#val"].Value; = 5.00;
when executed it becomes {} or null?
If you specify the parameter as output only it will not pass any value into the stored procedure, hence inside the procedure you will be dividing with a null which returns a null.
Change the parameter direction like this:
parm2.Direction = ParameterDirection.InputOutput;

How to get return value from stored procedure

I have the following stored procedure:
ALTER PROCEDURE spLogin
#CAD_WEB_LOGIN_USERNAME varchar(60),
#CAD_WEB_LOGIN_PASSWORD varchar(60),
#Result int output
AS
BEGIN
SELECT
CAD_NUMBER
FROM
CMACADDR
WHERE
CAD_WEB_LOGIN_USERNAME = #CAD_WEB_LOGIN_USERNAME
AND CAD_WEB_LOGIN_PASSWORD = #CAD_WEB_LOGIN_PASSWORD
END
In C#, I want to execute this query and get the return value.
This is my code:
int flag = 0;
con.Open();
SqlCommand cmd3 = new SqlCommand("spLogin", con);
cmd3.Connection = con;
cmd3.CommandType = CommandType.StoredProcedure;
cmd3.Parameters.Add("#CAD_WEB_LOGIN_USERNAME", SqlDbType.VarChar).Value = txtUserName.Text;
cmd3.Parameters.Add("#CAD_WEB_LOGIN_PASSWORD", SqlDbType.VarChar).Value = txtPassword.Text;
SqlParameter parm = new SqlParameter("#Return", SqlDbType.Int);
parm.Direction = ParameterDirection.ReturnValue;
cmd3.Parameters.Add(parm);
flag = cmd3.ExecuteNonQuery();
con.Close();
int id = Convert.ToInt32(parm.Value);
I get an error:
Procedure or function 'spLogin' expects parameter '#Result', which was not supplied.
What's the logic error with this code?
Thanks
Change the ParameterDirection to Output , and change the parameter name to #Result .
SqlParameter parm = new SqlParameter("#Result", SqlDbType.Int);
parm.Direction = ParameterDirection.Output;
cmd3.Parameters.Add(parm);
As error suggest 'spLogin' expects parameter '#Result'
Change
SqlParameter parm = new SqlParameter("#Return", SqlDbType.Int);
to
SqlParameter parm = new SqlParameter("#Result", SqlDbType.Int);
EDIT
Also updated your procedure, return some value. Currently you are not returning anything. Also you don't need to add an extra parameter in SP.
ALTER PROCEDURE Splogin #CAD_WEB_LOGIN_USERNAME VARCHAR(60),
#CAD_WEB_LOGIN_PASSWORD VARCHAR(60)
AS
BEGIN
Declare #MyResult as INT
SELECT #MyResult = cad_number
FROM cmacaddr
WHERE cad_web_login_username = #CAD_WEB_LOGIN_USERNAME
AND cad_web_login_password = #CAD_WEB_LOGIN_PASSWORD
RETURN #MyResult -- return value
END

Categories

Resources