2017-08-02 6 views
-1

ダイナミックSQL Serverクエリを使用してOnlineStoreと呼ばれるデータベースのdatetimeフィールドをランダムに変更する方法がわかりません。データベース内のすべてのdatetime列をランダム化するための動的SQL

これは宿題に関することに注意してください。私のクラスはかなり構造化されていないので、ここからどこに行くのか苦労しています。

私の質問は、ループやテーブル変数を使用し、データベース(Product.LastOrderDate、Orders.OrderDate)で2つのdatetime列を取得し、各行にランダムな日付を割り当てる動的SQL Serverクエリを作成するにはどうすればよいですか。今年ですか?

これはこれまで私が行ってきたことです。私はどんな変更にもオープンです。この回答に基づいて

Declare @SQL varchar(max) = ' 
Declare @D1 float = cast(cast(''2017-01-01 00:00:00'' as datetime) as float); 
Declare @D2 float = cast(cast(''2017-12-31 23:59:59'' as datetime) as float); 
+0

updateからの部品に注力したいと思うここで半分です: 'SELECT REPLACEは( 'UPDATE $トンのSETの$ C = ...'、「$(REPLACE t '、QUOTENAME(t。[name]))、' $ c '、QUOTENAME(c。[name]))sysからです。テーブルt JOIN sys.columns c ON c。[object_id] = t。[object_id] WHERE t.is_ms_shipped = 0 AND c.system_type_id = 61'。他の半分は「...」をあなたにランダムな日付を与える式で埋めています。何か 'RAND()'、何か 'DATEDIFF' /' DATEADD'のようなものです。必要な場合は、 'EXECUTE'とカーソルを使って結果の文を実行するという3つ目の部分があります。それは確かに楽しい小さなプロジェクトです。 –

答えて

0

https://stackoverflow.com/a/18408615

これはあなたにランダムな日付を生成するが、ほぼすべての方法を取得し、私は原因2月は2月であることに28で日頂きました。

select cast('2017-' + CAST(ABS(Checksum(NEWID()) % 12) + 1 AS varchar(2)) + '-' + CAST(ABS(Checksum(NEWID()) % 28) + 1 AS varchar(2)) as date) 

これはニーズに合わせて調整できます。

2

[1]現在の年は365日あり、私たちは、0と364の間psedoランダムのINTを生成することができます

SELECT ABS(CHECKSUM(NEWID()) % 365) -- Within SSMS press F5/Execute few times 

[2]我々は、単にので、DATEADDを使用することができ、現在の年以内のランダムな日付を生成するには、次の

SELECT DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 365), {d '2017-01-01'}) -- Within SSMS press F5/Execute few times 
-- it adds a days how many days ?    to first day of year 

例:

enter image description here

[3]今、私たちは、このようにUPDATEステートメント内この式を使用することができます。

UPDATE dbo.Orders 
SET  OrderDate = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 365), {d '2017-01-01'}) 

編集#1:

[4]私は本当に簡単なテスト3回(SQL2016)以下を実行しました
--DROP TABLE dbo.Test1, dbo.Test2 
GO 
CREATE TABLE dbo.Test1(
    ID   INT IDENTITY(1,1) PRIMARY KEY, 
    RandValue INT NOT NULL 
) 
GO 
INSERT dbo.Test1 (RandValue) 
VALUES ((SELECT ABS(CHECKSUM(NEWID())) % 10000)) 
GO 10000 
CREATE TABLE dbo.Test2(
    ID   INT IDENTITY(1,1) PRIMARY KEY, 
    RandValue INT NOT NULL 
) 
GO 
INSERT dbo.Test2 (RandValue) 
VALUES ((SELECT ABS(CONVERT(INT, CRYPT_GEN_RANDOM(4))) % 10000)) 
GO 10000 

結果:

SELECT COUNT(DISTINCT x.RandValue) AS DistinctCnt1 
FROM dbo.Test1 x 

SELECT COUNT(DISTINCT x.RandValue) AS DistinctCnt2 
FROM dbo.Test2 x 

-- Test# DistinctCnt1 DistinctCnt2 
-- 1  6351*   6338 
-- 2  6301   6385* 
-- 3  6296*   6268 

[マイ]結論:結果は明確に区別を明らかにしませんこれら2つの方法。

+1

ニース、これはそれを行う方法です! – saarrrr

+0

'CHECKSUM(NEWID())'の代わりに、 'CONVERT(INT、CRYPT_GEN_RANDOM(4))'(SQL Server 2008以降)があります。このアプリケーションでは問題はないと思うが、 'CRYPT_GEN_RANDOM'はGUID上のチェックサムよりもランダムのランダム性を保証する(GUIDは部分的にランダムであり、' CHECKSUM'はよく知られている欠陥/奇妙さチェックサムを計算する)。 –

+0

イディオムは「このアプリケーションのため」です。私は冒頭で、このソリューションが擬似ランダム値を生成することを述べました。 –

1

this answerに基づいて、私は以下を思いついた。これは2017年1月1日に2017年01月に出された2017-01-01にn秒をランダムに追加します。

最初のビットは50行のテーブル2017-01-01を生成しています。

あなたは...

if object_id('tempdb..#test') is not null drop table #test 
create table #test (orderDate datetime) 

-- add 50 rows to test table 
;with x as 
(
    select 1 as t 
    union all 
    select t+1 
    from x 
) 

insert into #test 
select top 50 '2017-01-01' 
from x 
option(maxrecursion 50) 

--select * from #test 

update t 
set OrderDate = dateadd(second,ABS(CHECKSUM(NewId())) % datediff(second,'2017-01-01 00:00:00','2017-12-31 23:59:59'),'2017-01-01 00:00:00') 
from #test t 

select * from #test 
関連する問題