I'm still trying to learn an SQL, i made a mistakes but i already search on the internet about the if statements...
I tried to create a simple function to check if the parameter is match the condition..
I have 2 parameters, that will be inputted manually by the users, but i got an error saying
Msg 156, Level 15, State 1, Procedure ufn_calculatebonus, Line 4 [Batch Start Line 1] Incorrect syntax near the keyword 'IF'. Msg 178, Level 15, State 1, Procedure ufn_calculatebonus, Line 10 [Batch Start Line 1] A RETURN statement with a return value cannot be used in this context.
This is the code i've tried to create, i thought i make the IF condition right? After the IF , should have a BEGIN and statements, closing it with END. ??
CREATE FUNCTION Sales.ufn_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
RETURNS TABLE
AS
IF #CompanyRevenue > 10
BEGIN
SELECT 'INPUT CANNOT BE BIGGER THAN 1000'
END
ELSE
BEGIN
RETURN
(
SELECT * FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter
);
END
GO
There are 2 distinct types of T-SQL table-valued functions, inline TVF and multi-statement TVF. The body of an inline TVF consists of only of a RETURNS statement with a query specification (not to be confused with a RETURN statement).
Your attempt at a multi-statement table-valued function is invalid for the reasons below.
The body of a multi-statement TVF must be surrounded with BEGIN...END.
A table variable with the returned schema must be declared in the function header.
One cannot return query results with a RETURN statement. Instead, insert results into the table variable declared in the function header end specify RETURN at the end of the function to return the results.
Below is an example of the remediated code. Importantly, note the use of an explicit column list throughout. Don't SELECT * in production code.
CREATE OR ALTER FUNCTION dbo.ufn_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
RETURNS #BalanceInfo TABLE (CustomerID int, Balance int, ErrorMessage varchar(100))
AS
BEGIN
IF #CompanyRevenue > 10
BEGIN
INSERT INTO #BalanceInfo (ErrorMessage) VALUES('INPUT CANNOT BE BIGGER THAN 1000');
END
ELSE
BEGIN
INSERT INTO #BalanceInfo (CustomerID, Balance) --note ErrorMessage is omitted and will be NULL
SELECT CustomerID, Balance FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter;
END;
RETURN;
END
GO
A stored procedure is a better fit than a than user-defined function if you need to raise custom errors for parameter validation. Here's a stored procedure example:
CREATE OR ALTER PROCEDURE dbo.usp_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
AS
IF #CompanyRevenue > 10
BEGIN
THROW 50000, 'INPUT CANNOT BE BIGGER THAN 1000', 16;
END;
SELECT CustomerID, Balance FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter;
GO
Related
Hi I have one doubt in snowflake
how to use variable result in the next sselect session.
I want stored one statement result in variable and that variable result need to call another statment in snowflake server .
use schema test.public;
create or replace procedure empresult()
returns table ()
language sql
as
$$
set empresult=(select deptid from TEST.PUBLIC.DEPT where deptid=10)
declare res resultset(
select * from emp where deptno in ($empresult)
)
begin
return table(res);
end;
$$;
above statment getting error.
Syntax error: unexpected 'declare'. (line 4)
please tell me how to write stored procedure query to call the one statment result into another session select statment task.
The sample code is missing colons and the correct syntax for variables.
One possible fix that works:
create or replace procedure empresult()
returns table ()
language sql
as
$$
declare
empresult integer;
begin
select deptid into :empresult from DEPT where deptid=10;
let res resultset := (select * from emp where deptno = :empresult);
return table(res);
end;
$$;
call empresult();
Staging data:
create temp table dept as select 10 deptid;
create temp table emp as select 'a' a, 'b' b, 10 deptno;
I'm trying to create the function in SQL Server. In this function I have generated the random number, but function not generated.
Create function [GetRandomNumber]
(
)
RETURNS bigint
as
Begin
Declare #randomNo int
set #randomNo = (select round(rand(checksum(newid()))*(10001)+50000,0) as [GetRandomNumber])
return #randomNo
End
this is generated in following error:
Invalid use of a side-effecting operator 'newid' within a function.
Msg 443, Level 16, State 1, Procedure GetRandomNumber, Line 8
Invalid use of a side-effecting operator 'rand' within a function.
You can. However, it will require a little bit of extra legwork.
First, you need to create a view, like the one below:
create view dbo.sys_NDF
as
select rand() as [ValueRand], newid() as [ValueGUID],
rand(checksum(newid())) as [SeededRand];
go
The trick is that you cannot call these system functions directly from your UDF, however you can query a view that returns their values. You can later expand it with other functions / columns if need be.
As such, your function starts to look like the following:
Create function [GetRandomNumber]()
RETURNS bigint as begin
return (select round(v.SeededRand * 10001 + 50000, 0) from dbo.sys_NDF v);
end;
go
Create SP instead of function. Because some system function are not allowed in user defined function.
CREATE PROCEDURE [GetRandomNumber]
as
Begin
Declare #randomNo int
set #randomNo = (select round(rand(checksum(newid()))*(10001)+50000,0) as [GetRandomNumber])
return #randomNo
End
GO
DECLARE #returnvalue INT
EXEC #returnvalue = GetRandomNumber
SELECT #returnvalue
When exactly do we use stored procedures with output parameters and when do we use stored procedures without parameters?
I base my question on an example:
Stored procedure with output parameter
CREATE PROCEDURE uspGetContactsCountByCity
#City nvarchar(60),
#ContactsCount int OUT
AS
BEGIN
SELECT #ContactsCount = COUNT(ContactID)
FROM Contacts
WHERE City = #City
END
Stored procedure executing
DECLARE #ContactsTotal INT
EXEC uspGetContactsCountByCity #ContactsCount = #ContactsTotal OUT, #city = 'Berlin'
SELECT #ContactsTotal
Results: 2
Stored procedure without output parameter
CREATE PROCEDURE uspGetContactsCountByCity2
#City nvarchar(60)
AS
BEGIN
SELECT COUNT(ContactID)
FROM Contacts
WHERE City = #City
END
Stored procedure executing:
EXEC uspGetContactsCountByCity2 #city = 'Berlin'
Results: 2
Both procedures return the same result, in same form, so what's the difference?
Basically, the result you're seeing is actually the result of your SELECT at the end of the procedure, which is doing the same thing.
Please take a look at this documentation:
If you specify the OUTPUT keyword for a parameter in the procedure definition, the stored procedure can return the current value of the parameter to the calling program when the stored procedure exits. To save the value of the parameter in a variable that can be used in the calling program, the calling program must use the OUTPUT keyword when executing the stored procedure.
So basically if you would like your stored procedure to just return just a value instead of a data set, you could use the output parameter. For example, let's take the procedures you have given as an example. They both do the same thing, this is why you got the same result. But what about changing a little bit in the first procedure that has the output parameter.
Here's an example:
create table OutputParameter (
ParaName varchar(100)
)
insert into OutputParameter values ('one'), ('two'),('three'),('one')
CREATE PROCEDURE AllDataAndCountWhereOne
#name nvarchar(60),
#count int OUT
as
Begin
SELECT #count = COUNT(*) from OutputParameter
Where ParaName = #name
select Distinct(ParaName) from OutputParameter
End
Declare #TotalCount int
Exec AllDataAndCountWhereOne #count = #TotalCount OUT, #name = 'One'
Select #TotalCount
With this example, you are getting all the distinct stored data in the table, plus getting the count of a given name.
ParaName
--------------------
one
three
two
(3 row(s) affected)
-----------
2
(1 row(s) affected)
This is one way of using the output parameter. You got both the distinct data and the count you wanted without doing extra query after getting the initial data set.
At the end, to answer your question:
Both procedures gives us the same result, in same form, so what's the difference?
You didn't make a difference in your own results, this is why you didn't really notice the difference.
Other Examples:
You could use the OUT parameter in other kinds of procedures. Let's assume that your stored procedure doesn't return anything, it's more like a command to the DB, but you still want a kind of message back, or more specifically a value. Take these two examples:
CREATE PROCEDURE InsertDbAndGetLastInsertedId
--This procedure will insert your name in the database, and return as output parameter the last inserted ID.
#name nvarchar(60),
#LastId int OUT
as
Begin
insert into OutputParameterWithId values (#name);
SELECT #LastId = SCOPE_IDENTITY()
End
or:
CREATE PROCEDURE InsertIntoDbUnlessSomeLogicFails
--This procedure will only insert into the db if name does exist, but there's no more than 5 of it
#name nvarchar(60),
#ErrorMessage varchar(100) OUT
as
Begin
set #ErrorMessage = ''
if ((select count(*) from OutputParameterWithId) = 0)
begin
set #ErrorMessage = 'Name Does Not Exist'
return
end
if ((select count(*) from OutputParameterWithId) = 5)
begin
set #ErrorMessage = 'Already have five'
return
end
insert into OutputParameterWithId values (#name);
End
These are just dummy examples, but just to make the idea more clear.
An example, based on yours would be if you introduced paging to the query.
So the result set is constrained to 10 items, and you use a total count out parameter to drive paging on a grid on screen.
Answer from ozz regarding paging does not make sense because there is no input param that implements a contraint on the number of records returned.
However, to answer the question... the results returned by these stored procedures are not the same. The first returns the record count of contacts in given city in the out param ContactsCount. While the count may also be recieved in the second implement through examining the reader.Rows.Count, the actual records are also made a available. In the first, no records are returned - only the count.
I am stuck with a very petty issue that I am unable to resolve.
CREATE FUNCTION dbo.fntblPsmHaendlerDailyCostsinfodump(#pDateString varchar(8), #HaendlerID int, #TableName varchar(100),#CountryID int)
RETURNS table
AS BEGIN
RETURN select top 10 * from tblcountry
END
GO
This is giving me an error -
'Incorrect syntax near begin'.
I am not able to identify why it is giving the error.
Correct syntax for inline UDF:
Inline user-defined functions follow these rules:
There is no function_body delimited by BEGIN and END.
The RETURN clause contains a single SELECT statement in parentheses.
CREATE FUNCTION dbo.fntblPsmHaendlerDailyCostsinfodump(
#pDateString varchar(8),
#HaendlerID int,
#TableName varchar(100),
#CountryID int)
RETURNS table
AS
RETURN (select top 10 * from tblcountry);
GO
BEGIN and END are necessary for multistatement UDFs.
Getting very annoyed with this simple query...
I need to add an offset to a varchar, if it's a number and do nothing is it is not.
For this reason I've created the following function in SQL-server.
I then extract the answer with:
select dbo.OffsetKPL("100",200)
However this does not work, I get the error
Msg 207, Level 16, State 1, Line 1
Invalid column name '100'.
The code for the function is as follows...
ALTER FUNCTION [dbo].[OffsetKPL](
#kpl varchar(20)
,#offset int = 0
)
RETURNS varchar(20)
AS
BEGIN
DECLARE #uitkomst varchar(20);
set #uitkomst = #kpl;
if not(#offset = 0) begin
if (IsNumeric(#uitkomst) = 1) begin
set #uitkomst = cast((cast(#kpl as int) + #offset) as varchar);
end;
end;
RETURN #uitkomst;
END
What's wrong? nowhere does it state that IsNumeric does not accept a variable.
Use single quotes for strings!
select dbo.OffsetKPL('100',200)
If you have QUOTED_IDENTIFIER on (the default) things in double quotes are expected to be object names.
isnumeric may not be what you need though as all kinds of unexpected things return 1 for this.
SELECT ISNUMERIC('$'), ISNUMERIC('.'),
ISNUMERIC('12d5'), ISNUMERIC(','), ISNUMERIC('1e1')
See IsNumeric() Broken? Only up to a point for some discussion on this point.