How to execute function in SQL Server 2008 - sql

I build a function and I am trying to execute it...but some errors are occurring
CREATE FUNCTION dbo.Afisho_rankimin(#emri_rest int)
RETURNS int
AS
BEGIN
Declare #rankimi int
Select #rankimi=dbo.RESTORANTET.Rankimi
From RESTORANTET
Where dbo.RESTORANTET.ID_Rest=#emri_rest
RETURN #rankimi
END
GO
SELECT dbo.Afisho_rankimin(5)AS Rankimi
GO
The errors when I execute it are:
Msg 2714, Level 16, State 3, Procedure Afisho_rankimin, Line 11
There is already an object named 'Afisho_rankimin' in the database.
and also it is said that:
Can not find column "dbo", or the user defined function, or aggregate "dbo.Afisho_rankimin", or the name is ambiguous

It looks like there's something else called Afisho_rankimin in your DB so the function is not being created. Try calling your function something else. E.g.
CREATE FUNCTION dbo.Afisho_rankimin1(#emri_rest int)
RETURNS int
AS
BEGIN
Declare #rankimi int
Select #rankimi=dbo.RESTORANTET.Rankimi
From RESTORANTET
Where dbo.RESTORANTET.ID_Rest=#emri_rest
RETURN #rankimi
END
GO
Note that you need to call this only once, not every time you call the function. After that try calling
SELECT dbo.Afisho_rankimin1(5) AS Rankimi

I have come to this question and the one below several times.
how to call scalar function in sql server 2008
Each time, I try entering the Function using the syntax shown here in SQL Server Management Studio, or SSMS, to see the results, and each time I get the errors.
For me, that is because my result set is in tabular data format. Therefore, to see the results in SSMS, I have to call it like this:
SELECT * FROM dbo.Afisho_rankimin_TABLE(5);
I understand that the author's question involved a scalar function, so this answer is only to help others who come to StackOverflow often when they have a problem with a query (like me).
I hope this helps others.

you may be create function before so,
update your function again using.
Alter FUNCTION dbo.Afisho_rankimin(#emri_rest int)
RETURNS int
AS
BEGIN
Declare #rankimi int
Select #rankimi=dbo.RESTORANTET.Rankimi
From RESTORANTET
Where dbo.RESTORANTET.ID_Rest=#emri_rest
RETURN #rankimi
END
GO
SELECT dbo.Afisho_rankimin(5) AS Rankimi
GO

Related

MSSQL Adding .ToString to datefields

i have some querys in my new SQL 2019 Database that connect to a table in a different database (MSSQL Server 2016) via linked servers.
But Everytime there is a date field in that query i get the error "The function or aggregat .ToString could not be found or the name is ambiguous".
I found that there is a hierarchy-ID-Function named "toString".
But i cant see why SQL should be using it when i dont call it to.
When i delete all Date fields from that query it executes without a problem.
SELECT * FROM [LinkedServerName].Databasename.integris.Tablename
EDIT:
I just noticed, that SQL somehow edits my text.
is what i wrote into the vieweditor.
is what the error shows me.
EDIT2: i set up the same linked server on an old SQL 2005 Server. Everything works fine. I guess because the 2005 server has no ToString() function... but im not sure.
I can construct a situation that would recreate the error, but I can't say for sure whether this is what is happening in your case. It's hard to demonstrate in a comment though, so I'll do as an answer.
Suppose we have a table t, with a computed column f, which references function dbo.f, which in turn references function dbo.g:
create function dbo.g() returns int as begin return 1 end;
go
create function dbo.f() returns int as begin return dbo.g(); end;
go
create table t(i int, f as dbo.f());
go
insert t(i) values (1);
select * from t;
go
So far so good. But now we drop function dbo.g and try to select from t:
drop function dbo.g;
select * from t;
This will result in the error: Cannot find either column "dbo" or the user-defined function or aggregate "dbo.g", or the name is ambiguous.
Look at the definition of the source table and check for computed columns, especially computed columns using nested constructs.

Using User Defined Functions For A Specific Database in SQL

How I can use a user defined function for a specific database (The use db statement is not working). Here are the images for the table and the query
I can't understand the errors which i am getting here.
Please someone help.
I have only a single table for now in my database
[The Query][2]
Use Lab6
Create function fetch_orders (#P_Customer_ID int)
Returns int
AS
Begin
Return (Select Count (Order_ID)
From Orders
Where Customer_ID = #P_Customer_ID)
End
You need a GO after a USE statement:
USE Lab6
GO
CREATE FUNCTION ...

Call User defined function as System Function in SQL server

I have created an user defined functions in SQL server. Is it possible to call these function in select statement, just like any other built-in function?
Create function [dbo].[TIME_TO_SEC](#inputTime time)
returns INT
As
Begin
DECLARE #secDiff INT = datediff(second, '00:00:00', #inputTime)
return #secDiff;
end
Currently calling this as below:
DECLARE #ret int;
EXEC TIME_TO_SEC #inputTime='01:00:00'
select #ret;
I am attempting something as simple as:
select TIME_TO_SEC('01:00:00') from TimeTable
Is it feasible in SQL-server?
It's possible, but you need to reference the function by the user's schema
select dbo.TIME_TO_SEC('01:00:00') from TimeTable
if you get an issue with your function, try to add "WITH EXECUTE AS CALLER"
Create function [dbo].[TIME_TO_SEC](#inputTime time)
Returns int
WITH EXECUTE AS CALLER
As
Begin
DECLARE #secDiff INT = datediff(second, '00:00:00', #inputTime)
return #secDiff;
end
then call the function with select
select dbo.[TIME_TO_SEC](getdate())
Yes, it's certainly feasible, and it looks like you've got everything you need already. Have you tried it?

Why am I getting this error? Must Declare Scalar Variable Error SQL Server 2008

I think I am trying to do something that is relatively straight forward, but keep getting the 'Must Declare Scalar Variable Error'. I have two variables:
DECLARE #CountOfThisCampaignSegment int
DECLARE #CountOfLastCampaignSegment int
select #CountOfThisCampaignSegment = COUNT(seg1) from #thisCampaignFinal
select #CountOfLastCampaignSegment = COUNT(seg1) from #lastCampaignFinal
I read that somewhere else that it seems I need to turn them into nvarchar, but I need to compare these two variables for an IF statement down the track in my procedure - so I am not sure if that would cause problems?
If anyone could give me some advice and background on why SQL Server throws this error, it would be greatly appreciated!
Many Thanks!
I suspect you actually have more than one batch in your script. Batches are separated by GO statements (by default) in SQL Server Management Studio.
Variables do not persist across batches. So this, for example, gives an error:
DECLARE #CountOfThisCampaignSegment int
DECLARE #CountOfLastCampaignSegment int
select #CountOfThisCampaignSegment = COUNT(seg1) from #thisCampaignFinal
select #CountOfLastCampaignSegment = COUNT(seg1) from #lastCampaignFinal
-- other statements
GO
-- this line fails with "must declare scalar variable":
select #CountOfThisCampaignSegment, #CountOfLastCampaignSegment

How to report an error from a SQL Server user-defined function

I'm writing a user-defined function in SQL Server 2008. I know that functions cannot raise errors in the usual way - if you try to include the RAISERROR statement SQL returns:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
But the fact is, the function takes some input, which may be invalid and, if it is, there is no meaningful value the function can return. What do I do then?
I could, of course, return NULL, but it would be difficult for any developer using the function to troubleshoot this. I could also cause a division by zero or something like that - this would generate an error message, but a misleading one. Is there any way I can have my own error message reported somehow?
You can use CAST to throw meaningful error:
create function dbo.throwError()
returns nvarchar(max)
as
begin
return cast('Error happened here.' as int);
end
Then Sql Server will show some help information:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Error happened here.' to data type int.
The usual trick is to force a divide by 0. This will raise an error and interrupt the current statement that is evaluating the function. If the developer or support person knows about this behavior, investigating and troubleshooting the problem is fairly easy as the division by 0 error is understood as a symptom of a different, unrelated problem.
As bad as this looks from any point of view, unfortunately the design of SQL functions at the moment allows no better choice. Using RAISERROR should absolutely be allowed in functions.
Following on from Vladimir Korolev's answer, the idiom to conditionally throw an error is
CREATE FUNCTION [dbo].[Throw]
(
#error NVARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
RETURN CAST(#error AS INT)
END
GO
DECLARE #error NVARCHAR(MAX)
DECLARE #bit BIT
IF `error condition` SET #error = 'My Error'
ELSE SET #error = '0'
SET #bit = [dbo].[Throw](#error)
I think the cleanest way is to just accept that the function can return NULL if invalid arguments are passed. As long is this is clearly documented then this should be okay?
-- =============================================
-- Author: AM
-- Create date: 03/02/2010
-- Description: Returns the appropriate exchange rate
-- based on the input parameters.
-- If the rate cannot be found, returns NULL
-- (RAISEERROR can't be used in UDFs)
-- =============================================
ALTER FUNCTION [dbo].[GetExchangeRate]
(
#CurrencyFrom char(3),
#CurrencyTo char(3),
#OnDate date
)
RETURNS decimal(18,4)
AS
BEGIN
DECLARE #ClosingRate as decimal(18,4)
SELECT TOP 1
#ClosingRate=ClosingRate
FROM
[FactCurrencyRate]
WHERE
FromCurrencyCode=#CurrencyFrom AND
ToCurrencyCode=#CurrencyTo AND
DateID=dbo.DateToIntegerKey(#OnDate)
RETURN #ClosingRate
END
GO
A few folks were asking about raising errors in Table-Valued functions, since you can't use "RETURN [invalid cast]" sort of things. Assigning the invalid cast to a variable works just as well.
CREATE FUNCTION fn()
RETURNS #T TABLE (Col CHAR)
AS
BEGIN
DECLARE #i INT = CAST('booooom!' AS INT)
RETURN
END
This results in:
Msg 245, Level 16, State 1, Line 14
Conversion failed when converting the varchar value 'booooom!' to data type int.
RAISEERROR or ##ERROR are not allowed in UDFs. Can you turn the UDF into a strored procedure?
From Erland Sommarskog's article Error Handling in SQL Server – a Background:
User-defined functions are usually
invoked as part of a SET, SELECT,
INSERT, UPDATE or DELETE statement.
What I have found is that if an error
appears in a multi-statement
table-valued function or in a scalar
function, the execution of the
function is aborted immediately, and
so is the statement the function is
part of. Execution continues on the
next line, unless the error aborted
the batch. In either case, ##error is
0. Thus, there is no way to detect that an error occurred in a function
from T-SQL.
The problem does not appear with
inline table-functions, since an
inline table-valued function is
basically a macro that the query
processor pastes into the query.
You can also execute scalar functions
with the EXEC statement. In this case,
execution continues if an error occurs
(unless it is a batch-aborting error).
##error is set, and you can check the
value of ##error within the function.
It can be problematic to communicate
the error to the caller though.
The top answer is generally best, but does not work for inline table valued functions.
MikeTeeVee gave a solution for this in his comment on the top answer, but it required use of an aggregate function like MAX, which did not work well for my circumstance.
I messed around with an alternate solution for the case where you need an inline table valued udf that returns something like select * instead of an aggregate. Sample code solving this particular case is below. As someone has already pointed out... "JEEZ wotta hack" :) I welcome any better solution for this case!
create table foo (
ID nvarchar(255),
Data nvarchar(255)
)
go
insert into foo (ID, Data) values ('Green Eggs', 'Ham')
go
create function dbo.GetFoo(#aID nvarchar(255)) returns table as return (
select *, 0 as CausesError from foo where ID = #aID
--error checking code is embedded within this union
--when the ID exists, this second selection is empty due to where clause at end
--when ID doesn't exist, invalid cast with case statement conditionally causes an error
--case statement is very hack-y, but this was the only way I could get the code to compile
--for an inline TVF
--simpler approaches were caught at compile time by SQL Server
union
select top 1 *, case
when ((select top 1 ID from foo where ID = #aID) = #aID) then 0
else 'Error in GetFoo() - ID "' + IsNull(#aID, 'null') + '" does not exist'
end
from foo where (not exists (select ID from foo where ID = #aID))
)
go
--this does not cause an error
select * from dbo.GetFoo('Green Eggs')
go
--this does cause an error
select * from dbo.GetFoo('Yellow Eggs')
go
drop function dbo.GetFoo
go
drop table foo
go
I can't comment under davec's answer regarding table valued function, but in my humble opinion this is easier solution:
CREATE FUNCTION dbo.ufn_test (#a TINYINT)
RETURNS #returns TABLE(Column1 VARCHAR(10), Value1 TINYINT)
BEGIN
IF #a>50 -- if #a > 50 - raise an error
BEGIN
INSERT INTO #returns (Column1, Value1)
VALUES('error','#a is bigger than 50!') -- reminder Value1 should be TINYINT
END
INSERT INTO #returns (Column1, Value1)
VALUES('Something',#a)
RETURN;
END
SELECT Column1, Value1 FROM dbo.ufn_test(1) -- this is okay
SELECT Column1, Value1 FROM dbo.ufn_test(51) -- this will raise an error
One way (a hack) is to have a function/stored procedure that performs an invalid action. For example, the following pseudo SQL
create procedure throw_error ( in err_msg varchar(255))
begin
insert into tbl_throw_error (id, msg) values (null, err_msg);
insert into tbl_throw_error (id, msg) values (null, err_msg);
end;
Where on the table tbl_throw_error, there is a unique constraint on the column err_msg. A side-effect of this (at least on MySQL), is that the value of err_msg is used as the description of the exception when it gets back up into the application level exception object.
I don't know if you can do something similar with SQL Server, but worth a shot.