1

システム内のすべてのテーブルのすべてのフィールドの監査された変更を含む次のSQLビューの結果があります。

ここに画像の説明を入力してください

この場合、上の画像は、 MySubscriptionというサブスクリプションのユーザーLucasに対して、読み取り書き込みの両方のアクセス許可が取り消されたことを示しています。

その情報をグリッドに表示する必要がありますが、それは表示したいものではありません。つまり、IDを表示したくないのです。50の代わりに「Read」、51の代わりに「Write」、1の代わりに「Lucas」、6の代わりに「MySubscription」を表示する必要があります。

そのために、SQLビューを改善して、前述のようにIDではなく値を取得したいと思います。私が探している結果はこれです: ここに画像の説明を入力してください

データベースには、結合を使用して必要な情報を取得するためのテーブルSubscriptionsProductPermissions、およびTenantUsersが含まれています。

どうすれば必要なことを達成できるかについて、いくつかの手がかりを教えてください。ありがとうございました。

4

4 に答える 4

2

一連のLEFT JOINs を使用してこれを行うことができます。結合する列のデータ型を同じにするために、いくつかのキャストが必要になる場合があります (結合するすべてのテーブルでNewValue呼び出される列を想定していますが、これは変更が必要になる場合があります)。Name

SELECT  a.AuditLogId,
        a.Operation,
        a.[Table],
        a.RowId,
        a.Name,
        [OldValue] = COALESCE(s_Old.Name, pp_old.Name, t_Old.Name),
        [NewValue] = COALESCE(s_New.Name, pp_New.Name, t_New.Name)
FROM    AuditLog a
        LEFT JOIN Subscriptions s_Old
            ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
            AND a.Name = 'SubscriptionID'
        LEFT JOIN ProductPermissions pp_Old
            ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
            AND a.Name = 'ProductPermissionId'
        LEFT JOIN TenantUsers t_Old
            ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
            AND a.Name = 'TenantUsers'
        LEFT JOIN Subscriptions s_New
            ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
            AND a.Name = 'SubscriptionID'
        LEFT JOIN ProductPermissions pp_New
            ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
            AND a.Name = 'ProductPermissionId'
        LEFT JOIN TenantUsers t_New
            ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
            AND a.Name = 'TenantUsers'

必要に応じて、これをトランザクションごとに 1 つの行に PIVOT できます。

SELECT  a.AuditLogId,
        a.Operation,
        a.[Table],
        a.RowId,
        [OldSubscriptionValue] = MAX(s_old.Name),
        [OldProductPermissionValue] = MAX(pp_old.Name),
        [OldTennantUserValue] = MAX(t_old.Name),
        [NewSubscriptionValue] = MAX(s_New.Name),
        [NewProductPermissionValue] = MAX(pp_New.Name),
        [NewTennantUserValue] = MAX(t_New.Name)
FROM    AuditLog a
        LEFT JOIN Subscriptions s_Old
            ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
            AND a.Name = 'SubscriptionID'
        LEFT JOIN ProductPermissions pp_Old
            ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
            AND a.Name = 'ProductPermissionId'
        LEFT JOIN TenantUsers t_Old
            ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
            AND a.Name = 'TenantUsers'
        LEFT JOIN Subscriptions s_New
            ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
            AND a.Name = 'SubscriptionID'
        LEFT JOIN ProductPermissions pp_New
            ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
            AND a.Name = 'ProductPermissionId'
        LEFT JOIN TenantUsers t_New
            ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
            AND a.Name = 'TenantUsers'
GROUP BY a.AuditLogId, a.Operation, a.[Table], a.RowId;

これはかなり汚い解決策です。このデータを選択したい形式で保存する傾向があります。つまり、50/51 の代わりに、読み取り/書き込みをNewValue列に直接保存します。

あるいは、トランザクションごとに 1 つの行を持つ 2 番目の形式が必要な場合は、この方法で保存する傾向があります。Entity-Attribute-Value Antipatternについて読む価値があるかもしれません。

于 2013-01-21T14:55:12.107 に答える
0

値が特定されているテーブルに参加してみてください。NewValueフィールドをSQLにハードコーディングすることを意味するため、実際には汚いソリューションです。

...
FROM
    audit LEFT JOIN 
    mysubscription ON audit.rowid = mysubscription.tenantuserid
        AND audit.newvalue = 1
    LEFT JOIN 
    lookup_list ON audit.rowid = lookup_list.lookup_id 
        AND audit.newvalue <> 1
...

それはあなたのために働くかもしれません。

于 2013-01-21T14:38:29.160 に答える
0

PIVOTデータとLEFT JOINルックアップ テーブルを参照できます。その後UNPIVOT、必要に応じて。

于 2013-01-21T14:34:08.883 に答える
0

数字の代わりに単語を表示するだけの場合は、表示する数字と単語をマッピングするルックアップ テーブルを作成します。

create table NewValueText (
    NewValue integer,
    Description char(20)
);

insert into NewValueText values
   (50, 'Read'),
   (51, 'Write');   --etc.

--MyTable is your table that contains the NewValue column.
select Description from MyTable
    inner join NewValueText on MyTable.NewValue = NewValueText.NewValue;
于 2013-01-21T14:34:09.997 に答える