T-SQL中的确定性GUID生成

时间:2011-03-29 10:45:43

标签: tsql guid uniqueidentifier

我必须准备一个脚本,从几个表中选择数据并在表中插入新行,其中存储了某种多对多关系。

因此,基本上,我有两个表uniqueidentifier字段作为主键,另一个表存储来自这些表的两个外键和一些附加数据。它们的主键也是uniqueidentifier

INSERT ResultTable ([primaryKey],[foreignA], [foreignB])
    SELECT  newid(), /* <- Can't have it! */
            @foreignKeyA,
            fb.[primaryKey]
    FROM foreignTableB as fb

问题是我无法使用newid()为生成的数据生成GUID。其中一个要求是,当脚本在相同的表上运行时,脚本会产生相同的结果(包括主键)。因此,我必须提出一个脚本,该脚本将插入基于另外两个uniqueidentifier值生成的uniqueidentifier值的新行。

现在,我不知道任何提供从一个GUID到另一个GUID的映射的函数。可能没有。但我仍然希望听到一些建议和意见。

此外:

  • 我们可以假设任何一对外键在整个表中都是唯一的
  • 我无法更改上述任何表格中的主键字段类型
  • 主要是SQL Server 2005/2008,但有些可能运行SQL Server 2000

提前致谢。

2 个答案:

答案 0 :(得分:2)

这里你最好的答案是生成一个插入语句列表的脚本。 可以从生成动态SQL字符串的另一个脚本生成此脚本。 您可能会迭代地执行此操作,每次循环都会调用guid函数。

最后,您将获得一个插入列表,这些插入可以使用guid以相同的结果多次运行。

但是生成guid的一个方面是时间,所以你永远无法重现guid(这真的是一点点)

答案 1 :(得分:0)

您可以首先使用CHECKSUM从多个列中获取整数值,然后将其转换回GUID:

CREATE TABLE ResultTable ([primaryKey] UNIQUEIDENTIFIER,[foreignA] INT, [foreignB] INT);
CREATE TABLE foreignTableB(primaryKey INT);
INSERT INTO foreignTableB(primaryKey) VALUES (1),(2),(3),(4),(5),(100),(1000);


DECLARE @foreignKeyA INT = 1;

INSERT ResultTable ([primaryKey],[foreignA], [foreignB])
SELECT CAST(CAST(CHECKSUM(@foreignKeyA, fb.primaryKey) AS VARBINARY(4)) AS UNIQUEIDENTIFIER)
      , @foreignKeyA, fb.[primaryKey]
FROM foreignTableB as fb;

SELECT * FROM ResultTable;

db<>fiddle demo