2

両方の列でNULLが許可されている2列のセットに一意性制約を作成する方法を誰が知っていますか?つまり、col1 = NULL AND col2 = NULLの一意性を無視しますが、そのうちの1つだけがNULLの場合に制約を機能させますか?単一の列に対してそれを行う方法を見つけましたが(nullも許可する一意の制約を作成するにはどうすればよいですか?)、2つの列に対してそれを行うことはできません。これは、既存のレコード(複数のNULL、NULLが許可されています)に対して機能するが、新しいNULL、NULLレコードを追加できない私のスクリプトです。

CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON dbo.MyTable(col1, col2)     
WHERE col1 IS NOT NULL AND col2 IS NOT NULL

更新:まあ、それはあなたが新しい(NULL、NULL)値を追加することを可能にするので、私は間違っていました、しかしそれはまた私がしたくない(1、NULL)、(1、NULL)のようなものを追加することを可能にするので、一意性はこの場合は、複数(NULL、NULL)のみを許可する必要があります。これを行う方法?

4

2 に答える 2

2

その時、他の何かが確かに機能していません。コード/スクリプトは期待どおりに機能します。

CREATE TABLE #MyTable
(
    Col1 INT NULL,
    Col2 INT NULL
)

CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON #MyTable(col1, col2)     
WHERE col1 IS NOT NULL AND col2 IS NOT NULL

INSERT INTO #MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works

INSERT INTO #MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works

SELECT * FROM #MyTable

INSERT INTO #MyTable(Col1, Col2)
VALUES(1, 1) --Works

INSERT INTO #MyTable(Col1, Col2)
VALUES(1, 1) --Fails

SELECT * FROM #MyTable

DROP TABLE #MyTable
于 2013-02-01T16:06:42.203 に答える
1

両方がnullの場合を除いて値を一意にしたい場合は、少なくとも1つの値がnullでない限り、値を一意にしたいことを意味します。インデックスのフィルターには。ANDがありますが、が必要ですOR

CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON dbo.MyTable(col1, col2)     
WHERE col1 IS NOT NULL OR col2 IS NOT NULL -- (note: doesn't work)

しかし...あなたはこれを行うことはできません。SQL Serverでは、AND条件を使用してwhere句のみを作成できます。また、永続化された計算列を使用してそれを行うことはできません。

代わりに、元のテーブルにインデックス付きビューを作成し、そのテーブルに一意のインデックスを配置することができます。少し重いですが、うまくいくはずです。

だから...@Meffのスクリプトを借りるには、次のようなものを見ていることになります。

CREATE TABLE dbo.MyTable
(
    Col1 INT NULL,
    Col2 INT NULL
)
GO
CREATE VIEW dbo.MyTableUniqueView WITH SCHEMABINDING AS
SELECT Col1, Col2 FROM dbo.MyTable
WHERE Col1 IS NOT NULL OR Col2 IS NOT NULL 
GO
CREATE UNIQUE CLUSTERED INDEX MyTableUniqueIndex
ON dbo.MyTableUniqueView(Col1, Col2)
GO
INSERT INTO MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works

INSERT INTO MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works

SELECT * FROM MyTable

INSERT INTO MyTable(Col1, Col2)
VALUES(1, 1) --Works

INSERT INTO MyTable(Col1, Col2)
VALUES(1, 1) --Fails

INSERT INTO MyTable(Col1, Col2)
VALUES(1, null) --Works

INSERT INTO MyTable(Col1, Col2)
VALUES(1, null) --Fails

SELECT * FROM MyTable
GO
DROP VIEW MyTableUniqueView
DROP TABLE MyTable
于 2013-02-01T16:13:16.067 に答える