我正在使用示例数据创建一个数据库。每次我运行存储过程为我的示例数据库生成一些新数据时,我都想根据表 A(“产品”)中的所有行清除并重新填充表 B(“项目”)。
如果表 A 包含主键值为 1、2、3、4 和 5 的行,我希望表 B 具有表 A 的外键,并将随机数的行插入表 B 中的每个表 A 行。(对于任何给定的“产品”,我们基本上是在货架上放上随机数量的“项目”。)
我正在使用此答案中的代码来生成数字列表。我加入此函数的结果以创建要插入的行:
WITH cte AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY (select 0)) AS i
FROM
sys.columns c1 CROSS JOIN sys.columns c2 CROSS JOIN sys.columns c3
)
SELECT i
FROM cte
WHERE
i BETWEEN @p_Min AND @p_Max AND
i % @p_Increment = 0
随机数在视图中生成(以绕过函数的限制),如下所示:
-- Mock.NewGuid view
SELECT id = ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)))
还有一个返回随机数的函数:
-- Mock.GetRandomInt(min, max) function definition
DECLARE @random int;
SELECT @random = Id % (@MaxValue - @MinValue + 1) FROM Mock.NewGuid;
RETURN @random + @MinValue;
但是,当您查看并执行此代码时...
WITH Products AS
(
SELECT ProductId, ItemCount = Mock.GetRandomInt(1,5)
FROM Product.Product
)
SELECT A = Products.ProductId, B = i
FROM Products
JOIN (SELECT i FROM Mock.GetIntList(1,5,1)) Temp ON
i < Products.ItemCount
ORDER BY ProductId, i
...这会返回一些不一致的结果!
A,B
1,1
1,2
1,3
2,1
2,2
3,2 <-- where is 1?
3,3
4,1
5,3 <-- where is 1, 2?
6,1
我希望,对于每个产品 ID,JOIN 会产生 1-5 行。但是,似乎值被跳过了!对于更大的数据集,这一点更加明显。我最初试图在 Item 中为每个 Product 行生成 20-50 行,但这导致每个产品只有 30-40 行。
问题:知道为什么会这样吗?每个产品都应该插入随机数量的行(1 到 5 之间),并且 B 值应该是连续的!相反,缺少一些数字!
如果我将数字存储在我创建的表中然后加入该表,或者如果我使用递归 CTE,也会发生此问题。
我正在使用 SQL Server 2008R2,但我相信我在我的 2012 数据库上也看到了同样的问题。兼容级别分别为 2008 和 2012。