2

私はTSQLビューを持っています。いくつかの列を除いて、いくつかの結合を行い、すべてを接着して本来あるべき見栄えを提供するという点で、かなり基本的なものです。ただし、複雑な列のビジネス ロジックを無効にする新しい要件が発生したため、それほど単純ではない列がいくつかあるため、ビュー コードの拡張が非常に難しくなっています。

詳しくは説明しませんが、私のデータベースには次のテーブルがあります。

tblEmployment

これは、「雇用」の行で構成されます。行の列のいずれかが特定の雇用の変更 (変更としましょう) に対して変更されるたびemploymentTitleに、現在の行が別の table にプッシュされtblEmploymentHistory、行tblEmploymentが変更されて最新の が含まれるようになりますemploymentTitle

基本的に、ビューが行うことは、tblEmploymentontblEmploymentHistoryを uniqueに結合しようとEmploymentIdentifierすることです。これは理にかなっています。

elapsedTimeビュー内のより複雑な列は、結合された行から (つまり から) さまざまな計算を行うことにより、(行ごとに)数値を計算しようとしますtblEmployment and tblEmploymentHistory。経過時間を取得するために、指示されたビジネス ロジックに基づいて計算を実行します。たとえば、履歴テーブルの特定の日時列のみが合計経過時間にカウントされ、その行の他の列が特定の値に設定されている場合にのみカウントされます。

新しい要件が発生したため、ビジネス ロジックは以前よりもはるかに複雑になっています。これを含めるようにビューを拡張するのは非常に面倒なので、これを含めるのは難しいと思います。ビジネス ロジックの残りの部分も存在するアプリケーション層で、これをより構造化することができると思います。

ビューをスクラップして、代わりにアプリケーションのアプリケーション層に移動するのは「正しい」ですか? 明らかに、ビューを持つことの利点は高速であることです。コードで約 100.000 行の計算を行うには、ある程度の時間がかかります。ただし、行をフィルター処理して約 10.000 にすることで最適化できます。

この問題に取り組む「標準」で最もクリーンな方法は何ですか?

4

2 に答える 2

3

答えは、いくつかのことに依存します。まず、データベースがセットベースの作業を行っていることを確認します。カーソル (一般的に言えば) またはある種のループに入り始めた場合は、それをアプリケーションに配置することをお勧めします。リレーショナル データベースは、そのような方法では効率的ではありません。私が考慮したいもう1つのことは、あなたが働いている環境の標準は何ですか? あなたがいる場所では、このようなDBで他のものが維持されていますか? もしそうなら、一貫性を保ちたいと思うかもしれません。

最終的に、それらの結果を最も効率的に返し、他のクエリに影響を与えることなく、それが答えになるはずです。

于 2015-09-09T13:26:12.157 に答える
1

約束どおり、UDF アプローチの例を示します。私のプロジェクトの 1 つで、これを 40 以上の異なる階層構造の UDF で使用して、1000 列近くの結果セットを取得しています。

CREATE TABLE dbo.TestTable(Col1 INT,Col2 INT,Col3 INT);
INSERT INTO dbo.TestTable VALUES(1,2,3),(4,5,6),(7,8,9);
GO

CREATE FUNCTION dbo.TestFunc(@Prm1 INT,@Prm2 INT)
RETURNS TABLE
AS
RETURN
    SELECT @Prm1 AS Func_Prm1 --use names, which will be unique in any usage, this makes things much easier!
          ,@Prm2 AS Func_Prm2
          ,@Prm1 * @Prm2 AS Func_Calculated;
GO

--This would be your simple VIEW, consisting of any columns you can easily get
SELECT *
FROM dbo.TestTable
--This is how you join the "buiness logic" to your view
CROSS APPLY dbo.TestFunc(TestTable.Col1,TestTable.Col2) AS func

DROP TABLE dbo.TestTable;
GO
DROP FUNCTION dbo.TestFunc;      
GO
于 2015-09-09T14:15:18.800 に答える