Getting Error as #Parameter1 is not a parameter for procedure - c#

I am learning mvc from this video where I am getting data from a form and saving it to database. When I ran my code first it gave an error stating
Procedure or function 'spAddEmployee' expects parameter '#Employee_Name', which was not supplied.
I followed a solution in which I initialized my stored procedure as NULL but now I am getting another error stating "#Parameter1 is not a parameter for procedure".
This is my stored procedure
ALTER PROCEDURE [dbo].[spAddEmployee]
(
#Employee_Name varchar(max) = NULL,
#Employee_Age int = NULL,
#Employee_Salary int = NULL,
#Employee_City varchar(50) = NULL
)
AS
BEGIN
INSERT INTO tblEmployee (Employee_Name, Employee_Age, Employee_Salary, Employee_City)
VALUES (#Employee_Name, #Employee_Age, #Employee_Salary, #Employee_City)
END
And this is my ADO.NET code:
public void AddEmployee(Employee employee)
{
string connectionString = ConfigurationManager.ConnectionStrings["EmployeeContext"].ConnectionString;
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("spAddEmployee", con)
{
CommandType = CommandType.StoredProcedure
};
SqlParameter paramName = new SqlParameter();
paramName.ParameterName = "#Employee_Name";
paramName.Value = employee.Employee_Name;
cmd.Parameters.Add(paramName);
SqlParameter paramAge = new SqlParameter();
paramAge.ParameterName = "#Employee_Age";
paramAge.Value = employee.Employee_Age;
cmd.Parameters.Add(paramAge);
SqlParameter paramSalary = new SqlParameter();
paramSalary.ParameterName = "#Employee_Salary";
paramSalary.Value = employee.Employee_Salary;
cmd.Parameters.Add(paramSalary);
SqlParameter paramCity = new SqlParameter();
paramCity.ParameterName = "#Employee_City";
paramCity.Value = employee.Employee_City;
cmd.Parameters.Add(paramCity);
con.Open();
cmd.ExecuteNonQuery();
}
}
And this is my controller code
[HttpPost]
[ActionName("Create")]
public ActionResult Create_Post(FormCollection formCollection)
{
Employee employee = new Employee();
employee.Employee_Name = formCollection["Employee_Name"];
employee.Employee_Age = Convert.ToInt32(formCollection["Employee_Age"]);
employee.Employee_Salary = Convert.ToInt32(formCollection["Employee_Salary"]);
employee.Employee_City = formCollection["Employee_City"];
EmployeeBuissnessLayer employeeBuissnessLayer = new EmployeeBuissnessLayer();
employeeBuissnessLayer.AddEmployee(employee);
return RedirectToAction("Index");
}
I am getting error at line
employeeBuissnessLayer.AddEmployee(employee);
Please help I have tried a lot of solutions but none of them have worked.

This
SqlParameter paramName = new SqlParameter();
paramName.ParameterName = "#Employee_Name";
paramName.Value = employee.Employee_Name;
cmd.Parameters.Add(paramName);
Should be
SqlParameter paramName = new SqlParameter();
paramName.ParameterName = "#Employee_Name";
// Always set the datatype
paramName.SqlDbType = SqlDbType.NVarChar;
// For strings, always set the length
paramName.Size = 128; // Max string length
// Ensure you pass DBNull not C# null
paramName.Value = employee.Employee_Name ?? System.DBNull.Value;
cmd.Parameters.Add(paramName);
Note: its best practice not to name your Stored Procedure with the sp prefix.

Related

How to call PostgreSQL 13 stored procedure (no function) with cursor INOUT parameter from Npgsql 4.1.5.0 in C#

