Return two decimal points in create function - sql

I have here an sql create function that will return float datatype.
I would like to know if how am I going to show the results to two decimal points.
ALTER FUNCTION [dbo].[udf_get_total]
(
-- Add the parameters for the function here
#code as int
)
RETURNS FLOAT
AS
BEGIN
-- Declare the return variable here
DECLARE #quantity as FLOAT
DECLARE #price as FLOAT
-- Add the T-SQL statements to compute the return value here
SET #quantity = (SELECT quantity FROM Requested_Item where Code_id = #code)
SET #price = (SELECT price FROM Requested_Item where Code_id = #code)
-- Return the result of the function
RETURN #quantity * #price
END
The sample results:
1632.1740985705144
6323.8092596543638

Use CAST
select cast(float_column as decimal(10,2))
from your_table
decimal(10,2) will display 10 digits before the point and 2 after it.

First of all. I'd rewrite your function. You're querying your table twice. This can be done by running a single SELECT statement. See this code:
ALTER FUNCTION [dbo].[udf_get_total]
(
#code AS INT
)
RETURNS FLOAT
AS
BEGIN
-- Declare the return variable here
DECLARE #quantity AS FLOAT
, #price AS FLOAT;
SELECT #quantity = quantity, #price = price
FROM Requested_Item
WHERE Code_id = #code;
-- Return the result of the function
RETURN #quantity * #price;
END
Now how to format your numbers properly? I used this method with CEILING and a bit of maths:
DECLARE #first FLOAT = 1632.1740985705144
, #second FLOAT = 6323.8092596543638;
SELECT FLOOR(#first * 100) / 100
, FLOOR(#second * 100) / 100;
It brings requested result:
╔═════════╦════════╗
║ 1632.17 ║ 6323.8 ║
╚═════════╩════════╝

Try this:
RETURN TRUNCATE(#quantity * #price, 2)
The 2 at the end means there will be 2 decimal points. You can really use the TRUNCATE function anywhere - the only downside is that it doesn't really round the numbers.

I only changed the return statement of my function to
RETURN CAST ((#total / #cur_amount) as decimal(10,2))
and it shows the 2 decimal points.

Related

Scalar-valued function returning NULL

I have the below function, and for the life of me, I cannot get it to return a value, I get NULL every time.
I am calling it via select [dbo].[getFiatProfit](600.26,'GBP', 1000.99,'BTC') as op
What am I missing?
/****** Object: UserDefinedFunction [dbo].[getFiatProfit] Script Date: 06/07/2022 11:42:26 ******/
ALTER FUNCTION [dbo].[getFiatProfit] (
#fiatInvested float,
#fiatInvestedCurrency nvarchar,
#quantity float,
#currency nvarchar
)
RETURNS float
AS
BEGIN
declare #tmp float
declare #result float
declare #usdtgbp float
IF (#fiatInvestedCurrency = 'USD')
BEGIN
select #tmp = [dbo].[usdtPairs].[Value] from [dbo].[usdtPairs] where usdtPairs.ID = #currency;
select #usdtgbp = [dbo].[usdtPairs].[Value] from [dbo].[usdtPairs] where usdtPairs.ID = 'GBP';
set #result = (((#quantity * #tmp) - #fiatInvested) / #usdtgbp);
-- set #result = #quantity * #tmp;
END
ELSE
BEGIN
select #tmp = [dbo].[usdtPairs].[Value] from [dbo].[usdtPairs] where usdtPairs.ID = #currency;
set #result = ((#quantity * #tmp) - #fiatInvested);
-- set #result = #quantity * #tmp;
END
return (#result)
END
Your issue looks it's because your parameters are declared without a length. nvarchar defaults to a length of 1 in a lot of circumstances, so it's simply the wrong value being received. A much better data type would be char(3) which is fixed length, given that all currencies have exact three-letter names.
You should also convert this function into a Table Valued Function, which is likely to perform far better.
CREATE OR ALTER FUNCTION dbo.getFiatProfit (
#fiatInvested float,
#fiatInvestedCurrency char(3),
#quantity float,
#currency char(3)
)
RETURNS TABLE
AS RETURN
SELECT
result = ((#quantity * u.Value) - #fiatInvested)
/ (CASE WHEN #fiatInvestedCurrency = 'USD'
THEN 1
ELSE
(SELECT u2.Value FROM dbo.usdtPairs u2 WHERE u2.ID = 'GBP')
END)
FROM dbo.usdtPairs u
WHERE u.ID = #currency;
You use it like this
SELECT t.*, fp.*
FROM YourTable t
CROSS APPLY dbo.getFiatProfit(t.fiatInvested, t.fiatInvestedCurrency, t.Qty, 'GBP') fp;

conversion from nvarchar to numeric fails

I am trying to execute this query but the following error is occurring:
Error converting data type nvarchar to numeric
this is my query :
Select Top 20 *,dbo.GetDistance(35.5,33.8, Longitude, Latitude) as Distance
From ViewBranchCoordinates
order by Distance desc
if i remove this line order by Distance desc the query run normally with no error
this is the function GetDistance
ALTER FUNCTION [dbo].[GetDistance]
(
-- Add the parameters for the function here
#Long decimal(30,24), #Lat decimal(30,24), #Long2 decimal(30,24), #Lat2 decimal(30,24)
)
--decimal(8,6), #Long)
RETURNS decimal(38,28)
AS
BEGIN
-- Declare the return variable here
DECLARE #Distance decimal(38,28)
DECLARE #valueOne decimal(30,24)
DECLARE #valueTwo decimal(30,24)
DECLARE #dLat decimal(30,24)
DECLARE #dLng decimal(30,24)
DECLARE #SectionOne decimal(30,24)
DECLARE #SectionTwo decimal(30,24)
Select #dLat = RADIANS(#Lat - #Lat2)
Select #dLng = RADIANS(#Long - #Long2)
Select #SectionOne = square(sin((#dLat)/2))
Select #SectionTwo = cos(RADIANS(#Lat)) * cos(RADIANS(#Lat2)) * square(sin(#dLng / 2))
Select #valueOne =CONVERT(decimal(30,24),#SectionOne + #SectionTwo)
Select #valueTwo = 2 * ATN2(SQRT(#valueOne), SQRT(1 - #valueOne))
Select #Distance = 6371000 * #valueTwo
RETURN #Distance
END
Any help please
I presume this will fail too?
Select Top 20 *
,dbo.GetDistance(35.5,33.8, cast (Longitude as decimal (30,24)), cast(Latitude as (30,24)) as Distance
From ViewBranchCoordinates
Your function expects data of a certain type. If your lat/long columns are nvarchar then non numeric data can be in those columns.
Search for problem data, e.g.
Select *
From ViewBranchCoordinates
Where try_cast (longitude as numeric) IS NULL
Then you need to fix the data.

SQL Server 2012 Money Data Type Issues

I am using this formula
(p.Price - i.Price) * q.Qty
in SQL Server 2012. There are p.Price values of 0 or null. The data type for the p.Price and i.Price is money, the q.Qty is int.
So, if the calculation is (0-10.00) * 50 = -500.00 (it's a negative number because it is product that are bought on a schedule) but I always get 0 or null as a result in my data table.
Update :
(sum(p.Price - i.Price) * q.Qty)
but I am getting an invalid in the select list because it is not contained in either an aggregate or the group by clause ?
In SQL Server money type can be negative. It has this range:
-922,337,203,685,477.5808 to 922,337,203,685,477.5807
Check your data and formula, it should be working as expected:
DECLARE #m1 money = 0;
DECLARE #m2 money = 10;
DECLARE #qty int = 50;
SELECT (#m1 - #m2) * #qty
Result
(No column name)
-500.00
If the values can be NULL, you can use ISNULL to turn them into zeros:
DECLARE #m1 money = NULL;
DECLARE #m2 money = 10;
DECLARE #qty int = 50;
SELECT (ISNULL(#m1,0) - ISNULL(#m2, 0)) * ISNULL(#qty, 0)
Result
(No column name)
-500.00

Concatenate Two double precisions into a string in sql server 2008 function

I have a Question regarding a Transact SQL Function.
What I need is to combine two INT values into a VARCHAR value. E.g. Lower Limit = '5', Upper Limit = '15'
My result should be "5 - 15"
Table looks like this:
ID Lower Limit Upper Limit
1 5 15
2 3 19
etc.
Code is like this so far.. All that there is left is to combine the two results:
Any help would be greatly appreciated !
CREATE FUNCTION [dbo].[GiveMeTheRange] (#argID INT)
RETURNS VARCHAR
AS
BEGIN
DECLARE #Range VARCHAR;
DECLARE #LowerLimit DOUBLE PRECISION;
DECLARE #UpperLimit DOUBLE PRECISION;
SELECT #LowerLimit = [Lower Limit]
FROM T_VormFactorKlassen
WHERE (ID = (#argID)
SELECT #UpperLimit = [Upper Limit]
FROM T_VormFactorKlassen
WHERE (ID = (#argID)
-- concattenate(#LowerLimit ' - ' #UpperLimit) <----That ain't workin'
RETURN #VormFactorKlasseNaam ;
END
Thanks
Try this:
SET #VormFactorKlasseNaam = CAST(#LowerLimit as varchar(5)) + ' - ' +
cast(#UpperLimit as varchar(5))
You really should avoid doing this kind of stuff with scalar functions. That said, this should work:
CREATE FUNCTION [dbo].[GiveMeTheRange] (#argID INT)
RETURNS VARCHAR(23) -- Always specify the length of the VARCHAR
AS
BEGIN
DECLARE #Range VARCHAR(23);
DECLARE #LowerLimit DOUBLE PRECISION;
DECLARE #UpperLimit DOUBLE PRECISION;
SELECT #LowerLimit = [Lower Limit]
FROM T_VormFactorKlassen
WHERE ID = (#argID)
SELECT #UpperLimit = [Upper Limit]
FROM T_VormFactorKlassen
WHERE ID = (#argID)
-- concattenate(#LowerLimit ' - ' #UpperLimit) <----That ain't workin'
SET #Range = CAST(#LowerLimit AS VARCHAR(10)) + ' - ' +
CAST(#UpperLimit AS VARCHAR(10))
RETURN #Range;
END

how to truncate a number in sybase ASE?

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1540/doc/html/san1278453173757.html
The functions TRUNCATE and TRUNCNUM are not supported in Adaptive Server Enterprise.
Does anyone know another way of doing this in ASE?
Thanks
I know these ways:
select Number = floor ( 455.443 )
select Number = cast ( 455.443 as int )
select Number = convert ( int, 455.443 )
select Number = 455.443 - ( 455.443 % 1 )
How about using the Floor function? It essentially does the same thing, and is supported in ASE.
This is an old question, but I did this a few days ago to mimic the "truncnum" function described in the link above.
create function custom_truncnum(#numberToTruncate float, #decimalPlaces int)
returns float
AS
declare #tenToTheXPower float;
declare #leftSideOfDecimal float;
declare #returnVal float;
set #tenToTheXPower = power(10, ABS(#decimalPlaces);
set #leftSideOfDecimal = FLOOR(#numberToTruncate);
if (#decimalPlaces <= 0)
set #returnVal = FLOOR(#numberToTruncate / #tenToTheXPower) * #tenToTheXPower;
else
set #returnVal = #leftSideOfDecimal + (FLOOR(#numberToTruncate - #leftSideOfDecimal) * #tenToTheXPower) / #tenToTheXPower);
return #returnVal;
GO
Now you should be able to do this in Sybase ASE:
SELECT dbo.custom_truncnum(345.567, 2)
345.56
SELECT dbo.custom_truncnum(345.562, 2)
345.56
SELECT dbo.custom_truncnum(345.567, -1)
340
SELECT dbo.custom_truncnum(345.567, -2)
300
SELECT dbo.custom_truncnum(345.567, 0) --This is the same as FLOOR(345.567)
345