2017-12-21 26 views
-4

私はこのコードを使用して、各アイテムにランダムなIDを生成する関数を呼び出してテーブルを更新します。私は約1000行から始めましたが、現在はサイズが大きくなり、テーブルに重複IDがあることがわかります。私は使用しているコードを修正する方法はありますか?同様に、新しいコードが生成されるように、すでにテーブルに生成されているIDを探します。私はまた、最初のまたは最後の名前が同じ文字で始まる場合、同じIDを生成することに気づきました。この関数はFNameとLNameの組み合わせで '23456789'の間に乱数を生成します。重複を見つけて削除するには

WHILE (EXISTS (SELECT Password FROM dbo.Users WHERE Password IS NULL)) 
BEGIN 
BEGIN TRY 
WITH SingleRow AS (
SELECT TOP 1 
FirstName, 
LastName, 
Password 
FROM dbo.Users 
WHERE Password IS NULL 
) 
UPDATE SingleRow 
SET Password = dbo.GenerateID(FirstName, LastName); 
END TRY BEGIN CATCH 
END CATCH; 
END; 

The function i use here generate this UniqueID

+0

(おそらく逐次処理可能な)トランザクションでラップします。しかし、完全に欠陥のあるGenerateID機能を見ることはできません! –

+0

@MitchWheat、私はOPが彼/彼女の以前の質問からの解決策を使用していると思う:https://stackoverflow.com/questions/47721893/generate-random-tokens-unique-ids-for-users-in-a-table -in-sql-server –

+1

と誰もがそのことを知っていると思われますか? –

答えて

0

あなたのコードを使用すると、フィールドのパスワードを設定することを示すが、結果は一意IDが重複したフィールドであることを示しています。

userIdが一意であると仮定します(そうでない場合は、実際のID列を今すぐ追加します)。 "ALTER TABLE dbo.Users ADD ID INT NOT NULL IDENTITY(1、1)"がトリックを行う必要があります)パスワードを変更するフィールドとすると、次のようになります。

DECLARE @FN VARCHAR(20); 
DECLARE @LN VARCHAR(20); 
DECLARE @PW VARCHAR(20); 
DECLARE @ID INT; 
SELECT TOP 1 
@FN = FirstName, 
@LN = LastName, 
@ID = userID 
FROM dbo.Users 
WHERE Password IS NULL; 
WHILE @@ROWCOUNT = 1 
BEGIN 
SET @PW = dbo.GenerateID(FirstName, LastName); 
WHILE EXIST (SELECT TOP 1 Password FROM dbo.Users WHERE Password = @PW) 
    SET @PW = dbo.GenerateID(FirstName, LastName); 
UPDATE dbo.Users SET Password = @PW WHERE userId = @ID; 
SELECT TOP 1 
@FN = FirstName, 
@LN = LastName, 
@ID = userID 
FROM dbo.Users 
WHERE Password IS NULL; 
END 

空白のパスワードを探します。何も見つからなければ、外側ループはスキップされる。見つかった場合は、テーブルにないパスワードが見つかるまでパスワードを生成します。次に、外側のループの終わりの前に空白のパスワードを持つ別の行を探します。

0

これはあなたの新しいもののようなものです。心配しないで、TSQLはとても簡単に学ぶことができます。最初にまず、UniqueID列に一意の非クラスタ化インデックスを作成することをお勧めします。これにより、重複する値がテーブルに挿入されないようにします。誰かが重複した値をテーブルに挿入しようとすると、例外がスローされます。これを使用する前に、テーブルからすべての重複した 'UniqueID'値を削除する必要があります。

 

    CREATE UNIQUE NONCLUSTERED INDEX [IDX_UniqueID] ON [dbo].[Users] 
    (
     [UniqueID] ASC 
    ) ON [PRIMARY] 

あなたはここに非クラスタ化インデックスについての詳細を学ぶことができます:「UNIQUEIDENTIFIER」https://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described

私もあなたがあなたの一意IDフィールドの基になる型を変更することを検討することを示唆していますここでのUniqueID列のための「UNIQUEIDENTIFIER」列の型を使用するテーブルスキーマの例です:

 

    CREATE TABLE [dbo].[Users](
     [personId] [int] IDENTITY(1,1) NOT NULL, 
     [firstName] [nvarchar](50) NOT NULL, 
     [lastName] [nvarchar](50) NOT NULL, 
     [UniqueID] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
    (
     [personId] ASC 
    ) ON [PRIMARY] 
    ) ON [PRIMARY] 

'uniqueidentifier' column typeはSQL Sereverにグローバル一意識別子(別名GUIDまたはUUID)を保持しています。ほとんどの言語でGUIDを生成するのは簡単です。 TSQLでGUIDを生成するには、新しくNEWID()関数を呼び出すだけです。

 

    SELECT NEWID() -- output: D100FC00-B482-4580-A161-199BE264C1D1 

現在のGUIDについての詳細を学ぶことができます:https://en.wikipedia.org/wiki/Universally_unique_identifier

は、この情報がお役に立てば幸いです。あなたのプロジェクトで最高の運があります。 :)

関連する問題