i have created a function:
CREATE FUNCTION FindDistrictId (#param XML)
RETURNS INT
(...)
which i want to use in a stored procedure like that:
CREATE PROCEDURE UpdateDistinctID
AS
UPDATE Notices SET DistinctId = FindDistrictId(Notices.XmlContent)
WHERE DistinctId = 0
I get 'FIndDistrictId is not a recognized built-in function name' when i try to do that. I thought that maybe i can't do Set field = function() but then i checked here and i think it should work.. any idea why it's not? The function is created for sure im my db, i checked sys.object
You need to include the schema (owner if this is SQL 2000 or earlier) of the function on the call. By default, that would be dbo.
UPDATE Notices SET DistinctId = dbo.FindDistrictId(Notices.XmlContent)
WHERE DistinctId = 0
Related
This question already has answers here:
Alter a SQL server function to accept new optional parameter
(3 answers)
Closed 4 years ago.
I have a stored procedure that looks like this:
CREATE FUNCTION [my_schema].[isEligible]
(#product NUMERIC(8))
RETURNS INT
AS
BEGIN
DECLARE #result INT;
/* do eligibility checking, setting #result */
RETURN #result;
END;
This is referenced in several existing queries similar to this:
SELECT *
FROM person
WHERE my_schema.isEligible(?) > -1 -- negative numbers are eligibility error codes
Where ? is the parameter for a given product id.
In one of the several queries that call the function, I need to pass in a new additional parameter, #exception. I want to have the function behave by default like it did before, and only change behavior for the one call that will be passing in a value for #exception, so I have added the new parameter like so:
CREATE FUNCTION [my_schema].[isEligible]
(#product NUMERIC(8),
#exception CHAR(1) = 'N')
RETURNS INT
AS
BEGIN
DECLARE #result INT;
/*
do eligibility checking (conditionally accounting for
#exception being 'Y'), and setting #result
*/
RETURN #result;
END;
But when I deploy the new version of the function and run a query which only passes in #product I'm getting An insufficient number of arguments were supplied for the procedure or function [my_schema].[isEligible]. I thought that adding = 'N' would provide a default value and avoid this issue.
I read here that sometimes this generic sounding error is actually hiding other errors which aren't allowed to bubble up, but I don't know if that's the case, since it's talking about procedures and this is a function. Not sure if there's a difference or if functions don't support optional arguments like procedures.
I'd love to not have to pass in NULL for the new parameter if possible, which would simplify the rollout of the updated version of the function. Is there a way to do call this function both like isEligible(?) and isEligible(?, ?) or do I need the first one to be isEligible(?, NULL) for it to work?
You could call your function as:
SELECT *
FROM person
WHERE my_schema.isEligible(?, default) > -1
and:
SELECT *
FROM person
WHERE my_schema.isEligible(?, value) > -1
Given:
In the original post I was attempting to call db.Database.ExecuteCommand, since then I changed that to what you see here. (Which works). Execute Command was always returning 0xfffff. SQLQuery returns the value of the last select statement or the rows inserted depending on how you code it up.
using (db=new MyEntites())
{
var inserted = db.Database.SqlQuery<decimal>(query,parms}
}
Where last two lines in query are:
SET NOCOUNT OFF
Select SCOPE_IDENTITY() AS newID
From the documentation for ExecuteSqlCommand method, the return value is
The result returned by the database after executing the command.
This means you need to RETURN the value in your procedure, not as a result set. So do this in your stored procedure as the last command:
RETURN SCOPE_IDENTITY()
Thanks to your suggestions, Step 1 put something like this in the query string as last select:
Select SCOPE_IDENTITY() as TESTID;
Then use this EF form of SQLQuery, the type of decimal is what is returned for the select example above.
using (db=new MyEntites())
{
var identity = db.Database.SqlQuery<decimal>(query,parms}
}
I am trying to get some value in output parameters using SqlCommand Parameters.
The stored procedure runs fine, giving proper records. I verified it executing procedure on Sql Server as well to be sure I am doing it right.
Still, I'm not able to get output on server-side, it always comes nothing! While debugging, I see that IsDirty proeprty for command.Parameters is set to True.
Can anyone tell what does it indicate?
Here is some code :
command.Parameters.Add("#count", SqlDbType.Int).Value = initialCountValue
command.Parameters("#count").Direction = ParameterDirection.Output
Dim dr = command.ExecuteReader()
newCountValue = Convert.ToInt32(command.Parameters("#count").Value)
Here is procedure example:
CREATE PROCEDURE [dbo].[usp_some_procedure]
#filter INT
#count INT output
AS
BEGIN
DECLARE #filtered_ids TABLE(row_num INT IDENTITY(1,1), id INT primary key)
INSERT INTO #filtered_ids ( id )
SELECT id
FROM dbo.some_table
WHERE #filter = 0 OR table_field = #filter
ORDER BY id desc
SELECT #count = COUNT(*)
FROM #filtered_ids
SELECT some_table.*
FROM some_table
INNER JOIN #filtered_ids
ON some_table.id = #filtered_ids.id
END
Output parameters are not visible to the calling code while the reader is opened.
Close the reader that you opened with ExecuteReader, then read your value:
Using dr = command.ExecuteReader()
...
End Using
newCountValue = CInt(command.Parameters("#count").Value)
SqlCommand.Parameters is an instance of SqlParameterCollection. SqlParameterCollection does not have a publicly available member called IsDirty. If you are seeing one in your command.Parameters then it is not an instance of SqlParameterCollection which means that command isn't an instance of SqlCommand.
I did find what appears to be a decompiled version of the SqlParameterCollection class that seems to have an internal member called IsDirty, but you should not have access to this.
It seems to me that you are doing something weird here and it's entirely possible that is the cause of your problem. I would add the default System.Data.SqlClient namespace and see if that resolves your problem.
It might help to post more of your code including where you are getting your SqlCommand class from.
Using Simple.Data, I would like to get the result from an output parameter in a stored procedure. Let's say I have the following SP (disregard the uselessness of it):
CREATE PROCEDURE [dbo].[TestProc]
#InParam int,
#OutParam int OUTPUT
AS
BEGIN
SELECT #OutParam = #InParam * 10
END
When I call it with Simple.Data, I use the following code.
var db = Database.Open();
int outParam;
var result = db.TestProc(42, out outParam);
Console.WriteLine(outParam); // <-- == 0
Console.WriteLine(result.OutputValues["OutParam"]); // <-- == 420
It feels like outParam should contain the value, and not the OutputValues dictionary. So my question is: Is there a nicer way to get the result from OutParam in this particular case?
Unfortunately, out parameters are not supported by the dynamic binding infrastructure used by Simple.Data, as they are not supported in all CLR languages.
I am open to suggestions for better syntax, though.
Well I've been using Model-First with DbSet code generation. And now I what I want to do is to add some stored procedures.
But Code I get look like like:
public virtual ObjectResult<Nullable<int>> CountPostsInThread(Nullable<int> threadID, ObjectParameter postCount)
{
var threadIDParameter = threadID.HasValue ?
new ObjectParameter("threadID", threadID) :
new ObjectParameter("threadID", typeof(int));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<int>>("CountPostsInThread", threadIDParameter, postCount);
}
Now, how Do I get rid off all those ?
It's something wrong with tt files, or with my stored procedure ?
SP:
ALTER PROCEDURE dbo.sp_CountPostsInThread
(
#threadID int,
#PostCount int = 0 OUTPUT
)
AS
SELECT COUNT(*)
FROM PostSet
WHERE PostSet.ThreadID = #threadID
Nothing is wrong with the template or stored procedure. SP's parameters accept NULL value so because of that EF makes them nullable. The ternary operator is used because if you pass null EF must somehow pass the type of null parameter to correctly setup SqlParameter used internally.