In my project i have used EntityFramework 5 and I came up to use an SP in my Context. Like this
public virtual object GetEvaluations(int AgentId, DateTime StartDate, DateTime EndDate, int FormId)
{
DataTable table = new DataTable();
using (DbDataAdapter adapter = new SqlDataAdapter())
{
adapter.SelectCommand = _context.Database.Connection.CreateCommand();
adapter.SelectCommand.Parameters.Clear();
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand.CommandText = "GetEvaluations";
SqlParameter aid = new SqlParameter("#AgentId", SqlDbType.Int);
aid.Value = AgentId;
SqlParameter sd = new SqlParameter("#StartDate", StartDate.Date.ToString("dd.MM.yyyy"));
SqlParameter ed = new SqlParameter("#EndDate", EndDate.Date.ToString("MM.dd.yyyy"));
SqlParameter fid = new SqlParameter("#FormId", SqlDbType.Int);
fid.Value = FormId;
adapter.SelectCommand.Parameters.Add(aid);
adapter.SelectCommand.Parameters.Add(sd);
adapter.SelectCommand.Parameters.Add(ed);
adapter.SelectCommand.Parameters.Add(fid);
adapter.Fill(table);
}
return table;
}
Here the DateTime formats different style but just working like this. Even this 2 parameters are looking to the same field in the table.
Please look at datetime formats (they are different) i think they must be same style.
My SP:
USE [EvaluationAssistt]
GO
/****** Object: StoredProcedure [dbo].[GetEvaluations] Script Date: 12.03.2015 11:25:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Hammit Yildirim
-- Create date: 11.03.2015
-- Description: Defined for Category Point Reports Performance
-- =============================================
ALTER PROCEDURE [dbo].[GetEvaluations]-- 258,'1.11.2014','11.24.2014',8
#AgentId int,
#StartDate Datetime,
#EndDate Datetime,
#FormId int
AS
BEGIN
SET NOCOUNT ON;
select fce.Id from FormsCallsEvaluated fce
left join FormsCalls fc on fce.CallId = fc.CallId
where fc.AgentId=#AgentId and fc.DateStarted > #StartDate and fc.DateStarted < #EndDate and fce.FormId=#FormId
END
What is my problem
I tryed below and returning me empty table
public virtual object GetEvaluations(int AgentId, DateTime StartDate, DateTime EndDate, int FormId)
{
DataTable table = new DataTable();
using (DbDataAdapter adapter = new SqlDataAdapter())
{
adapter.SelectCommand = _context.Database.Connection.CreateCommand();
adapter.SelectCommand.Parameters.Clear();
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand.CommandText = "GetEvaluations";
SqlParameter aid = new SqlParameter("#AgentId", SqlDbType.Int);
aid.SqlValue = AgentId;
SqlParameter sd = new SqlParameter("#StartDate", SqlDbType.DateTime);
sd.SqlValue = StartDate.Date;
SqlParameter ed = new SqlParameter("#EndDate", SqlDbType.DateTime);
ed.SqlValue = EndDate.Date;
SqlParameter fid = new SqlParameter("#FormId", SqlDbType.Int);
fid.SqlValue = FormId;
adapter.SelectCommand.Parameters.Add(aid);
adapter.SelectCommand.Parameters.Add(sd);
adapter.SelectCommand.Parameters.Add(ed);
adapter.SelectCommand.Parameters.Add(fid);
adapter.Fill(table);
}
return table;
}
It is working SQL side just like this
USE [EvaluationAssistt]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[GetEvaluations]
#AgentId = 258,
#StartDate = N'1.11.2014',
#EndDate = N'11.24.2014',
#FormId = 8
SELECT 'Return Value' = #return_value
GO
You defined your #StartDate and #EndDate columns as DateTime but you try to pass them string values.
Just pass the right type and values to your parameter like;
SqlParameter sd = new SqlParameter("#StartDate", StartDate.Date);
SqlParameter ed = new SqlParameter("#EndDate", EndDate.Date);
Related
I'm trying to get the output parameter of primary key which is ID. When I do the update query I get Null. Can you please suggest a way to do this?
CREATE PROCEDURE sp_InsertTax
(#ID int output,
#TaxAuthorityID int,
#TaxClassificationID int,
#EntityID int,
#AppliesTo_TaxEntityTypeID int)
AS
IF EXISTS (SELECT * FROM Tax
WHERE TaxAuthorityID = #TaxAuthorityID
AND TaxClassificationID = #TaxClassificationID
AND EntityID = #EntityID
AND AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID)
BEGIN
UPDATE Tax
SET TaxAuthorityID = #TaxAuthorityID,
TaxClassificationID = #TaxClassificationID,
EntityID = #EntityID,
AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID
WHERE ID = #ID
END
ELSE
BEGIN
IF #ID IS NULL
BEGIN
INSERT INTO Tax(TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
VALUES (#TaxAuthorityID, #TaxClassificationID, #EntityID, #AppliesTo_TaxEntityTypeID)
SET #ID = Scope_Identity()
END
END
GO
The below is my ADO.NET code to call the update stored procedure:
public int InsertFederalTax(int ClassificID, int appliesTo)
{
int tax_id = 0;
Sqlconn.Open();
SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
cmd.CommandType = CommandType.StoredProcedure;
var returnparameter = cmd.Parameters.AddWithValue("ID", SqlDbType.Int);
returnparameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add("#TaxAuthorityID", SqlDbType.Int).Value = 1;
cmd.Parameters.Add("#TaxClassificationID", SqlDbType.Int).Value = ClassificID;
cmd.Parameters.Add("#EntityID", SqlDbType.Int).Value = 0;
cmd.Parameters.Add("#AppliesTo_TaxEntityTypeID", SqlDbType.Int).Value = appliesTo;
cmd.ExecuteNonQuery();
if (!(returnparameter.Value is DBNull))
tax_id = Convert.ToInt32(returnparameter.Value);
Sqlconn.Close();
return tax_id;
}
I think you intended to capture the ID of an existing duplicate record, which you would do as follows. I've also added best practice template items for a SP. Also note the comment from marc_c about not prefixing your SP with sp_.
CREATE PROCEDURE InsertTax
(
#ID int output
, #TaxAuthorityID int
, #TaxClassificationID int
, #EntityID int
, #AppliesTo_TaxEntityTypeID int
)
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
-- This assumes that none of the parameters can ever be null
-- And from your comments we know that no duplicates can exist
SELECT #ID = ID
FROM Tax
WHERE TaxAuthorityID = #TaxAuthorityID
AND TaxClassificationID = #TaxClassificationID
AND EntityID = #EntityID
AND AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID;
IF #ID IS NOT NULL BEGIN
UPDATE Tax
SET TaxAuthorityID = #TaxAuthorityID,
TaxClassificationID = #TaxClassificationID,
EntityID = #EntityID,
AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID
WHERE ID = #ID;
END; ELSE BEGIN
INSERT INTO Tax (TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
VALUES (#TaxAuthorityID, #TaxClassificationID, #EntityID, #AppliesTo_TaxEntityTypeID);
SET #ID = SCOPE_IDENTITY();
END;
RETURN 0;
END;
GO
And I recommend declaring your return parameter as:
var returnparameter = new SqlParameter("#ID", SqlDbType.Int)
{
Direction = ParameterDirection.InputOutput
};
cmd.Parameters.Add(returnparameter);
Please, may you try to change your C# code with this updates bellow, and give us feed-back:
public int InsertFederalTax(int ClassificID, int appliesTo)
{
int tax_id = 0;
Sqlconn.Open();
SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ID", SqlDbType.Int);
cmd.Parameters["#ID"].Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("#TaxAuthorityID", 1);
cmd.Parameters.AddWithValue("#TaxClassificationID", ClassificID);
cmd.Parameters.AddWithValue("#EntityID", 0);
cmd.Parameters.AddWithValue("#AppliesTo_TaxEntityTypeID", appliesTo);
cmd.ExecuteNonQuery();
if(!(cmd.Parameters["#ID"].Value is DBNull))
{
tax_id = Convert.ToInt32(cmd.Parameters["#ID"].Value);
}
Sqlconn.Close();
return tax_id;
}
I am using following code for fetching customer details using Stored Procedure
public List<Customer> GetPacketReconciliation(int customerId, int size, DateTime billDate, ref DateTime lastRunDate)
{
List<Customer> getCustomer = new List<Customer>();
SqlParameter[] arParms = new SqlParameter[4];
arParms[0] = new SqlParameter("#Cust_ID", SqlDbType.Int);
arParms[0].Value = customerId;
arParms[1] = new SqlParameter("#Size", SqlDbType.Int);
arParms[1].Value = size;
arParms[2] = new SqlParameter("#Last_Run_Date", SqlDbType.DateTime);
arParms[2].Direction = ParameterDirection.InputOutput;
arParms[2].Value = lastRunDate;
arParms[3] = new SqlParameter("#Bill_Date", SqlDbType.DateTime);
arParms[3].Value = billDate;
using (SqlConnection sqlCon = new SqlConnection(this.GetConnectionString()))
{
sqlCon.Open();
using (SqlDataReader reader = SqlHelper.ExecuteReader(sqlCon, CommandType.StoredProcedure, "dbo.GetCustomer", arParms))
{
if (reader.HasRows)
{
getCustomer= MapToEntityCollection<Customer>(reader);
}
}
}
if (arParms[2].Value != DBNull.Value)
{
lastRunDate = Convert.ToDateTime(arParms[2].Value);
}
return getCustomer;
}
Store Procedure
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [dbo].[GetCustomer]
#Cust_ID SMALLINT,
#Size INT,
#Last_Run_Date DATETIME OUTPUT,
#Bill_Date DATETIME
AS
BEGIN
END
Here i am using one ref variable lastRunDate. When debugging i can see that lastdate value is setting properly in sqlparameter.But when i view it using sql profiler,i can see that lastRunDate is setting as null.if i hardcode it like arParms[2].Value = DateTime.Parse("2017-01-01") ,it works.Any issue with reference parameter ??
Anyone seeing any issue in this code ..
I have a stored procedure called SelFromWeather2 and I need to return values from table. When I perform syntax check I don't get errors, but when I call it from C# I get syntax error near SelFromWeather2.
Here is code:
CREATE PROCEDURE SelFromWeather2
#location VARCHAR(MAX),
#des VARCHAR(200) OUTPUT,
#min INT OUTPUT,
#max INT OUTPUT,
#humidity INT OUTPUT,
#pressure INT OUTPUT,
#speed INT OUTPUT,
#date Datetime OUTPUT
AS
IF EXISTS(SELECT * FROM Weather2 WHERE LOCATION LIKE #location)
BEGIN
CREATE TABLE T
(
forc XML,
loc VARCHAR(MAX),
dat Datetime
);
INSERT INTO T(forc, loc, dat) SELECT TOP 1 [FORECAST],[LOCATION],[DATE] FROM Weather2
WHERE LOCATION LIKE #location ORDER BY DATE DESC;
SET #location=(SELECT loc FROM T);
SET #location =(SELECT loc FROM T);
SET #des= (SELECT forc.value('(/Weather//Forecast/Description/node())[1]', 'nvarchar(max)') FROM T);
SET #min= (SELECT forc.value('(/Weather//Forecast/MinTemp/node())[1]', 'int') FROM T);
SET #max=(SELECT forc.value('(/Weather//Forecast/MaxTemp/node())[1]', 'int') FROM T);
SET #humidity=(SELECT forc.value('(/Weather//Forecast/Humidity/node())[1]', 'int') FROM T);
SET #pressure= (SELECT forc.value('(/Weather//Forecast/Pressure/node())[1]', 'int') FROM T);
SET #speed=(SELECT forc.value('(/Weather//Forecast/Speed/node())[1]', 'int') FROM T);
SET #date= (SELECT forc.value('(/Weather//Forecast/Date/node())[1]', 'Datetime') FROM T);
DROP TABLE T;
END
The code for calling this procedure is:
string location = "Paris";
SqlDataReader myReader = null;
SqlCommand myComand = new SqlCommand("SelFromWeather2", myConnection);
myComand.Parameters.AddWithValue("#location", location);
SqlParameter min = myComand.Parameters.Add("#min", System.Data.SqlDbType.Int);
SqlParameter max = myComand.Parameters.Add("#max", System.Data.SqlDbType.Int);
SqlParameter humidity = myComand.Parameters.Add("#humidity", System.Data.SqlDbType.Int);
SqlParameter pressure = myComand.Parameters.Add("#pressure", System.Data.SqlDbType.Int);
SqlParameter speed = myComand.Parameters.Add("#speed", System.Data.SqlDbType.Int);
SqlParameter dat = myComand.Parameters.Add("#date", System.Data.SqlDbType.DateTime);
SqlParameter des = myComand.Parameters.Add("#des", System.Data.SqlDbType.VarChar, 200);
min.Direction = System.Data.ParameterDirection.Output;
max.Direction = System.Data.ParameterDirection.Output;
humidity.Direction = System.Data.ParameterDirection.Output;
pressure.Direction = System.Data.ParameterDirection.Output;
speed.Direction = System.Data.ParameterDirection.Output;
dat.Direction = System.Data.ParameterDirection.Output;
des.Direction = System.Data.ParameterDirection.Output;
myComand.ExecuteReader();
int minTemp = (int)min.Value;
int maxTemp = (int)max.Value;
int hum = (int)humidity.Value;
int press = (int)pressure.Value;
int wind = (int)speed.Value;
string description = des.Value.ToString();
DateTime datum = (DateTime)dat.Value;
Please help, I'm stuck!
Set CommandType of myCommand to StoredProcedure
You need to set the CommandType to StoredProcedure
myCommand.CommandType = CommandType.StoredProcedure
The default is Text.
I have a DataGridView for editing a table. The following code is using to update the table.
using (SqlConnection con = new SqlConnection("...."))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter("select * from T", con);
SqlCommandBuilder cb = new SqlCommandBuilder(da);
cb.ConflictOption = ConflictOption.OverwriteChanges;
da.UpdateCommand = cb.GetUpdateCommand();
// da.UpdateCommand.CommandText = "exec sp1 #p1, #p2, #p3...";
da.InsertCommand = cb.GetInsertCommand();
da.DeleteCommand = cb.GetDeleteCommand();
da.Update(datatable.GetChanges());
}
I found that da.Update(datatable.GetChanges()) smartly generates minimal set clause according to the modified columns.
update T set c1 = #p1 where K = #p2 -- If only c1 is changed in the grid
update T set c1 = #p1, c2 = #p2 where K = #p3 -- if both c1 and c2 is changed
update T set c4 = #p1 where K = #p2 -- if only c4 is changed
......
How to write the stored procedure for the CommandText?
You will want to create a stored procedure on the server that receives the parameters. The method you are using is for generating SQL and does not use stored procedures, it sends SQL thru the connection to the server. If I named the sproc UpdateSomeUserTable:
oleDbCommand1.CommandText = "UpdateSomeUserTable";
oleDbCommand1.CommandType = System.Data.CommandType.StoredProcedure;
oleDbCommand1.Parameters["us_id"].Value = "668987";
oleDbCommand1.Parameters["us_lname"].Value = "White";
oleDbCommand1.Parameters["us_fname"].Value = "Johnson";
oleDbConnection1.Open();
oleDbCommand1.ExecuteNonQuery();
oleDbConnection1.Close();
This is a code smelling, I do not advise use, but it works.
dataAdapter.RowUpdating += (sender, e) =>
{
if (e.Command != null && !string.IsNullOrEmpty(e.Command.CommandText))
{
e.Command.CommandText = $"";
}
};
I have error 'Error converting data type nvarchar to decimal'
when call stored procedure call another stored procedure from C# as
cmd = new SqlCommand("tax_Base_emp", con);
cmd.CommandType = CommandType.StoredProcedure;
parm1 = new SqlParameter("#emp_code", SqlDbType.BigInt);
parm1.Value = emp_code;
parm1.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm1);
parm2 = new SqlParameter("#co_id", SqlDbType.BigInt);
parm2.Value = Settings.Default.comp_id;
parm2.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm2);
parm3 = new SqlParameter("#d", SqlDbType.DateTime);
parm3.Value = Convert.ToDateTime("31/1/2010");
parm3.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm3);
parm4 = new SqlParameter("#y", SqlDbType.Int);
parm4.Value =int.Parse(textBox2.Text);
parm4.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm4);
parm5 = new SqlParameter("#check_month", SqlDbType.Int);
parm5.Value =1;
parm5.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm5);
parm6 = new SqlParameter("#month", SqlDbType.Int);
parm6.Value =8;
parm6.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm6);
SqlParameter parm7 = new SqlParameter("#indate", SqlDbType.DateTime);
parm7.Value = Convert.ToDateTime("8/5/2010");
parm7.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm7);
SqlParameter parm8 = new SqlParameter("#Sumtotal", SqlDbType.Decimal);
parm8.Scale = 2;
parm8.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parm8);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
decimal tax_value = Convert.ToDecimal(cmd.Parameters["#Sumtotal"].Value);
And the stored proecdure called:
ALTER PROCEDURE Tax_Base_emp
#emp_code bigint,
#co_id bigint,
#d datetime,
#y int,
#check_month int,
#month int,
#indate datetime,
#Sumtotal decimal(8,2) output
AS
declare #tax_main_sal decimal(8,2)
declare #tax_var_sal decimal(8,2)
declare #salary decimal(8,2)
declare #insh_varsalary decimal(8,2)
declare #insh_value decimal(8,2)
declare #vacation_value decimal(8,2)
declare #vacation_varsalary decimal(8,2)
declare #ded_value decimal(8,2)
declare #ben_value decimal(8,2)
exec Taxable_mainsalary #emp_code,#co_id,#tax_main_sal output
exec taxable_varsalary #emp_code,#co_id, #tax_var_sal output
----taxableSalary---------------
set #salary=#tax_main_sal+#tax_var_sal
----insurance-------------------
exec varsalary_insh #emp_code,#co_id,#d,#y, #insh_varsalary output
exec insh_no #emp_code,#co_id,#insh_varsalary,#check_month, #insh_value output
----vacation--------------------
exec vacation_varsalary #emp_code,#co_id,#vacation_varsalary output
exec vacation_value #emp_code,#co_id,#y,#month,#vacation_varsalary,output
---------deduction---------------
exec deduction_for_tax #emp_code,#co_id,#indate,#ded_value output
-------------benifit------------
exec benfit_for_tax #emp_code,#co_id,#indate,#ben_value output
-----------------------------------NetSalary--------------------------------------------------------
set #Sumtotal=(isnull(#salary,0)+isnull(#ben_value,0))-(isnull(#insh_value,0)+isnull(#vacation_value,0)+isnull(#ded_value,0))
return
I don't see anything wrong with your C# code - it's really hard to tell what would be causing the problem. Your C# code is just simply calling a single stored proc - that shouldn't be a problem, really.
However, I do have a few recommendations for your coding style:
put your SqlConnection and SqlCommand into using(....) { .... } blocks to make your code more reliable
try to avoid specifying default property values, like Direction = ParameterDirection.Input; over and over again; the .Input is the default - only specify it when you deviate from that default
if you do the same steps over and over and over again - why don't you put this in a method and call that method a couple of times?? This also saves you from having to create a gazillion of SqlParameter objects that you then just throw away .....
You'd end up with something like:
public void CallStoredProc()
{
using(SqlConnection con = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand("tax_Base_emp", con))
{
cmd.CommandType = CommandType.StoredProcedure;
AddParameter(cmd.Parameters, "#emp_code", SqlDbType.BigInt, emp_code);
AddParameter(cmd.Parameters, "#co_id", SqlDbType.BigInt, comp_id);
AddParameter(cmd.Parameters, "#d", SqlDbType.DateTime, Convert.ToDateTime("31/1/2010"));
AddParameter(cmd.Parameters, "#y", SqlDbType.Int, int.Parse(textBox2.Text));
AddParameter(cmd.Parameters, "#check_month", SqlDbType.Int, 1);
AddParameter(cmd.Parameters, "#month", SqlDbType.Int, 8);
AddParameter(cmd.Parameters, "#indate", SqlDbType.DateTime, Convert.ToDateTime("8/5/2010"));
AddOutputParameter(cmd.Parameters, "#Sumtotal", SqlDbType.Decimal, 8, 2);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
decimal tax_value = Convert.ToDecimal(cmd.Parameters["#Sumtotal"].Value);
}
}
public void AddParameter(SqlParameterCollection params, string name, SqlDbType type, object value)
{
SqlParameter tmpParam = new SqlParameter(name, type);
tmpParam.Value = value;
params.Add(tmpParam);
}
public void AddOutputParameter(SqlParameterCollection params, string name, SqlDbType type, int precision, int scale)
{
SqlParameter tmpParam = new SqlParameter(name, type);
tmpParam.ParameterDirection = Direction.Output;
tmpParam.Precision = precision;
tmpParam.Scale = scale;
params.Add(tmpParam);
}
I can't see anything in the code you have posted that would cause that.
I suspect that the error is in one of the 8 stored procedures you are calling where you are assigning an nvarchar to a decimal.
I'd comment these all out temporarily and just return a dummy number if that fixes it uncomment half and try again. If the error reoccurs then you know it is in one of the ones you just uncommented. i.e. do a binary search to find the offending procedure.