0

我不明白为什么这个游标中的变量@NextURLId 没有被更新。这是代码

DECLARE @NextURLId INT = 1
DECLARE @varContact_Id INT

DECLARE GetURL_Cursor CURSOR FOR
    SELECT DISTINCT(contact_id)
    FROM obp.Contacts
OPEN GetURL_Cursor

FETCH NEXT FROM GetURL_Cursor INTO @varContact_id
WHILE @@FETCH_STATUS = 0
BEGIN
-- Available URLs have the used value as NULL. Used has value of 1.
SET @NextURLId = (SELECT MIN(id) FROM obp.URL WHERE used IS NULL)

UPDATE obp.Contacts SET URL = (
    SELECT url from obp.URL WHERE id = @NextURLId)
UPDATE obp.URL SET  
    used = 1,
    contact_id = @varContact_Id,
    date = GETDATE()
 WHERE id = @NextURLId

FETCH NEXT FROM GetURL_Cursor INTO @varContact_id
END;

CLOSE GetURL_Cursor
DEALLOCATE GetURL_Cursor

该代码应该从表 (obp.URL) 中检索一个唯一的 URL,在 Contacts 表中输入该 URL,然后更新该 URL 以指示该 URL 已被使用。在我看来,在使用 'used = 1' 更新 URL 表之后,代码的下一次迭代应该在我查询它时获得一个新的 URLId。

但是,当我运行此代码时,每次都会得到相同的 URL。毫无疑问,我遗漏了一些明显的东西,但需要一些帮助来指出它。

作为一个方面,如果有一个基于集合的解决方案,我会很高兴听到它。

TIA

4

1 回答 1

0

这个

UPDATE obp.Contacts SET URL = (
    SELECT url from obp.URL WHERE id = @NextURLId)

用相同的更新每一行。添加适当的 WHERE 子句,例如

WHERE contact_id=@varContact_id

关于此要求:我了解您希望将联系人与 URL 相关联,并且没有逻辑规则将其与什么相关联。乍一看,我会认为匹配表是正确的方法。对我来说,将这样的关联放在一个单独的表中感觉更好,即使我坚信两个关联对象之间存在 1:1 的关系。obp.URL 和 obp.Contacts 是维度表(我假设/希望)。如果发生更改,将关联保存在一个不同的表中需要一项操作。在您的模型中,更改必须反映在这两个表中。

这是一个这样的表的想法:

create table Contact_URL_match
   (ID int identity (1,1)
   ,URL_id int not null unique
   ,contact_id int not null unique
   ,created datetime)

唯一约束不允许插入相同的 URL 或相同的 Contact_id 两次。在每次插入/更新之前,都会检查重复内容,如果发现该操作将被拒绝,从而保护唯一性。

为了在第一个大型初始动作中显示新匹配,请尝试这个(尚未测试,只是一个想法)

INSERT INTO
  Contact_URL_match
    (URL_id
    ,contact_id
    ,created)
SELECT
  urls.id 
  ,contacts.contact_id      
  ,getdate()
FROM
  (SELECT 
    DISTINCT(contact_id)
    ,ROW_NUMBER() over (ORDER BY contact_id asc) rn
  FROM 
    obp.Contacts) contacts
INNER JOIN
  (SELECT 
    id 
    ,ROW_NUMBER() over (ORDER BY id) rn
  FROM 
    obp.URL) urls
ON
  contacts.rn=urls.rn

在子查询中,这会根据 ORDER BY 子句在两个源表中创建一个行号。然后,它通过该行号连接子查询的结果集,这是一种故意的随机行为。我希望你想要那个。该连接的结果被插入到匹配表中。

如果稍后您想要显示一个新的关联,您可以将 WHERE 子句添加到子查询中,以指定您希望哪个 URL 与哪个联系人匹配。在选择 URL 或联系人之前,请使用 NOT EXISTS 检查匹配表,以确保其中没有使用它。

编辑: 语法错误已清理

于 2013-10-06T04:52:34.210 回答