2010-04-23 11 views
15

Czy istnieje metoda programowo (w języku T-SQL) pobieranie maksymalnej (i minimalnej) wartości typu danych? Że zachowuje się jak float.MaxValue w języku C#.Uzyskiwanie maksymalnej wartości float w SQL programowo

chciałbym użyć go w jakimś wyborem, gdy parametr nie równa wszelkie rzeczywiste wartości w bazie danych, więc chciałbym użyć czegoś jak

declare @min float 
declare @max float 
--fill @min and @max, can be null if undefined 
select * from foo 
    where bar between isnull(@min,0) and isnull(@max,max(float)/*magic*/) 

Odpowiedz

21

Choć nie wydaje się być dowolny sposób inline aby uzyskać min lub wartości max, there's a solution somebody put together:

CREATE TABLE datatype_extrema 
    (min_bit bit NOT NULL DEFAULT (0) CHECK (min_Bit=0) 
    ,max_bit   AS CAST(0x1 AS bit) 
    ,min_tinyint  AS CAST(0x00 AS tinyint) 
    ,max_tinyint  AS CAST(0xFF AS tinyint) 
    ,min_smallint  AS CAST(0x8000 AS smallint) 
    ,max_smallint  AS CAST(0x7FFF AS smallint) 
    ,min_int   AS CAST(0x80000000 AS int) 
    ,max_int   AS CAST(0x7FFFFFFF AS int) 
    ,min_bigint  AS CAST(0x8000000000000000 AS bigint) 
    ,max_bigint  AS CAST(0x7FFFFFFFFFFFFFFF AS bigint) 
    ,min_smalldatetime AS CAST('19000101 00:00' AS smalldatetime) 
    ,max_smalldatetime AS CAST('20790606 23:59' AS smalldatetime) 
    ,min_datetime  AS CAST('17530101 00:00:00.000' AS datetime) 
    ,max_datetime  AS CAST('99991231 23:59:59.997' AS datetime) 
) 
    INSERT INTO datatype_extrema DEFAULT VALUES 
    GO 
    CREATE TRIGGER nochange_datatype_extrema 
    ON datatype_extrema INSTEAD OF INSERT, UPDATE, DELETE 
    AS BEGIN 
    RAISERROR ('No changes allowed for table datatype_extrema.', 16, 1) 
    ROLLBACK TRANSACTION 
    END 
    GO 

po tym, można albo skopiować maksymalną wartość do zmiennej lokalnej lub (przy użyciu zapytań) przekroju dołączyć do tej tabeli.

Declare @max_int int 
    Set @max_int=(SELECT max_int FROM datatype_extrema) 
    IF COALESCE(@FirstInt, @max_int) < COALESCE(@SecondInt, 0) 
11

Oto domyślne dla pływaka i prawdziwego typu (że brakuje w przyjętym odpowiedź):

select 
    CAST('-1.79E+308' AS float) as MinFloat, 
    CAST('1.79E+308' AS float) as MaxFloat, 
    CAST('-3.40E+38' AS real) as MinReal, 
    CAST('3.40E+38' AS real) as MaxReal 

Niestety, nie jest możliwe, aby przekształcić je z varbinary, ale varchar działa bez problemy.

1

Na float i realmin i maks wartości mogą być obliczane z wykorzystaniem POWER funkcję:

SELECT 
    max_float = (1 + (POWER(2e0, 52) - 1)/POWER(2e0, 52)) * POWER(2e0, 1023) 
    , min_float = -(1 + (POWER(2e0, 52) - 1)/POWER(2e0, 52)) * POWER(2e0, 1023) 
    , max_real = CAST((1 + (POWER(2e0,23)-1)/POWER(2e0,23)) * POWER(2e0,127) AS real) 
    , min_real = CAST(-(1 + (POWER(2e0,23)-1)/POWER(2e0,23)) * POWER(2e0,127) AS real) 

i są to wartości po przecinku:

SELECT 
    max_float = 1.7976931348623158E+308 
    , min_float = -1.7976931348623158E+308 
    , max_real = 3.4028234E+38 
    , min_real = -3.4028234E+38 
1
1.79769313486231580799909999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 

ten jest maksymalną liczbą pływak wartość

Oto jak można go dostać:

DECLARE @decimal_length int = 0 
DECLARE @decimal_value varchar(max) = '1.79' 
DECLARE @decimal_value_buffer varchar(max) = @decimal_value 
DECLARE @new_int varchar(10) = '9' 
DECLARE @dummy float 
WHILE @decimal_length < 308 
BEGIN 

    SET @decimal_value = @decimal_value + @new_int 

    BEGIN TRY 
     SET @dummy = CAST(@decimal_value + 'E+308' AS float) 
     SET @decimal_length = @decimal_length + 1 
     SET @decimal_value_buffer = @decimal_value 
     SET @new_int = '9' 
    END TRY 
    BEGIN CATCH 
     SET @decimal_value = @decimal_value_buffer 
     SET @new_int = @new_int - 1 
    END CATCH 
END 

PRINT @decimal_value 
+0

To jest wyjątkowa! – Tigerjz32

+0

Pytanie OP polegało bardziej na programowym sposobie uzyskania maksymalnej wartości typu float. –

+0

Dodałem metodę brutalnej siły identyfikującą, kiedy float zgłasza błąd. – Kyle

Powiązane problemy