質問
この変更が確認されるまで、提案された新しい値を保持する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