我有一个名为FavoriteFruits
的表,其列为NAME
,FRUIT
和GUID
。该表已经填充了名称和水果。所以我们说:
NAME FRUIT GUID
John Apple NULL
John Orange NULL
John Grapes NULL
Peter Canteloupe NULL
Peter Grapefruit NULL
好的,现在我想用新的GUID
(使用GUID
)更新NEWID()
列,但我希望每个不同的名称具有相同的GUID
。所以我希望所有John Smiths
都具有相同的GUID
,我希望Peters
具有相同的GUID
,但GUID
与NAME FRUIT GUID
John Apple f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
John Orange f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
John Grapes f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
Peter Canteloupe e3b1851c-1927-491a-803e-6b3bce9bf223
Peter Grapefruit e3b1851c-1927-491a-803e-6b3bce9bf223
不同一个用于约翰斯。所以现在它看起来像这样:
{{1}}
我可以在更新语句中执行此操作而无需使用游标吗?如果是这样,请举个例子?
谢谢你们......
答案 0 :(得分:6)
更新 CTE将无效,因为it'll evaluate per row。表变量可以工作:
您应该能够使用表变量作为更新数据的源。这是未经测试的,但它看起来像:
DECLARE @n TABLE (Name varchar(10), Guid uniqueidentifier);
INSERT @n
SELECT Name, newid() AS Guid
FROM FavoriteFruits
GROUP BY Name;
UPDATE f
SET f.Guid = n.Guid
FROM @n n
JOIN FavoriteFruits f ON f.Name = n.Name
这样就可以使用每个名称的GUID填充变量,然后将其连接回原始表并相应地进行更新。
答案 1 :(得分:0)
在USING
语句的MERGE
子句中重新表达注释。
以下内容无效,因为it'll evaluate per row:
MERGE INTO FavoriteFruits
USING (
SELECT NAME, NEWID() AS GUID
FROM FavoriteFruits
GROUP
BY NAME
) AS source
ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
UPDATE
SET GUID = source.GUID;
但是,使用表变量的以下内容将起作用:
DECLARE @n TABLE
(
NAME VARCHAR(10) NOT NULL UNIQUE,
GUID UNIQUEIDENTIFIER NOT NULL UNIQUE
);
INSERT INTO @n (NAME, GUID)
SELECT NAME, NEWID()
FROM FavoriteFruits
GROUP
BY NAME;
MERGE INTO FavoriteFruits
USING @n AS source
ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
UPDATE
SET GUID = source.GUID;
答案 2 :(得分:0)
也有单一语句解决方案,但是有一些限制。我的想法是使用OPENQUERY()
,如下所示:
UPDATE FavoriteFruits
SET GUID = n.GUID
FROM (
SELECT NAME, GUID
FROM OPENQUERY(
linkedserver,
'SELECT NAME, NEWID() AS GUID FROM database.schema.FavoriteFruits GROUP BY NAME'
)
) n
WHERE FavoriteFruits.NAME = n.NAME
此解决方案意味着您需要创建一个自我指向的链接服务器。另一个特点是你不能在表变量上使用这个方法,也不能在本地临时表中使用这种方法(全局表和普通表一样)。