1

数値列の比較で正しい結果が得られないという奇妙な問題があります。入力は同じですが、coalesce() 関数が適用されると、突然一致する行がなくなります。

テーブルは次のように定義されます。

CREATE TABLE orders
(
    orderid        INT NOT NULL,
    freight        NUMERIC,
    PRIMARY KEY (orderid),
);

私はこの方法でクエリをテストしています:

private void Problematic(IDbConnection connection)
{
    using (var cmd = session.Connection.CreateCommand())
    {
        cmd.CommandText =
            @"select order0_.OrderId as OrderId55_,
                     order0_.Freight as Freight55_,
              from
                    Orders order0_
              where
                    coalesce(order0_.Freight, @p0) > @p1";  // ALT 1
                 // order0_.Freight > @p1";                 // ALT 2

        var p0 = cmd.CreateParameter();
        p0.ParameterName = "p0";
        p0.DbType = DbType.Decimal;
        p0.Value = 100;
        cmd.Parameters.Add(p0);

        var p1 = cmd.CreateParameter();
        p1.ParameterName = "p1";
        p1.DbType = DbType.Decimal;
        p1.Value = 0;
        cmd.Parameters.Add(p1);

        using (var reader = cmd.ExecuteReader())
        {
            // ALT 1 above yields 0 result rows.
            // ALT 2 above yields 830 result rows.
        }
    }
}

Freight列は null 可能ですが、実際の値はすべて null ではなく、0 より大きい値です。したがって、2 つのクエリが同じ数の一致する行を生成すると予想されます。

私はこのクエリで型を分析しています:

select
    typeof(@p0),
    typeof(@p1),
    typeof(coalesce(order0_.Freight, @p0)),
    typeof(order0_.Freight),
    coalesce(order0_.Freight, @p0) > @p1,
    order0_.Freight > @p1
from
    Orders order0_

結果 (すべての行) は次のとおりです。

    typeof(@p0)                              => text
    typeof(@p1)                              => text 
    typeof(coalesce(order0_.Freight, @p0))   => real
    typeof(order0_.Freight)                  => real
    coalesce(order0_.Freight, @p0) > @p1     => 0
    order0_.Freight > @p1                    => 1

異なる式が異なる結果を生成する理由を誰か説明できますか?

4

1 に答える 1

0

どうやら、データベース ドライバーDBType.Decimalはテキストに変換されます。

DBType.Double代わりに使用してください。

于 2013-03-18T08:04:40.463 に答える