質問

この変更が確認されるまで、提案された新しい値を保持する2番目のフィールドがそれぞれ続くフィールドのセットがあるテーブルを処理する必要があります。

少しこのように見えます:

refID    field1    newField1    field2    newField2   ... 

refIDは、マスターテーブルにリンクするID値です。マスターテーブルの1行には、詳細テーブルにn行を含めることができます。データ型には、int、strings、dateTimesが含まれます。

今、詳細テーブルに提案された変更があるかどうか、refIDを指定して、私に伝えるクエリを探しています。

私はCOALESCE()とISNULL()を使用して、いくつかのUNIONセレクトで少し遊んでいましたが、それらの試みはすべてせいぜい少し奇妙に見えました。 DBはMS-SQL-Server 2005です。

私の問題を明確にするために:

--this is a simplification of the details table in question
CREATE TABLE [dbo].[TEST_TABLE](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [refID] [int] NOT NULL,
    [firstName] [varchar](50) NULL,
    [newFirstName] [varchar](50) NULL,
    [lastName] [varchar](50) NULL,
    [newLastName] [varchar](50) NULL
)

--here we insert a detail row ... one of many that might exist for the master table (e.g. data about the company)
insert into TEST_TABLE(refID, firstName, lastName) values(666, 'Bill', 'Ballmer')
--this is what happens when a user saves a suggested change
update TEST_TABLE SET newLastName = 'Gates' where ID = 1
--and this is what happens when this suggestion is accepted by a second user
update TEST_TABLE set lastName=newLastName, newLastName = NULL where ID = 1
役に立ちましたか?

解決

これは、私の頭上で考えることができる最もクリーンなソリューションです。各データ要素(col1、col2など)に対してロジックを繰り返す必要があります。

DECLARE @RefID int, @Changes bit

SET @Changes = 0 --No changes by default

SET @RefID = 42 --Your RefID

IF EXISTS(SELECT * FROM MyDetailTable
          WHERE RefID = @RefID
          AND (
          (Col1 IS NULL AND NewCol1 IS NOT NULL)
          OR 
          (Col1 IS NOT NULL AND NewCol1 IS NULL)
          OR
          (Col1 <> Col2)
          ))
   SET @Changes = 1

他のヒント

ランドルホス溶液を変更しました。

 select 
        refID ,
        case when 
            newField1 is not null or
            newField2 is not null or
            ...
        then 1 else 0 end  haschanged
    from myTable
    where refID = @refID

更新:基本的に、Aron Aaltonが別の出力形式で言ったこと。

簡単なクエリを次に示します。

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE COALESCE(t.newFirstName,t.newLastName) IS NOT NULL
       AND t.refID = 1

特定の refID に対して提案された変更がある場合、このクエリは1行を返します(質問の例に基づきます)。

もちろん、実際のテーブルでは、COALESCE関数の引数として各 'newValue' 列をリストする必要があります。 (合体リストでは、リスト内のすべての式が同じデータ型であることを明確にするために、非VARCHARをVARCHARに明示的にキャストすることをお勧めします。

COALESCEではなくCASE式を使用する場合:

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE CASE 
           WHEN t.newFirstName IS NOT NULL THEN 1
           WHEN t.newLastName  IS NOT NULL THEN 1
           ELSE NULL
           END IS NOT NULL
       AND t.refID = 1

このスキーマはすでに定義されており、運用中ですか?そうでない場合は、いくつかの説明の個別の「変更」テーブルを作成することを強くお勧めします-fieldvalueがsql_variantであるfieldname、fieldvalueを使用する可能性があります。

特に、このアプローチでは監査履歴を保持しないため、値が「受け入れられる」(私は想定しない)場合、既存の構造は見栄えがよくないと思います。

これをテストすることはできませんが、おそらく:

select (field1 is not null and field2 is not null) as ChangesMade where refID = @id
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top