I have this Stored Procedure with IN char parameter and INOUT cursor parameter:
CREATE OR REPLACE PROCEDURE SP_ObtenerFacturaPorNombreCliente(IN p_nombreCliente CHAR, INOUT p_cursorFacturas REFCURSOR)
LANGUAGE PLPGSQL
AS
$$
BEGIN
OPEN p_cursorFacturas FOR
SELECT "CodigoFactura", "NombreCliente", "DireccionCliente", "TelefonoCliente", "Fecha", "SubTotal", "Iva", "ValorIva", "Total", "Geografico", "Geometrico" FROM "Factura"
WHERE "NombreCliente" = p_nombreCliente
ORDER BY "CodigoFactura";
END
$$
The stored procedure calling with Npgsql 4.1.5.0 in C#:
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=mybase;User Id=user;Password=password;");
npgsqlConnection.Open();
npgsqlConnection.TypeMapper.UseNetTopologySuite();
string sentencialSQL = "CALL SP_ObtenerFacturaPorNombreCliente(:p_nombreCliente, :p_cursorFacturas);";
NpgsqlCommand npgsqlCommand = new NpgsqlCommand(sentencialSQL, npgsqlConnection);
// ===============================
NpgsqlParameter npgsqlParameter1 = new NpgsqlParameter();
npgsqlParameter1.ParameterName = ":p_nombreCliente";
npgsqlParameter1.Value = "Perico de los palotes";
npgsqlParameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;
npgsqlParameter1.Direction = ParameterDirection.Input;
npgsqlCommand.Parameters.Add(npgsqlParameter1);
// -------------------
NpgsqlParameter npgsqlParameter2 = new NpgsqlParameter();
npgsqlParameter2.ParameterName = ":p_cursorFacturas";
npgsqlParameter2.Value = string.Empty;
npgsqlParameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
npgsqlParameter2.Direction = ParameterDirection.InputOutput;
npgsqlCommand.Parameters.Add(npgsqlParameter2);
// ===============================
npgsqlCommand.CommandType = CommandType.Text; // CommandType.StoredProcedure is with Function
NpgsqlDataReader npgsqlDataReader = npgsqlCommand.ExecuteReader();
With: npgsqlParameter2.Value = string.Empty; I have this error:
42601: syntax error at or near <<:>>
With: npgsqlParameter2.Value = null; I have this error:
Parameter :p_cursorFacturas must be set
UPDATE:
With #madreflection suggestion, I changed null by DBNull.Value but the calling changed npgsqlParameter2 with "<unnamed portal 1>"
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=mybase;User Id=user;Password=password;");
npgsqlConnection.Open();
npgsqlConnection.TypeMapper.UseNetTopologySuite();
string sentencialSQL = "CALL SP_ObtenerFacturaPorNombreCliente(:p_nombreCliente, :p_cursorFacturas);";
NpgsqlCommand npgsqlCommand = new NpgsqlCommand(sentencialSQL, npgsqlConnection);
// ===============================
NpgsqlParameter npgsqlParameter1 = new NpgsqlParameter();
npgsqlParameter1.ParameterName = ":p_nombreCliente";
npgsqlParameter1.Value = "Perico de los palotes";
npgsqlParameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;
npgsqlParameter1.Direction = ParameterDirection.Input;
npgsqlCommand.Parameters.Add(npgsqlParameter1);
// -------------------
NpgsqlParameter npgsqlParameter2 = new NpgsqlParameter();
npgsqlParameter2.ParameterName = ":p_cursorFacturas";
npgsqlParameter2.Value = DBNull.Value;
npgsqlParameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
npgsqlParameter2.Direction = ParameterDirection.InputOutput;
npgsqlCommand.Parameters.Add(npgsqlParameter2);
// ===============================
npgsqlCommand.CommandType = CommandType.Text; // CommandType.StoredProcedure is with Function
NpgsqlDataReader npgsqlDataReader = npgsqlCommand.ExecuteReader();
Ok I figured it out. This post helped me a lot. Here's the answer for others.
//transaction is needed to keep unnamed portal 1
var transaction = npgsqlConnection.BeginTransaction();
//create the command and add all the parameters, command type, etc
...
npgsqlCommand.CommandType = CommandType.Text;
npgsqlCommand.CommandText = "call your_procedure(:parameters)";
//execute the original procedure with ExecuteNonQuery
npgsqlCommand.ExecuteNonQuery();
//change the command text and execute the reader
npgsqlCommand.CommandText = "fetch all in \"<unnamed portal 1>\"";
var npgsqlDataReader = npgsqlCommand.ExecuteReader();
while (reader.Read())
{
// do whatever is needed to extract the data
}
//clean up
transaction.Commit();
npgsqlConnection.Close();

Insert with a stored procedure and return an output parameter

