游标变量未更新

时间:2013-10-06 04:36:16

标签: sql-server tsql

我不明白为什么这个游标中的变量@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。在我看来,在使用'使用= 1'更新URL表后然后,当我查询它时,代码的下一次迭代应该得到一个新的URLId。

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

作为一方,如果有基于设定的解决方案,我很乐意听到。

TIA

1 个答案:

答案 0 :(得分: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子句在两个源表中创建行号。然后它通过该rownumber加入子查询的结果集,这是一种故意随机的行为。我希望你想要那个。该连接的结果将插入到匹配表中。

如果以后要显示单个新关联,则可以将WHERE子句添加到子查询中,以指定要与Contact匹配的URL。在选择URL或联系人之前,请使用NOT EXISTS检查匹配表,以确保它没有在那里使用。

编辑:语法错误已清除