I have a below stored procedure with output parameter.
ALTER proc [dbo].[CRS_GetNewMessageCount]
#CaseId int,
#Type varchar(50),
#Location varchar(50),
#Count int out
as
begin
if #location='admin'
begin
if #type='consumer'
select #Count=(Select count(fdId) from tb_CRS_Messages where fdCaseId=#CaseId and fdIsConsumerType=1 and fdIsReadatAdmin=0)
else
select #Count=(Select count(fdId) from tb_CRS_Messages where fdCaseId=#CaseId and fdIsMemberType=1 and fdIsReadatAdmin=0)
end
else
begin
if #type='consumer'
select #Count=(Select count(fdId) from tb_CRS_Messages where fdCaseId=#CaseId and fdIsConsumerType=1 and fdIsReadatFront=0)
else
select #Count=(Select count(fdId) from tb_CRS_Messages where fdCaseId=#CaseId and fdIsMemberType=1 and fdIsReadatFront=0)
END
SELECT #Count
END
It is perfect working at SQL server see below output :
I am calling this stored procedure through Entity Framework :
using (DbContext db = new DbContext())
{
try
{
var NewMessage = new ObjectParameter("Count", typeof(int));
int returnValue = 0;
db.CRS_GetNewMessageCount(CaseId, type, location, NewMessage);
int.TryParse(NewMessage.Value.ToString(), out returnValue);
return returnValue;
}
catch { return 0; }
}
It gives null value in output parameter.
Please help.
Not sure whether it makes a difference, but did you try to use "typeof(Int32)" instead of "typeof(int)"? Also try NewMessage as ObjectParameter and not as var, maybe it makes a difference.
ObjectParameter NewMessage = new ObjectParameter("NewMessage ", typeof(Int32));
Did you try to run your stored procedure without parameters, means return #Count-variable with a value no matter what parameters you enter? Like this you can identify whether your input parameters are wrong (handed over by C#) or not.
Hope this helps How to: Execute a Query Using a Stored Procedure with In and Out Parameters
https://msdn.microsoft.com/en-us/library/bb896334(v=vs.100).aspx
Related
I'm trying to create a stored procedure to add or update a collection of object executed in c#, but not sure why it isn't executing correctly in c# while it works fine in sql.
I'm not sure how generate some useful error message to help with debugging either.
Any tip or pointer to guide me to the right direction is greatly appreciated.
Here's the sample code:
SQL script:
CREATE TYPE CodeList
AS TABLE
(
Code varchar(255) NOT NULL UNIQUE,
Name varchar(max) NOT NULL,
GeneratedDate date NULL
);
GO
PRINT 'Created CodeList Type';
GO
CREATE PROCEDURE AddOrUpdateCodes
#List AS CodeList READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE dbo.Code AS tgt
USING #List AS src
ON tgt.Code = src.Code
WHEN MATCHED THEN
UPDATE SET Name = src.Name, GeneratedDate = src.GeneratedDate
WHEN NOT MATCHED THEN
INSERT (Code, Name, GeneratedDate) VALUES (src.Code, src.Name, src.GeneratedDate);
END
GO
PRINT 'Created AddOrUpdateCodes Stored Procedure';
GO
DECLARE #List AS CodeList;
INSERT INTO #List (Code, Name, GeneratedDate) VALUES ('SQLTEST', 'SQLTEST', '2018-07-30')
EXEC AddOrUpdateCodes #List
GO
SELECT * FROM Symbol;
C# Code:
public int AddOrUpdateCodes(List<Code> codes)
{
using (var entity = new CodeEntities())
{
var dataTable = new DataTable("CodeList");
using (var reader = ObjectReader.Create(codes, "Code", "Name", "GeneratedDate"))
{
dataTable.Load(reader);
}
var sqlParameter = new SqlParameter("#List", dataTable);
sqlParameter.SqlDbType = SqlDbType.Structured;
sqlParameter.TypeName = "dbo.CodeList";
var result = entity.Database.ExecuteSqlCommand("AddOrUpdateCodes",
sqlParameter);
entity.SaveChanges();
return result;
}
}
The DbContext.Database.ExecuteSqlCommand() method helps to executes the given DDL/DML command against the database. Try using this line passing SqlParameters:
var result = entity.Database.ExecuteSqlCommand("AddOrUpdateCodes #List",
sqlParameter);
entity.SaveChanges();
return result;
I'm a beginner at C#. I can't call a stored procedure.
My stored procedure is this:
CREATE PROCEDURE USP_login
#us VARCHAR(20),
#pwd VARCHAR(20)
AS
BEGIN TRAN
BEGIN TRY
SELECT *
FROM dbo.KhachHang
WHERE tenDangNhap = #us AND matKhau = #pwd
END TRY
BEGIN CATCH
ROLLBACK TRAN
RETURN 0
END CATCH
COMMIT TRAN
RETURN 1
GO
In my C# code, I use this function to call the USP_login stored procedure but it doesn't work:
public bool loginStored(string us, string pwd)
{
object[] sqlParams =
{
new SqlParameter ("#userName", us),
new SqlParameter ("#passWord", pwd),
};
var rs = db.Database.SqlQuery<bool>("USP_login #userName, #passWord", sqlParams).SingleOrDefault();
return rs;
}
Error message in screenshot:
Looks like SELECT * ... is returning more than just a single bool. (Based on the query, clearly the table has at least two fields, tenDangNhap and matKhau.) But that's what you told the code to expect:
db.Database.SqlQuery<bool>(/.../)
Either select only the column you want:
SELECT SomeBooleanValue FROM dbo.KhachHang WHERE tenDangNhap=#us AND matKhau=#pwd
Or specify the correct type that can be expected for each record (which may be a custom class that you need to define):
db.Database.SqlQuery<SomeObjectType>(/.../)
have a stored Procedure that do some operation and return 1 or 0 as below.
CREATE PROCEDURE dbo.UserCheckUsername11
(
#Username nvarchar(50)
)
AS
BEGIN
SET NOCOUNT ON;
IF Exists(SELECT UserID FROM User WHERE username =#Username)
return 1
ELSE
return 0
END
Using linq I tried to get return value. But i am getting the output as -1 always.
Below is my Linq code :
using (PlanGenEntities3 entity2 = new PlanGenEntities3())
{
var result = entity2.Entity_test_GetHoliday();
string output = result.ToString();
}
How to solve this ?
Just declare your scalar variable as a output parameter for SQL query, then in the code you could retrieve its value this way:
```
using (PlanGenEntities3 myContext = new PlanGenEntities3())
{
var outputParameter = new System.Data.Objects.ObjectParameter("OutputParameterName", typeof(int));
myContext.Entity_test_GetHoliday(outputParameter );
Console.WriteLine(outputParameter.Value);
}
```
I suppose there is way to access the default scalar output of your SP in the similar manor.
If he had it as an output parameter it would automatically show as a reference parameter of the proper corresponding data type in the LINQ call.
He wouldn't really need to create a parameter object to contain that.
alter procedure [dbo].[XXX]
(
#vendorworksationID uniqueidentifier ,
#sdate date,
#edate date,
#total int out
)
begin
select #total = COUNT(*)
from AdvertisedCampaignHistory a
where
CAST(a.CreationDate AS DATE) BETWEEN CAST(#sdate as DATE) AND CAST(#edate as DATE)
and a.CampaignID in (select cc.BCampaignID
from BeaconCampaign cc, VendorWorkStation vw
where cc.VendorWorkStationID = vw.VendorWorkStationID
and VendorID = #vendorworksationID)
return #total
end
The above code shows the stored procedure that return an integer value from SQL Server
ObjectParameter Output = new ObjectParameter("total", typeof(Int32));
var resBC = this.Context.getTotalSentBeaconCampaign(VendorWorkstationID, sdate,edate,Output).FirstOrDefault();
The above code shows how I am passing parameters and retrieving the value on the C# side
While running the code I am getting following error
The data reader returned by the store data provider does not have
enough columns for the query requested.
What could be the possible cause for this error?
Entity Framework cannot support Stored Procedure Return scalar values out of the box.To get this to work with Entity Framework, you need to use "Select" instead of "Return" to return back the value.
More Ref : http://www.devtoolshed.com/using-stored-procedures-entity-framework-scalar-return-values
My stored procedure is working correctly. However, I am not able to retrieve it.
My current function to retrieve the value from the stored procedure is:
public static int GetCsStatus()
{
using (Entities db = new Entities())
{
System.Data.Objects.ObjectParameter s = new System.Data.Objects.ObjectParameter("Status", typeof(int));
int r = db.proc_CsStatus(120, s);//.ToString());
return r;
}
}
I don't mind if this is changed or not used at all. I am currently getting a "r" value of -1 when I am expecting a 0 or 1.
Here is my stored procedure:
USE [DATABASE_CS]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_CsStatus]
-- Add the parameters for the stored procedure here
#TimeLimit Int,
#Status Int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Declare variables.
DECLARE #LastUpdate Int
-- Calculate the LastUpdate.
SELECT #LastUpdate = DATEDIFF(second, Timestamp, CURRENT_TIMESTAMP)
FROM Heartbeat
WHERE Id=1
-- Compare it to the TimeLimit.
IF #LastUpdate > #TimeLimit SELECT #Status = 0
ELSE SELECT #Status = 1
END
GO
Any input is much appreciated!!!
After executing your procedure, your the ObjectParameter s will contain the value. Your procedure call will not return it. The value you are looking for should be able to be found in s.Value.
Try the following:
public static int GetCsStatus()
{
using (Entities db = new Entities())
{
System.Data.Objects.ObjectParameter s = new System.Data.Objects.ObjectParameter("Status", typeof(int));
int r = db.proc_CsStatus(120, s);
return (int)s.Value;
}
}
The value which you are returning(r) is the number of rows affected by your procedure.
More Info:
Behind the scenes, your procedure is doing something along the lines of the following:
return base.ExecuteFunction("proc_CsStatus", input, output);
ObjectContext.ExecuteFunction() returns the number of rows affected by the call.