アプリケーションの構成テーブルに単一の行を格納したい。このテーブルには1行のみを含めることができるようにしたいと思います。
単一行の制約を強制する最も簡単な方法は何ですか?
列の1つに1つの値のみを含めることができることを確認してから、その主キーを作成します(または一意性制約を適用します)。
CREATE TABLE T1(
Lock char(1) not null,
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)
主に設定を保存するために、さまざまなデータベースにこれらのテーブルが多数あります。構成アイテムがintである場合、DBからintのみを読み取ることを知っている方がずっといいです。
私は通常、ダミアンのアプローチを使用しますが、これは常に私にとってはうまくいきましたが、1つ追加します:
CREATE TABLE T1(
Lock char(1) not null DEFAULT 'X',
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)
「DEFAULT 'X'」を追加すると、Lock列を扱う必要がなくなり、テーブルを初めてロードするときにどちらがロック値であったかを覚える必要がなくなります。
この戦略を再考することができます。同様の状況で、履歴情報のために古い構成行を残しておくことは非常に貴重であることがよくあります。
これを行うには、実際に余分な列creation_date_time
(挿入または更新の日付/時刻)と、現在の日付/時刻を正しく挿入する挿入または挿入/更新トリガーがあります。
次に、現在の構成を取得するには、次のようなものを使用します。
select * from config_table order by creation_date_time desc fetch first row only
(DBMSフレーバーによる)。
こうすることで、リカバリの目的で履歴を維持することができ(テーブルが大きくなりすぎてもクリーンアップ手順を設定できますが、これはほとんどありません)、最新の構成で作業することができます。
INSTEAD OF Trigger を実装して、データベース内でこのタイプのビジネスロジックを適用できます。
トリガーには、テーブルにレコードが既に存在するかどうかを確認するロジックを含めることができます。存在する場合は、挿入をロールバックします。
さて、大きな画像を見るために一歩下がって、おそらくあなたがこの情報を、例えば設定ファイルや環境変数に保存するための代替的でより適切な方法があるのだろうか?
これは、YまたはN(たとえば、アプリケーションロック状態)を保持する1行のみを含むことができるロックタイプのテーブルに対して考え出したソリューションです。
1列のテーブルを作成します。 YまたはNのみを挿入できるように、1つの列にチェック制約を設定します。 (または1または0、または何でも)
「通常の」状態でテーブルに1行挿入します(たとえば、Nはロックされていないことを意味します)
次に、SIGNAL(DB2)またはRAISERROR(SQL Server)またはRAISE_APPLICATION_ERROR(Oracle)のみを持つテーブルにINSERTトリガーを作成します。これにより、アプリケーションコードはテーブルを更新できますが、INSERTは失敗します。
DB2の例:
create table PRICE_LIST_LOCK
(
LOCKED_YN char(1) not null
constraint PRICE_LIST_LOCK_YN_CK check (LOCKED_YN in ('Y', 'N') )
);
--- do this insert when creating the table
insert into PRICE_LIST_LOCK
values ('N');
--- once there is one row in the table, create this trigger
CREATE TRIGGER ONLY_ONE_ROW_IN_PRICE_LIST_LOCK
NO CASCADE
BEFORE INSERT ON PRICE_LIST_LOCK
FOR EACH ROW
SIGNAL SQLSTATE '81000' -- arbitrary user-defined value
SET MESSAGE_TEXT='Only one row is allowed in this table';
私のために働く。
IsActiveという名前の主キーにビットフィールドを使用します。したがって、最大で2つの行があり、有効な行を取得するsqlは次のとおりです。
テーブルの挿入アクションでトリガーを作成できます。誰かがテーブルに新しい行を挿入しようとするたびに、挿入トリガーコードの最新の行を削除するロジックを起動します。
古い質問ですが、小さな列タイプのIDENTITY(MAX、1)を使用するのはどうですか?
CREATE TABLE [dbo].[Config](
[ID] [tinyint] IDENTITY(255,1) NOT NULL,
[Config1] [nvarchar](max) NOT NULL,
[Config2] [nvarchar](max) NOT NULL
IF NOT EXISTS ( select * from table )
BEGIN
///Your insert statement
END
ここでは、データベースの最初のエントリの後に同じになる非表示値を作成することもできます。例:Student Table:Id:int firstname:charここのエントリボックスでは、制限するid列に同じ値を指定する必要があります主キー制約のためにロックbla blaを書き込むこと以外の最初のエントリの後、永久に1つの行のみを持つように。お役に立てれば!