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
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();
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 );
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);
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;
}
}
}
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.