いくつかのプロジェクトでSQL Server用の再利用可能なデータアクセスレイヤーを作成しています。私は適切な方法を見つけることに問題があります.NETのdecimal
をクエリのパラメータとして渡します。最も明白な方法:10進数と文字列をSqlParameterとして渡す適切な方法
cmd.Parameters.AddWithValue("@P0", parameterValue);
はほとんどうまくいきます。値はDBに正しく格納されますが、SqlClientは実際の値から正確な型を推測します。したがって、アプリケーションが12345.678を渡すと、@ P0はNUMERIC(8,3)
と宣言されます。まったく同じクエリが他の値と一緒に使用されると、その値の精度と位取りが宣言されます。私には分かっていないが、SQL Serverではこれらのクエリは等しくなく、それぞれがsys.dm_exec_cached_plans
に別々のエントリを取得します。 string
とまったく同じ問題があります。長さごとに異なるクエリプランがあります。
いくつかのアプリケーションでは、1分あたりの記録が非常に大きく、それぞれが5〜10個の0〜の値を持っています(一部のセンサーデータ、通貨値)。ほとんどの各INSERT
は独自のクエリプランを取得し、数日後には、同じクエリプランの100,000以上のバージョンがキャッシュされ、数GB以上のRAMを使用しています。
私の考えは、すべての可能なタイプをいくつかの任意のタイプにまとめることです。 decimal
の場合、精度が20より低いときは20に設定します。精度が20より大きい場合は、実際の精度(たとえば24,28,32,36)よりも4で割り切れる最小値として設定します。スケール(最小2、次にステップ2)と文字列(最小128、次に2の累乗)についても同様です。この方法では問題を制御し続けるようです - 私は100kではなく各クエリで約100種類のバリアントプランを見てきましたが、SQL Serverはバッファプール用のメモリを使用しています。
この方法は間違っていますか? decimals
がロードされたSqlClientとクエリを使用しているときに、クエリプランキャッシュを管理下に保つためのより良い方法がありますか? - このDALの目的は、多くのDBMS(SQL Serverの、MS Accessの、Firebirdの、オラクル現時点では)ための抽象層を作成することですので、
- 使用ストアドプロシージャを:私が行うことができないものの
一覧。
- 私の仲間のチームメイトに、各変数の実際のタイプをどうにかして渡すように強制する - それは残酷なものだからです。
- ゴミ箱このDALは、昔ながらのDbProviderFactoryを使用して、それが1990年代のようなパラメータを作成 - このDALはまた、などのSQL方言、DB構造の作成、
- ゴミ箱このDALのためのクエリの作成を処理し、NHibernateのような「正しい」DAOを使用しているため - それはここに発明されなかったからです。
- この質問はdba.stackexchange.comにお願いします.SqlClientには問題があり、SQL Server自体ではなく、私が使用する方法に問題があるためです。
良い点は、NUMERIC(38,8)に小数点のデフォルトタイプを設定すると考えられるすべてのケースを処理する必要があります。何らかの理由で誰かが小数点以下8桁以上の数値を渡した場合は、スケールを変更して精度を最大値に保ちます。今では、なぜ私は最初にvarchar(8000)と数値(38,8 + n)に行くのではなく、多くの値の複雑なアイデアを考え出したのだろうと言いました。 – MagnatLU