I am trying to insert values in an Entity database and return true if everything is OK. I tested my stored procedure and it is working fine but when I try to call it from the code I am getting the following error:
No mapping exists from object type System.Collections.Generic.List`1
My question is: am I calling it properly?
using (Entities ent = new Entities())
{
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("#Parameter1", "Parameter1"));
parameters.Add(new SqlParameter("#Parameter2", "Parameter2"));
SqlParameter outputParameter = new SqlParameter();
outputParameter.ParameterName = "#Confirm";
outputParameter.SqlDbType = System.Data.SqlDbType.Bit;
outputParameter.Direction = System.Data.ParameterDirection.Output;
parameters.Add(new SqlParameter("#Confirm", outputParameter));
ent.Database.ExecuteSqlCommand("exec TestProc #Parameter1, #Parameter2", parameters);
bool success = Convert.ToBoolean(outputParameter.Value);
}
ExecuteSqlCommand takes an object[] not a List, so pass parameters.ToArray().
Also don't indicate success or failure with an output parameter. Just throw an error from the stored procedure if something goes wrong.
And change
SqlParameter outputParameter = new SqlParameter();
outputParameter.ParameterName = "#Confirm";
outputParameter.SqlDbType = System.Data.SqlDbType.Bit;
outputParameter.Direction = System.Data.ParameterDirection.Output;
parameters.Add(new SqlParameter("#Confirm", outputParameter));
to
SqlParameter outputParameter = new SqlParameter();
outputParameter.ParameterName = "#Confirm";
outputParameter.SqlDbType = System.Data.SqlDbType.Bit;
outputParameter.Direction = System.Data.ParameterDirection.Output;
parameters.Add( outputParameter );

Why calling SP with parameters to return multiple resultsets in Entity Framework throws error

I have a stored procedure which has 2 input parameters and returns multiple result set.
ALTER PROCEDURE [dbo].[sp_GetList]
#eid int,
#sid int,
AS
SELECT ID, NAME FROM EMPLOYEE WHERE id=#eid;
SELECT ID, NAME FROM STUDENTS WHERE id=#sid
In entity framework I am calling this stored procedure as below.
I am using this tutorial from msdn.
https://msdn.microsoft.com/en-us/library/jj691402(v=vs.113).aspx
using (var db = new APIContext()) {
db.Database.Initialize(force: false);
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[sp_GetList]";
DbParameter eid = cmd.CreateParameter();
eid.ParameterName = "#eid";
eid.DbType = System.Data.DbType.Int32;
eid.Direction = ParameterDirection.Input;
eid.Value = resourceID;
DbParameter sid = cmd.CreateParameter();
sid.ParameterName = "#sid";
sid.DbType = System.Data.DbType.Date;
sid.Direction = ParameterDirection.Input;
sid.Value = sid;
cmd.Parameters.Add(sid);
try
{
db.Database.Connection.Open();
var reader = cmd.ExecuteReader();
EmpList = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Shared.Model.EmpList>(reader).ToList();
MList.EmpList = EmpList;
reader.NextResult();
SList = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Shared.Model.SList>(reader).ToList();
MList.SList = SList;
}
finally
{
db.Database.Connection.Close();
}
When I run this code, I get error:
Additional information: Procedure or function 'sp_GetList' expects parameter '#eid', which was not supplied.
I understand this is very basic error when it comes to ado.net, but this is different using Entity framework.
Any help is apreciated.
Your code seems to be missing:
cmd.Parameters.Add(eid);

Oracle VARCHAR Parameter always returns "1" from PL/SQL Stored Procedure in C#

I am trying to get a string from a stored procedure in C# .NET from Oracle PL/SQL. The query is OK in Oracle SQL Developer, but the output parameter in C# will always return "1". I have tried setting different parameter size, direction, etc. Nothing helps. It will either return "1"/null or throw an error. Also I added an INT32 param just for testing, and it will return null every time. Above is a simplified testing query and the C# code. Being struggling for two days now on this silly thing.
string sql = #"
DECLARE
eligProdFinal1 nvarchar2(128);
status integer;
testNR integer;
BEGIN
--dbms_output.put_line( eligProdFinal1 || '|' || eligProdFinal2 || '|' || eligProdFinal3 );
dbms_output.put_line('TEST');
eligProdFinal1 := '';
dbms_output.get_line( :eligProdFinal1, :status ); --status 0 is OK
dbms_output.put_line(37);
dbms_output.get_line( :testNR, :status ); --status 0 is OK
END;
";
.NET:
//added to get DBMS Ouput Line from a query in PL/SQL ORACLE
public static string GetDbmsOutputLine(string sqlExp)
{
string dbConSAPCCDEV = "...";
using (var connection = new OracleConnection() { ConnectionString = dbConSAPCCDEV })
{
using (OracleCommand command = new OracleCommand())
{
command.Connection = connection;
command.CommandType = System.Data.CommandType.Text;
command.CommandText = string.Format(sqlExp);
connection.Open();
OracleParameter statusParameter = new OracleParameter();
statusParameter.ParameterName = "status";
statusParameter.Direction = ParameterDirection.Output;
command.Parameters.Add(statusParameter);
//tried adding the param like this, or in a single line like below
//OracleParameter lineParameter = new OracleParameter();
//lineParameter.ParameterName = "eligProdFinal1";
//lineParameter.OracleDbType = OracleDbType.Varchar2;
//lineParameter.Size = 760;
//lineParameter.Direction = ParameterDirection.ReturnValue;
//command.Parameters.Add(lineParameter);
command.Parameters.Add(new OracleParameter("eligProdFinal1", OracleDbType.NVarchar2, 128, null, ParameterDirection.Output));
OracleParameter testParameter = new OracleParameter();
testParameter.ParameterName = "testNR";
testParameter.Direction = ParameterDirection.Output;
command.Parameters.Add(testParameter);
command.ExecuteNonQuery();
if (command.Parameters["eligProdFinal1"].Value is DBNull)
return null;
string output = command.Parameters["eligProdFinal1"].Value.ToString();
string testNr = command.Parameters["testNR"].Value.ToString();
connection.Close();
return output;
}
}
}

Pass Array as parameter to Oracle stored proc from c# to bulk insert

I am trying to send arrays as parameter to Oracle stored proc in order to process bulk insert.
type Licensingentity_id is table of odilic_admin.licensingentity.licensingentity_id%type index by pls_integer;
type Nationalprovidernumber is table of odilic_admin.licensingentity.nationalprovidernumber%type index by pls_integer;
type Home_state_province_id is table of odilic_admin.licensingentity.home_state_province_id%type index by pls_integer;
procedure HomeStateLookup_bulk_insert(i_entityId in Licensingentity_id,
i_npn in Nationalprovidernumber,
i_homeStateId in Home_state_province_id) is
v_caller varchar2(60) := 'System_Scheduler';
begin
FORALL i IN 1 .. i_entityId.count
insert into home_state_lookup_stg
(licensingentity_id,
npn,
home_state_province_id,
isprocessed,
inserted_by,
inserted_date,
updated_by,
updated_date)
values
(i_entityId(i),
i_npn(i),
i_homeStateId(i),
0,
v_caller,
sysdate,
v_caller,
sysdate);
end HomeStateLookup_bulk_insert;
and here is the c# code
NiprConnectionString = ConfigurationManager.ConnectionStrings["ODI.NIPR.DB.Reader"].ConnectionString;
OracleConnection cnn = new OracleConnection(NiprConnectionString);
cnn.Open();
OracleCommand cmd = cnn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = NaicStateLookupRepositoryProcedures.HOME_STATE_BULK_INSERT;
cmd.BindByName = true;
cmd.ArrayBindCount = entities.Count;
var i_entityId = new OracleParameter();
var i_npn = new OracleParameter();
var i_homeStateId = new OracleParameter();
i_entityId.OracleDbType = OracleDbType.Int32;
i_npn.OracleDbType = OracleDbType.Varchar2;
i_homeStateId.OracleDbType = OracleDbType.Int32;
i_entityId.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
i_npn.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
i_homeStateId.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
i_entityId.Value = entities.Select(c => c.Key).ToArray();
i_npn.Value = entities.Select(c => c.Value.Item1).ToArray();
i_homeStateId.Value = entities.Select(c => c.Value.Item2).ToArray();
i_entityId.Size = entities.Count;
i_npn.Size = entities.Count;
i_homeStateId.Size = entities.Count;
cmd.Parameters.Add(i_entityId);
//cmd.Parameters[0].Value = i_entityId;
cmd.Parameters.Add(i_npn);
//cmd.Parameters[1].Value = i_npn;
cmd.Parameters.Add(i_homeStateId);
//cmd.Parameters[2].Value = i_homeStateId;
int result = cmd.ExecuteNonQuery();
but getting an exception -
ORA-06550: line 1, column 52: PLS-00103: Encountered the symbol ">"
when expecting one of the following:
( ) - + case mod new not null
Any help is much appreciated.
I can't promise this is the answer, and I don't have the tables you reference to test this for myself, but at first glance I noticed you set:
cmd.BindByName = true;
As such, I think you need to declare your parameter names:
var i_entityId = new OracleParameter("i_entityId");
var i_npn = new OracleParameter("i_npn");
var i_homeStateId = new OracleParameter("i_homeStateId");
I've never passed an array as a parameter to a procedure, but if you were to do this with a normal insert, it would look something like this:
string sql = "insert into foo values (:boo, :bar, :baz)";
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.Parameters.Add(new OracleParameter("boo", OracleDbType.Varchar2));
cmd.Parameters.Add(new OracleParameter("bar", OracleDbType.Date));
cmd.Parameters.Add(new OracleParameter("baz", OracleDbType.Varchar2));
cmd.Parameters[0].Value = booArray;
cmd.Parameters[1].Value = barArray;
cmd.Parameters[2].Value = bazArray;
cmd.ArrayBindCount = booArray.Length;
cmd.ExecuteNonQuery();
I would start by defining the parameters with the parameter names, though.

Categories