2011-04-29 40 views
2

我想匿名數據庫中的所有數據,所以我正在重命名其中的所有人。我早些時候問過類似的問題,並被告知使用NewID來強制每更新一行創建一個新的值,但在這種情況下,它似乎並不奏效。TSQL每行不會產生新值

我在做什麼錯?

-- Create Table Customer 
CREATE TABLE #FirstName 
(
    ID int, 
    FirstName nvarchar(255) NULL, 
    Gender nvarchar(255) NULL 
) 

CREATE TABLE #LastName (
    ID int, 
    LastName nvarchar(255) 
) 

-- BULK INSERT to import data from Text or CSV File 
BULK INSERT #FirstName 
FROM 'C:\Users\jhollon\Desktop\tmp\names\firstnames.lined.txt' 
WITH 
(
FIRSTROW = 1, 
FIELDTERMINATOR = ',', 
ROWTERMINATOR = '\n' 
) 

BULK INSERT #LastName 
FROM 'C:\Users\jhollon\Desktop\tmp\names\lastnames.lined.txt' 
WITH 
(
FIRSTROW = 1, 
FIELDTERMINATOR = ',', 
ROWTERMINATOR = '\n' 
) 

/*SELECT FirstName FROM #FirstName WHERE ID = (
    SELECT RandomNumber FROM (
     SELECT ABS(CHECKSUM(NewID())) % 1500 AS RandomNumber FROM tblTenant WHERE Sex = '1' 
     ) AS A 
    );*/ 

UPDATE tblTenant SET TenantName = ( 
    SELECT LastName + ', ' + FirstName FROM 
     (SELECT UPPER(FirstName) as FirstName FROM #FirstName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 500 + 1501)) AS A, 
     (SELECT LastName FROM #LastName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 200 + 1)) as B 
) WHERE Sex = '2'; 

UPDATE tblTenant SET TenantName = ( 
    SELECT LastName + ', ' + FirstName FROM 
     (SELECT UPPER(FirstName) as FirstName FROM #FirstName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 500 + 1)) AS A, 
     (SELECT LastName FROM #LastName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 200 + 1)) as B 
) WHERE Sex = '1'; 

DROP TABLE #FirstName; 
DROP TABLE #LastName; 
+0

P.S .:的性別=「1」和性別=「2」從當客戶端嘗試外包的發展遺留下來的,但失敗,草草收場。我明白它應該是一個布爾值,或枚舉。 – Malfist 2011-04-29 16:35:41

回答

2

正確的。子查詢計算一次是作爲通告(「超高速緩存標量子查詢」)

嘗試此它使用NEWID作爲派生表

UPDATE T 
SET 
    TenantName = L.LastName + ', ' + F.FirstName 
FROM 
    tblTenant T 
    CROSS APPLY 
    (SELECT TOP 1 UPPER(FirstName) as FirstName FROM #FirstName 
      WHERE CHECKSUM(NEWID()) <> T.ID 
      ORDER BY NEWID()) F 
    CROSS APPLY 
    (SELECT TOP 1 LastName FROM #LastName 
      WHERE CHECKSUM(NEWID()) <> T.ID 
      ORDER BY NEWID()) L 
+0

沒有區別 – Malfist 2011-04-29 16:43:48

+0

Malfist:添加了一個WHERE子句來強制逐行評估...... – gbn 2011-04-29 16:45:40

+0

完美,儘管永久。可能是因爲它每行都在訴諸行動。 – Malfist 2011-04-29 16:47:12

0

我不知道我理解你的問題,但如果你想的ID是唯一的值,你可以把它的標識列。 例如:

[ID] [int] IDENTITY(1,1) NOT NULL 
+0

他們是獨一無二的,我很懶,並且不想查找如何在CSV導入中創建標識工作,所以我使用命令行工具來添加行號。 – Malfist 2011-04-29 16:39:27

+1

你投我的迴應,因爲我誤解你在問什麼,因爲用你的話說你是懶惰的? – 2011-04-29 17:02:34

+0

我沒有投票。 – Malfist 2011-04-29 17:32:36

0

下面的代碼說明了不具有內到外的相關性,在使用上面的CROSS APPLY答案時,舊名稱不能保證與新名稱不同。
WHERE F.Id <> T.Id ORDER BY NEWID()將是姓CROSS內更好地應用

USE tempdb 
GO   
IF OBJECT_ID('tblTenant') IS NOT NULL 
    DROP TABLE tblTenant 
GO 
CREATE TABLE tblTenant 
(
    Id  int, 
    FirstName nvarchar(20), 
    LastName nvarchar(20), 
    Gender bit 
) 
INSERT INTO tblTenant 
VALUES (1, 'Bob' , 'Marley', 1), 
     (2, 'Boz' , 'Skaggs', 1) 

SELECT DISTINCT FirstName 
INTO #FirstNames 
FROM tblTenant 

SELECT DISTINCT LastName 
INTO #LastNames 
FROM tblTenant 

    -- There is a probability > 0 that a tenant's new name = tenants old name 
    SELECT 
     OldFirst = T.FirstName, 
     OldLast = T.LastName, 
     NewFirst = F.FirstName, 
     NewLast = L.LastName 
    FROM 
     tblTenant T 

     CROSS APPLY 
     (
     SELECT TOP 1 UPPER(FirstName) AS FirstName 
     FROM #FirstNames 
     WHERE CHECKSUM(NEWID()) <> T.ID 
     ORDER BY NEWID() 
    ) F 

     CROSS APPLY 
     (
     SELECT TOP 1 LastName 
     FROM #LastNames 
     WHERE CHECKSUM(NEWID()) <> T.ID 
     ORDER BY NEWID() 
    ) L