3

編集:従業員固有の番号として使用されます(ランダムな順序である必要があります)

列のあるテーブルがあります

id(auto-increment), uniqueNumber, and some other field

挿入されたレコードごとに、uniqueNumberに対して6桁の一意の番号を生成します。

今、これをトリガーで取得しています

Create TRIGGER [dbo].[trgUniqueCode] ON [dbo].[testtable]
FOR INSERT
AS
declare @id int;
DECLARE @Upper INT
DECLARE @Lower INT
declare @result int
select @id=i.id from inserted i;
SET @Lower = 100000 
SET @Upper = (select top 1(isnull(UniqueNumber,999999)) from testtable) 
set @result =(ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0))
update testtable set UniqueNumber = @result where ID=@id

この方法が機能するかどうかわからない、生成するための最良の方法を探している(優先時間の実行)、またはC#で一意の番号を生成しますか?

4

8 に答える 8

8

まだ割り当てていないすべての番号のリストを生成します。リストをシャッフルし、ランダムIDと増分インデックスを含む新しいテーブルを作成します。新しいIDが必要な場合は、インデックスが最小のIDを選択してください。未使用のIDテーブルから削除し、新しいIDとして返します。

于 2013-03-11T21:56:39.283 に答える
3

次を使用して、SQLServerから正確に6桁の長さの乱数を取得できます。

SELECT CAST((RAND() * (899999) + 100000) as int) 

次のコードを使用して、ランダムに生成された番号でテーブルのフィールドを更新します。

最初の部分は、新しい行がテーブルに挿入されるたびに呼び出される関数です。

CREATE VIEW ViewRndNum
AS
SELECT CAST((RAND() * (899999) + 100000) as int);


CREATE FUNCTION [dbo].[GetID](@Counter int = 0)
RETURNS int
AS
BEGIN
    DECLARE @RandNumber as int;
    DECLARE @iEmployeeCode as int;
    DECLARE @iExistingEmployeeCode as int;


    IF (@Counter < 20) 
        BEGIN
        SELECT @iEmployeeCode = RndNum
                    FROM ViewRndNum;


        SELECT @iExistingEmployeeCode = EmployeeCode FROM dbo.Employees WHERE EmployeeCode = @iEmployeeCode
        IF @iExistingEmployeeCode = @iEmployeeCode 
            BEGIN
                SET @Counter = @Counter + 1
                SELECT @iEmployeeCode = [dbo].[GetID](@Counter)
            END
        END
    ELSE
        SET @iEmployeeCode = 99999999
RETURN @iEmployeeCode
END
GO

CREATE TABLE [dbo].[Employees](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [EmployeeType] [int] NULL,
    [EmployeeID] [bigint] NULL,
    [EmployeeCode] [int] NULL,
    [Employee] [varchar](max) NULL,
    [CreatedDate] [datetime] NULL,
    [LastSeen] [datetime] NULL,
 CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Employees] ADD  CONSTRAINT [DF_Employees_EmployeeCode]  DEFAULT ([dbo].[getID]((0))) FOR [EmployeeCode]
GO
于 2013-03-11T21:46:32.820 に答える
2

Transact-SQL:

select floor(rand()*1000000-1)

C#:

Random rnd = new Random();
int rslt = rnd.Next(100000, 999999);

一意の値を生成するための最善のアプローチは、1つ増やすことです。一意の値を生成する他の方法は、ますます計算効率が悪くなります。

また、ハッシュ関数を使用することもできます。ハッシュ関数は「ほぼ」一意の値を提供します。しかし、それは私がよく知らない理由です。

3番目のオプションは、GUIDsを一意の識別子として使用することです。それらは非常に計算効率が高く、ドメインの境界を越えても一意であることが保証されています。ただし、これらは6つだけではなく、約80のシンボルです:)

于 2013-03-11T21:43:09.863 に答える
2

編集:おっと、「ランダムな順序である必要があります」という要件を逃しました。申し訳ありません。

それに応えて、私はこの問題に対してまったく異なるアプローチを提案します。「ランダムでなければならない」というビジネス要件を押し戻すべきだと思います。何のために?

私の経験では、それは通常、マネージャーが「ボブはアリスの直後に雇われた、アリスの従業員IDは1987であるため、ボブは1988でなければならない」などのシナリオを望まないためです。これに対する私の答えは「だから何?」です。ボブの従業員IDを知っていても、攻撃者を助けることはできません。そうすると、組織のセキュリティにはるかに大きな問題が発生します。

上記の優れた回答を実装しているときに、考えて試してみることがあります。

私の元の、間違った、答え:

自動インクリメントフィールドを使用してみませんか?

SQL Serverで、次のように列を作成します。

create table dbo.Whatever (
    id int not null identity( 100000, 1 ) ,
    …

また、一意性を強制するために主キー制約または一意性制約のいずれかを作成する必要があります。また、下限と上限(それぞれ、100000と999999)を強制するためのチェック制約も作成する必要があります。

create table dbo.Whatever (
    id int not null identity( 100000, 1 ) 
        constraint id_u unique 
        constraint id_bounds check ( id between 100000 and 999999 ) ,
    …

これは絶対に6桁の数字である必要がありますか?他の場所で提案されているように、uniqueidentifierを使用できますか?NEWID()関数は、複数のセッションに対して同時に一意の番号を生成しようとするシリアル化の問題が発生しないことを意味します。

于 2013-03-11T21:48:58.547 に答える
1

SQL Server 2012で、次のコードを使用して単純な注文テーブルを作成しました。ここで、ODRIDはカスタム形式の販売注文IDです。

CREATE TABLE [dbo].[OrderTransaction](
[OrderID] [bigint] IDENTITY(1,1) NOT NULL,
[ODRID]  AS (right('ES00000000'+CONVERT([nvarchar](10),[OrderID]),(11))),
[OrganisationID] [bigint] NOT NULL,
[SubTotal] [int] NOT NULL,
[Discount] [int] NOT NULL,
[TotalAmount] [bigint] NOT NULL,
[CreatedBy] [int] NULL,
[CreatedDate] [datetime] NULL,
[ModifieddBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
CONSTRAINT [PK_OrderTransaction] PRIMARY KEY CLUSTERED 
(
[OrderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
于 2016-12-29T11:28:12.950 に答える
0

c#

Random rand = new Random();
int randomNumber = rand.Next(100000, 999999);

SQLでは少し難しいです:

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-set-based-random-numbers

于 2013-03-11T21:44:11.787 に答える
0
function random_numbers($digits,$id) {
$min = pow(10, $digits - 1);
$max = pow(10, $digits) - 1;
$number = mt_rand($min, $max);
$count = strlen($id);
$ssn_id = substr($number, $count);
$ssn_id = trim($id.$ssn_id);
return $ssn_id;
}

echo random_numbers(9,145);
于 2014-04-01T07:07:39.117 に答える
0

これを使って -

DECLARE @NewPINGenerated Int = CONVERT(numeric(12,0),RAND() * 899999) + 100000
DECLARE @SMS VARCHAR(100)='Message Here '+CAST(@NewPINGenerated as varchar)
于 2018-10-10T10:37:16.390 に答える