1

I want to store values in certain units along with their corresponding conversions. So for example, there would be following columns

  1. DateTime
  2. Millimetres
  3. Centimetres
  4. Metres

For a given datetime, the user will provide me a value in any one of the units. So I will need to calculate the rest by myself. Is this better to implement using computed columns or views? I suppose if I am using views or computed columns, I will need to always provide one specific unit as input which I can do in code before inserting. Is their any other way and what is the best way to implement such requirement?

1 Answer 1

1

You should store any value using its ISO measure unit. Calculations and conversions should be done at the client side. Don't expect any performance gain over client side conversion when using computed columns.

As far as passing in data in any measure unit, I advise against that design: make the client pass in the data in the ISO measure unit and do any conversion on the client.

If you insist passing data in any unit, this is how an INSTEAD OF trigger could work:

CREATE TABLE length_values (
    id int PRIMARY KEY,
    length_m decimal(21,6)
)
GO

CREATE VIEW v_length_values
AS
SELECT 
    id,
    length_m,
    (length_m * 1000) AS length_mm,
    (length_m / 1000) AS length_km
FROM length_values;
GO


CREATE TRIGGER TR_length_values ON v_length_values
INSTEAD OF INSERT, UPDATE
AS
BEGIN

    SET NOCOUNT ON;

    MERGE INTO length_values AS trg
    USING INSERTED AS src
        ON trg.id = src.id
    WHEN MATCHED THEN
        UPDATE
        SET length_m = COALESCE(src.length_m, src.length_mm / 1000, src.length_km * 1000)
    WHEN NOT MATCHED THEN
        INSERT (id, length_m)
        VALUES (id, COALESCE(src.length_m, src.length_mm / 1000, src.length_km * 1000));

END

Some data to test:

INSERT INTO v_length_values (id, length_km) VALUES (1, 20);
INSERT INTO v_length_values (id, length_m) VALUES (2, 20);
INSERT INTO v_length_values (id, length_mm) VALUES (3, 1);

Results:

+----+--------------+-----------------+----------------+
| id |   length_m   |    length_mm    |   length_km    |
+----+--------------+-----------------+----------------+
|  1 | 20000.000000 | 20000000.000000 | 20.00000000000 |
|  2 | 20.000000    | 20000.000000    | 0.02000000000  |
|  3 | 0.001000     | 1.000000        | 0.00000100000  |
+----+--------------+-----------------+----------------+
4
  • What about using Views? Could it be useful? Are there any advantages in using Views for this? I think it will save space but I am not sure if that is a huge benefit considering space is cheap these days.
    – devSuper
    Commented Jun 15, 2015 at 10:15
  • Also, I am not sure if I can have an option for asking user to pass data in certain unit as sometimes users are not able to do that.
    – devSuper
    Commented Jun 15, 2015 at 10:17
  • Computed columns, unless persisted, do not use space: they're just a definition of how the column should be calculated. The calculation happens when the column is selected. With views you could achieve the "pass data in any unit" using an INSTEAD OF trigger to update the source table using the ISO unit. Actually, you could use the same techinque on a table with computed columns. The simplest solution is still forcing the client to pass the data in the correct unit. Commented Jun 15, 2015 at 10:24
  • @devSuper I added a view + trigger example Commented Jun 15, 2015 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.