Jones Joseph
Jones Joseph

Reputation: 4938

Using SELECT in CAST function of SQL

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

Answers (4)

Ben
Ben

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
  • Pro: Control behaviour in each case exactly
  • Con: Each case must be written out.

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
  • Pro: Any number of decimal places can be coped with
  • Con: Rounds down, can't control e.g. banker's rounding.

Upvotes: 0

Unnikrishnan R
Unnikrishnan R

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

Serg
Serg

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

Frits
Frits

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

Related Questions