0

我在不同的服务器上使用MySQLMSSQL,所以我需要学习如何以两种方式做到这一点。我有一个类型为varchar. 通常它会用integersand填充floats,但不时会用“See Notes”或类似的文字填充。我有一个查询生成器,因此用户可以将结果与数字进行比较。我可以将用户的输入从integersto转换为floatsSQL 句柄,这在测试时很好integersfloats,但只要它达到varchar.

更复杂的是,用户输入在查询构建器中,所以我不能只运行 2 个单独的查询来分解事情。所以我首先需要知道的是 SQL 是如何处理查询的。在 PHP 中,如果你有一个 if 语句,并且第一个条件失败,它将永远不会继续第二个条件。例如:if($_POST && $_POST['result'])代码不会尝试读取$_POST因为$_POST不存在的结果。

如果它的工作方式相同,那么我需要一些方法来测试结果是否为整数。如果是,那么它可以继续运行脚本。但我也不知道我该怎么做。像这样的东西:

SELECT *
FROM my_table
WHERE ISNUMERIC(result) = 1 AND result > 4.5

因此,如果 result 包含 a varchar,它将在到达之前终止,result > 4.5这样我就不会破坏我的陈述并得到错误。

谢谢。

4

3 回答 3

1

如果您使用的是 SQL Server,则上面的查询可以正常工作。不过,您可以尝试以下替代方法:

SELECT *
FROM my_table 
WHERE result > 
  CASE WHEN ISNUMERIC(result) = 1
  THEN '5'
  ELSE result
  END

这是两者的SQL Fiddle

如果您使用的是 MySQL,那么这似乎可行:

SELECT *
FROM my_table 
WHERE result > 5

还有SQL 小提琴

于 2013-01-11T00:31:24.340 回答
1

我会再看一下桌子的设计。通常,如果您大部分时间都需要存储数字,则将其存储在数字字段中。如果您需要存储文本,请将其存储在文本字段中。如果您需要同时存储两者,请考虑使用 2 个字段并使它们可以为空(然后用户只需要输入 1 个字段)

于 2013-01-11T20:17:13.423 回答
0

我发现拥有一个函数非常有用,该函数在给定文本输入的情况下将返回一个INT,如果无法解析该值,则返回 NULL 。然后你可以简单地查询

WHERE dbo.ParseInteger(result) >= 3

就我而言,我只对整数感兴趣,但我相信你可以扩展它以适应浮点数。这可能比您需要的更复杂;例如,如果你不关心指数,你可以扔掉 70%。我对 MySQL 太生疏了,无法提供翻译。最后,请注意,我假设的是英文风格的数字,您可能有不同的组和小数分隔符。

CREATE FUNCTION dbo.ParseInteger(@Input VARCHAR(100)) RETURNS BIGINT WITH SCHEMABINDING
AS BEGIN
    SET @Input = dbo.Trim(@Input)  -- If you're not worried about linebreaks or other odd chars, LTRIM(RTRIM(@Input)) will be fine
    IF ISNUMERIC(@Input) = 0 RETURN NULL
    IF @Input IN ('.', '+', '-', ',') RETURN NULL
    SET @Input = REPLACE(@Input, ',', '')  -- Strip commas

    DECLARE @DecimalPos INT = CHARINDEX('.', @Input)
    DECLARE @ExpPos     INT = CHARINDEX('E', @Input)
    DECLARE @IntValue   BIGINT
    IF @DecimalPos = 0 AND @ExpPos = 0
        BEGIN
        -- There's no decimal and no exponent, so we can easily cast this bog-standard integer
        SET @IntValue = CAST(@Input AS BIGINT)
        END
    ELSE IF @DecimalPos > 0 AND @ExpPos = 0
        BEGIN
        -- There's a decimal point but no exponent; we can cast the integer part, and then nudge it if necessary to round off the tenths place
        SET @IntValue = CAST(SUBSTRING(@Input, 1, @DecimalPos - 1) AS BIGINT)
        IF SUBSTRING(@Input, @DecimalPos + 1, 1) BETWEEN '5' AND '9'
            IF @IntValue < 0
                SET @IntValue -= 1
            ELSE
                SET @IntValue += 1
        END
    ELSE
        BEGIN
        -- There's an exponent, and probably a decimal; this will be relatively complicated
        IF @DecimalPos = 0
            BEGIN
            -- There's no decimal; insert one, just so we have consistency downstream
            SET @Input      = LEFT(@Input, @ExpPos - 1) + '.0E' + RIGHT(@Input, LEN(@Input) - @ExpPos)
            SET @DecimalPos = @ExpPos
            SET @ExpPos    += 2
            END

        DECLARE @Magnitude INT = CASE WHEN LEFT(@Input, 1) = '-' THEN @DecimalPos - 2 ELSE @DecimalPos - 1 END  -- For normalized scientific notation, this will always be one, but we can't expect that
        DECLARE @Exponent  INT = CAST(RIGHT(@Input, LEN(@Input) - @ExpPos) AS INT)
        IF @Exponent > 18 RETURN NULL  -- BIGINT can handle values up to 2^63, or 9.2E18

        SET @Input = REPLACE(SUBSTRING(@Input, 1, @ExpPos - 1), '.', '')

        DECLARE @MagAdjustment INT = @Magnitude + @Exponent - CASE WHEN LEFT(@Input, 1) = '-' THEN LEN(@Input) - 1 ELSE LEN(@Input) END

        IF @MagAdjustment > 0
            BEGIN
            SET @Input += REPLICATE('0', @MagAdjustment)
            END
        ELSE IF @MagAdjustment < 0
            BEGIN
            WHILE -@MagAdjustment > @Magnitude AND LEN(@Input) > 1
                BEGIN
                SET @MagAdjustment += 1
                SET @Input          = SUBSTRING(@Input, 1, LEN(@Input) - 1)
                END

                IF -@MagAdjustment > @Magnitude SET @Input = '0'
            ELSE IF -@MagAdjustment = @Magnitude SET @Input = CASE WHEN LEFT(@Input, 1) BETWEEN '5' AND '9' THEN '1' WHEN LEFT(@Input, 2) BETWEEN '-5' AND '-9' THEN '-1' ELSE '0' END
            ELSE                                 SET @Input = SUBSTRING(@Input, 1, CASE WHEN LEFT(@Input, 1) = '-' THEN 1 ELSE 0 END + LEN(@Input) + @MagAdjustment)
            END

        SET @IntValue = CAST(@Input AS BIGINT)
        END

    RETURN @IntValue
END
于 2013-01-11T00:08:34.437 回答