2

これが他のサイトに属しているのか、他のサイトに属しているSOのかわからない場合は、移動する必要があるかどうかをお知らせください。

これが私が取り組んでいるものです:
それは製品のテーブルを持っている非常に古いeコマースシステムです。この製品の表は、Windowsタスクスケジューラを介して毎晩2つのファイルによって更新されます。1つのファイルには製品情報(名前、説明、色、製造元など)があり、もう1つのファイルには価格、在庫、倉庫の場所などの情報があります。これらのファイルを解析してデータベース内の製品を更新するプロセスには、数時間かかります。私はこれらの2つのファイルを制御できません。

両方のファイルがデータベース内の製品を更新したかどうかを判断する方法が必要です。両方のファイルの情報を持っているユーザーにのみ製品を表示できます。製品が1つだけ更新された場合、その製品は不完全であると見なされ、表示できません。

今のところ、2つのタスクのいずれかによってレコード/製品が変更されるたびに、count + 1に追加/更新するトリガーを追加し、新しい列に保存することを考えています。次に、別のタスクを実行して、その列が2に等しいかどうかを確認し、表示または非表示にするために必要な処理を実行します。しかし、私はそこにいくつかの他のアイデアがあるかもしれないと思いますか?

4

4 に答える 4

1

これはどうですか、ビット型(ブール値)の別の列があります。それを「IsValid」と呼びましょう。クリーンなレコード(両方によって更新されたことがわかっているレコード)の場合、値はになりますtrue。更新が発生するたびに、そのビットを反転NOT(演算子を適用)します。これは、トリガーを介して簡単に実行できます。したがって、2つの更新(各ファイルから1つ)がある場合、正味の値はtrue再びになります。そのレコードを読み取るアプリの部分は、その「IsValid」フラグを調べて、そのレコードが実行可能かどうかを判断します。

これは、各ファイルがレコードを0回または1回だけ更新する場合にのみ機能します。ファイル1が同じレコードを2回更新し、ファイル2が何もしない場合、フラグはレコードを有効として誤って報告します。

于 2012-10-19T20:46:30.403 に答える
1

レガシ プロセスの完全な回帰テストについて心配する必要がないように、トリガーを使用して Product テーブルの更新を 2 番目のテーブルに記録することを選択します。

トリガーは、更新された列をチェックすることで、実行中のプロセスを判別できます。次に、両方のプロセスによって更新されたすべての製品を返す単純なクエリを作成します。

/* Test tables */
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Product')
  DROP TABLE Product

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ProductChangeLog')
  DROP TABLE ProductChangeLog
GO

CREATE TABLE Product (
  ProductID INT NOT NULL PRIMARY KEY, 
  ProductName VARCHAR(50) NOT NULL,
  ProductDescription VARCHAR(100) NOT NULL,
  ProductPrice MONEY NOT NULL,
  ProductAvailQty INT NOT NULL
) 

CREATE TABLE ProductChangeLog (
  ChangeLogID INT NOT NULL IDENTITY(1,1), 
  ProductID INT NOT NULL,
  ChangeTime DATETIME NOT NULL,
  ChangeType VARCHAR(50) NOT NULL,
) 
GO 

CREATE TRIGGER tr_Product ON Product 
FOR UPDATE
AS

  INSERT ProductChangeLog (ProductID, ChangeTime, ChangeType) 
  SELECT 
    ProductID,
    GETDATE(),
    -- Log the process which was run depending on columns modified
    CASE WHEN UPDATE(ProductName) OR UPDATE(ProductDescription)
         THEN 'Process1'
         WHEN UPDATE(ProductPrice) OR UPDATE(ProductAvailQty)
         THEN 'Process2'
         ELSE 'Neither'
    END 
  FROM inserted
GO 

INSERT Product 
SELECT 1, 'Blue V-Neck', 'Sweater', 25.00, 100 UNION ALL 
SELECT 2, 'Green V-Neck', 'Sweater', 30.00, 200 UNION ALL
SELECT 3, 'Black crew', 'T-Shirt', 10.00, 45

/* Change two products in first process */
UPDATE Product 
SET ProductDescription = 'Men''s Sweater' 
WHERE ProductDescription = 'Sweater'

/* Change three products in second process */
UPDATE Product
SET ProductPrice = ProductPrice + 10

/* See all changes */
SELECT * 
FROM ProductChangeLog 

DECLARE @today DATETIME
SET @today = DATEADD(DAY, 0, DATEDIFF(DAY, 0, GETDATE())) 

/* See all products changed today by both processes */
SELECT * 
FROM Product p 
WHERE EXISTS (
  SELECT * 
  FROM ProductChangeLog 
  WHERE ChangeType = 'Process1'
    AND ChangeTime > @today 
    AND ProductID = p.ProductID 
) 
AND EXISTS ( 
  SELECT * 
  FROM ProductChangeLog 
  WHERE ChangeType = 'Process2'
    AND ChangeTime > @today 
    AND ProductID = p.ProductID 
) 

*SQL Server 2005 でテスト済み

于 2012-10-19T22:05:12.073 に答える
1

各ファイルの最終更新のタイムスタンプを含む 2 つの列を使用します。過去 X (24?) 時間以内に両方のタイムスタンプを持つレコードのみを表示します。

于 2012-10-19T19:41:06.860 に答える
0

Id_Record という主キーを持つテーブルがあるとします。

このテーブルへの最新の更新を表示する (または表示しない) だけの場合: Id_Record、Dt_Timestamp_File1、Dt_Timestamp_File2 で別のテーブルを作成し、ファイルの更新ごとにタイムスタンプをトリガーします。次に、2 つのタイムスタンプの許容差を定義します (または、必要なその他の規則)。

次に、次の方法でレコードを取得できます。

SELECT Id_Record, Ds_Record_Name, Nr_Record_Price, Nr_Record_In_Stock FROM Stock WHERE Id_Record IN (SELECT Id_Record FROM Stock_Update WHERE Dt_Timestamp_File1 > Dt_Timestamp_File2 - 3600000 AND Dt_Timestamp_File1 < Dt_Timestamp_File2 + 3600000)

UnixTime を使用していると仮定し (常に unixtime [1/1/70 からのミリ秒] で時間を比較する方が簡単です)、最大時差は 1 時間です。

于 2012-10-19T19:44:32.663 に答える