Get Output parameter and Dataset from Stored Procedure using Entity Framework - entity-framework

I'm trying to call the stored procedure attached below using Entity Framework 4.1 to cover 2 possible scenarios:
exec TEST_SP_OUTPUT 1
Should return a dataset from ACTIONTYPE table and #Success = 1
exec TEST_SP_OUTPUT 0
No dataset returned and #Success = 0
CREATE PROCEDURE [dbo].[TEST_SP_OUTPUT]
(
#Id int,
#Success int OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF (#Id = 1)
BEGIN
SELECT ActionName, ActionType FROM ACTIONTYPE
SET #Success = 1;
END
ELSE
SET #Success = 0;
END
The question is: can I handle both executions using a single Complex Type within the Entity Framework model?
Bear in mind that the scenario "exec TEST_SP_OUTPUT 0" is not returning any dataset or columns.
Correct me if I'm wrong, but I a possible solution may be setting dummy results for the second scenario:
CREATE PROCEDURE [dbo].[TEST_SP_OUTPUT]
(
#Id int,
#Success int OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF (#Id = 1)
BEGIN
SELECT ActionName, ActionType FROM ACTIONTYPE
SET #Success = 1;
END
ELSE
BEGIN
SELECT '' as ActionName, '' as ActionType
SET #Success = 0;
END
END
Cheers.
Juan.

Related

Stored procedure returns nullable int

In my procedure i am returning a int value.
ALTER PROCEDURE [dbo].[GetValue]
-- Add the parameters for the stored procedure here
#ID int,
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
DECLARE #isNew int
SET #isNew=0
DECLARE #returnedValue int
DECLARE #output int
SET #returnedValue=[dbo].fn_GetIsNewLecturer(#ID)
IF(#returnedValue=0)
BEGIN
PRINT 'new'
EXEC #output=[dbo].[GetNew] #ID
SELECT #output
END
ELSE
BEGIN
PRINT 'old'
EXEC #output=[dbo].[sp_GetOld] #ID
SELECT #output
END
RETURN #output
END
it return value should be int. But it returns Nullable int?. how to change it as int
Try this:
select [Output] = isnull(#output, 0)
Here's why it should work:
declare #i int
select ni = #i, nni = isnull(#i,0)
into #t
select is_nullable, *
from tempdb.sys.columns
where [object_id] = object_id(N'tempdb..#t')
drop table #t

Mapping Stored Procedure doesn't return one string

I am trying to map the following stored procedure in Entity Framework. It clearly should return one string but I cannot get it to do so. When I do a Function Import, it maps to the choice return a collection of scalar string. If I set it to None, it just returns a int. Is it the SP? Is there no support for select stored procedures?
ALTER PROCEDURE [dbo].[getCurrentConnection]
#registrationID VARCHAR(100)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT TOP 1 ConnectionGUID FROM clientconnection WHERE registrationid = #registrationID ORDER BY created desc
END
The generated code does:
public virtual ObjectResult<string> SPgetCurrentConnection(string registrationID)
{
var registrationIDParameter = registrationID != null ?
new ObjectParameter("registrationID", registrationID) :
new ObjectParameter("registrationID", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("SPgetCurrentConnection", registrationIDParameter);
}
I also can't delete the SP from my model and start again. I don't see it on the designer. It only lets me modify and that gives the Prefix SP in front of it
Solved by modifying the SP to return an Output parameter.
ALTER PROCEDURE [dbo].[getCurrentConnection]
#registrationID VARCHAR(100),
#connectionID varchar(100) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #connectionID = (SELECT TOP 1 ConnectionGUID FROM clientconnection WHERE registrationid = #registrationID ORDER BY created DESC)
END
Then writing the function in code:
public string GetCurrentConnection(string accountId)
{
using (savitasEntities2 db = new savitasEntities2())
{
string cid = String.Empty;
ObjectParameter connectionId = new ObjectParameter("connectionID", typeof(string));
db.GetCurrentConnection(accountId, connectionId);
return connectionId.Value.ToString();
}
}

TSQL - How to iterate a list of strings

I want to create a procedure that will insert all my jobs to the DB.
(a. All my jobs have equal characteristics. b. SSDT doesn't support jobs code management)
Now, I thought to create a script to insert all of them and as a c# developer I thought I need to initialize a list with their names.
I discovered while googling that the way to do it is with an in memory table and the best I could come with is this.
declare #jobsNames table(Id int, JobName nvarchar(100))
insert into #jobsNames (Id,JobName)
select 1,'JobName1' union
select 2,'JobName2' union
......
BEGIN TRANSACTION
DECLARE JobsCursor CURSOR FOR SELECT JobName FROM #jobsNames
OPEN JobsCursor
FETCH NEXT FROM JobsCursor INTO #JobName
WHILE ##Fetch_status = 0
BEGIN
.. do stuff
FETCH NEXT FROM JobsCursor INTO #JobName
WHILE ##Fetch_status = 0
END
COMMIT TRANSACTION
Question -
Is this the shortest/recommended way?
(It seems a hellotof code for a foreach)
declare #jobNames table(Id int, JobName nvarchar(100))
insert #jobNames values
(1, 'JobName1'),
(2, 'JobName2'),
--
(10, 'JobName10')
while exists(select 1 from #jobNames)
begin
declare #id int, #name nvarchar(100)
select top 1 #id = Id, #name = JobName from #jobNames
delete from #jobNames where Id = #Id
-- Do stuff here
end
Personally I avoid Cursors like the plague. Please make sure that you HAVE to iterate instead of doing your work set based. They don't call it RBAR for nothing.
DECLARE #counter INT, #max INT
SELECT #counter = 1, #max = max(id)
FROM #jobsNames
WHILE #counter <= #max
BEGIN
SELECT #val1 = val1 ... FROM #jobNames where ID = #counter
-- .. do stuff
SET #counter = #counter + 1
END

Invalid Object Error on Insert after read of same table

I am trying to insert data into a table based off what is already in the table. I read the table to get the number of records inserted for a certian month and then insert information based off if it is more or less than ten. After I read the table it throws an invalid object name when I try to do that insert. It's not an invalid object as it just read the table. If this is a permissions error how do I correct it? My code is below. Thanks,
Jason
declare #email VARCHAR(75),
#seminarNumber INT,
#isValidEmail BIT,
#monthlyTotal INT,
#statusCode INT
set #email = 'email#domain.com'
set #seminarNumber = '12345'
set #isValidEmail = dbo.RegexMatch('^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$',#email)
if #isValidEmail = 1
begin
SELECT #monthlyTotal = count(mailid)
from Email_Tracking
where emailaddress = #email
and year(datesent) = year(getdate())
and month(datesent) = month(getdate())
if #monthlyTotal > 10
begin
set #statusCode = 1
end
else
begin
set #statusCode = 2
end
end
else
begin
set #statusCode = 3
end
if #statusCode = 1
begin
insert Email_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Maximum surveys for the month have already been sent')
end
else if #statusCode = 2
begin
insert Email_Tracking ('seminarNumber','email','datesent')
values(#seminarNumber,#email,getdate())
end
else if #statusCode = 3
begin
insertEmail_Tracking ('seminarNumber','email','reasonNotSent')
values(#seminarNumber,#email,'Email address missing or invalid')
end
print #statusCode
try removing quotes from column names. so for eg:
insert Email_Tracking (seminarNumber,email,reasonNotSent)
values(#seminarNumber,#email,'Email address missing or invalid')

Getting value from stored procedure in another stored procedure

Sorry, lots of code coming up..
I saw another question like this that used output parameters. I'm using the RETURN statement to return the value I want to use.
I have one stored procedure InsertMessage that looks like this:
ALTER PROCEDURE dbo.InsertNewMessage
(
#messageText text,
#dateTime DATETIME,
#byEmail bit,
#bySMS bit
)
AS
DECLARE #NewId int
BEGIN
BEGIN TRANSACTION
INSERT INTO MessageSet VALUES (#byEmail, #bySMS, #dateTime, #messageText)
SET #NewId = SCOPE_IDENTITY()
COMMIT
END
RETURN #NewId
which another stored procedure uses:
ALTER PROCEDURE dbo.InsertMessageFromUserToGroup
(
#userEmail nvarchar(256),
#groupId int,
#messageText text,
#bySMS bit,
#byEmail bit
)
AS
--Inserts a new message to a group
DECLARE #messageId int
DECLARE #dateTime DATETIME = GETDATE()
--First check if user is a part of the group
IF NOT EXISTS (SELECT userEmail FROM UserToGroupSet WHERE userEmail = #userEmail AND groupId = #groupId)
RETURN 'User not part of group'
ELSE --User is a part of the group, add message
BEGIN
BEGIN TRANSACTION
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
INSERT INTO MessageToUser VALUES(#userEmail, #messageId)
INSERT INTO MessageToGroup VALUES(#messageId, #groupId)
COMMIT
END
The row that causes the trouble and of which I'm unsure how to handle is this one:
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
The syntax seems ok because I can save it. When I run it I get the error message:
Running [dbo].[InsertMessageFromUserToGroup] ( #userEmail = test#test.com, #groupId = 5, #messageText = sdfsdf, #bySMS = false, #byEmail = true ).
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.InsertNewMessage", or the name is ambiguous.
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
No rows affected.
(0 row(s) returned)
#RETURN_VALUE =
Finished running [dbo].[InsertMessageFromUserToGroup].
It seems as if the other stored procedure can't be found. I've tried different ways of calling the procedure but everything else fails as well. Any suggestions?
Try changing
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS,
#byEmail)
to
EXEC #messageId = [dbo].[InsertNewMessage] #messageText, #dateTime, #bySMS,
#byEmail
Notice that SET has been changed to EXEC, and the parentheses have been removed from the parameters.
See the example in the MSDN documenation at the end of the article for more information.