Reputation: 4938
I am working on an order management web project in C# which can be provided to multiple clients.
In 'orders' table, I have a field 'Qty' of 4 decimals. Now not all clients may require 4 decimal places, so I have a table 'Config' which holds this value in field 'QtyDecimal'.
Presently what I am doing to show the correct number of decimals is something like this:
string xQtyDec = getQtyDecimalFromConfig();
sqlCommand = "Select CAST(Qty as numeric(18," + xQtyDec + ")) [Quantity] from orders";
...
I was wondering if this could be accomplished in SQL itself, something like
SELECT CAST(Qty as numeric(18, (SELECT QtyDecimal FROM config))) [Quantity] from orders
Is this possible?
Upvotes: 0
Views: 2338
Reputation: 35613
The best option is not to do this, but rather to do it in C# at the point where you convert the dataset for display or download. However if you need to do it in SQL you can use one of these approaches.
Approach 1:
Select CAST(CASE (select xQtyDecimal from Config)
WHEN 1 then CAST(FieldName as NUMERIC(10,1)
WHEN 2 then CAST(FieldName as NUMERIC(10,2)
WHEN 3 then CAST(FieldName as NUMERIC(10,3)
WHEN 4 then CAST(FieldName as NUMERIC(10,4)
WHEN 5 then CAST(FieldName as NUMERIC(10,5)
ELSE FieldName END AS NUMERIC(10,6)) As FieldNameAlias
From TableName
Approach 2:
SELECT CAST(CAST(FieldName * POWER(10, (select xQtyDec from config)) as BIGINT) AS NUMERIC(20,10))/POWER(10, (select xQtyDec from config))
FROM TableName
Upvotes: 0
Reputation: 5031
In SQL Server,you need to build a dynamic query to achieve the result.
DECLARE @Scale NVARCHAR(50)
SELECT @scale= QtyDecimal FROM config
DECLARE @sql NVARCHAR(500)='SELECT CAST(Qty as numeric(18, ' +@scale+')) [Quantity] from orders'
EXEC (@sql)
Upvotes: 1
Reputation: 22811
According to Sql sever syntax , see https://msdn.microsoft.com/en-us/library/ms174979.aspx data type parameters (precision and scale) must be literals. They couldn't be expressions. You'd better do things like that on client side. Alternatively use round(), cast result to max possible scale (4) and strip extra zeroes from string representation
declare @s int = 2; -- scale config parameter, = 0..4
select t.col, substring(calc.v, 1, len(calc.v) -(4-@s))
from (--- sample data
values (12345.06789)
, (8765000.1)
) t(col)
cross apply (
select v = cast(cast(round(col, @s) as numeric (18,4)) as varchar(20))
) calc
Upvotes: 1
Reputation: 314
Yes, that is possible, but you should rewrite your query as:
SELECT CAST(orders.Qty as numeric(18, (config.QtyDecimal))) AS [Quantity] from orders, config
WHERE {some selection on config table to get the correct QtyDecimal}
Upvotes: 0