SQL Update,将值递增1

时间:2014-05-12 09:48:36

标签: sql ingres

我的思绪一片空白......我错过了一些明显的尝试写一个小脚本的东西:

我有一张桌子上有各种ID:

TBL_USETHISID
nextid int

我有另一张参考表:

TBL_REFS
ref varchar(6)
thisdate datetime
nextid int

我想从TBL_USETHISID获取ID,然后更新TBL_REFS,以便每行的ID比前一个ID多一个。然后,我将从TBL_REFS中选择max(nextid)并更新最高的TBL_USETHISID。

我正在努力解决这个问题,我们必须使用它而不是自动增量字段,因为这些ID用于多个表。

显然我已经尝试过:

UPDATE TBL_REFS FROM TBL_USETHISID
SET nextid = TBL_USETHISID.nextid + 1

提前感谢您的帮助。

编辑 - 样本数据:

TBLUSETHISID:

nextid
7001

TBL_REFS

ref       thisdate               nextid
0000123   2012-10-02 00:00:00        
0000124   2012-10-02 00:00:00 
0000125   2012-10-02 00:00:00 

更新后:

TBL_REFS

ref       thisdate               nextid
0000123   2012-10-02 00:00:00    7001    
0000124   2012-10-02 00:00:00    7002
0000125   2012-10-02 00:00:00    7003

然后我会从TBL_REFS UPDATE TBL_USETHISID设置nextid = max(a.nextid)+1来更新原始表。我希望我的格式是正确的,我认为代码是可读性的。

3 个答案:

答案 0 :(得分:2)

我强烈建议你使用SEQUENCEs。这是惯用的Ingres方法(实际上,序列是SQL:2003标准,如果我记得很清楚,那么每个支持SQL的优秀RDBMS都应该支持它们。)

不幸的是,Actian将文档移动到一个新系统,这使得创建描述某个页面的页面的直接链接非常困难,所以我无法在这里给你一个链接。请转到http://docs.actian.com,选择Ingres 10文档(在选项中),然后打开SQL参考。

简而言之,创建一个名为TBL_REFS_SEQ的序列:

CREATE SEQUENCE TBL_REFS_SEQ; -- Also grant it

然后你可以做类似的事情:

UPDATE TBL_REFS 
FROM TBL_USETHISID 
SET nextid = TBL_REFS_SEQ.NEXTVAL;

序列也有CURVAL属性。

注意:请记住,如果您希望特定用户/角色可以访问此序列,则需要为此新创建的序列授予权限。

来自 Ingres 10.0 SQL参考指南

  

对于特定序列的NEXT VALUE或CURRENT VALUE表达式,每行由INSERT语句插入一次,由UPDATE语句更新,或者添加到SELECT语句的结果集中。如果在同一序列中多次出现NEXT VALUE或CURRENT VALUE表达式在单个语句中编码,则只为该语句触及的每一​​行计算一个值。如果NEXT VALUE表达式和CURRENT VALUE表达式在同一语句中的相同序列上编码,则首先计算NEXT VALUE表达式,然后计算CURRENT VALUE表达式(确保它们返回相同的值),而不管它们在语句中的顺序如何语法。

答案 1 :(得分:0)

试试这个,

UPDATE tbl_refs  SET nextid=(SELECT nextid+1 FROM tbl_usethisid)

答案 2 :(得分:0)

最简单的方法是通过LOOPS,但不是最有效的方法。也不确定ingres中的语法,因为我从未使用过它。

也可以通过CTE(再次不确定CTE是否在ingres中工作)。也会尝试为此提供解决方案。

然后检查以下代码

--simulated table structure
DECLARE @TBLUSETHISID TABLE
(
    nextid INT
)

DECLARE @TBL_REFS TABLE
(
    ref varchar(6),
    thisdate datetime,
    nextid int
)

-- values for testing
INSERT INTO @TBLUSETHISID VALUES(7001);

INSERT INTO @TBL_REFS VALUES('000123', '2012-10-02 00:00:00', null);
INSERT INTO @TBL_REFS VALUES('000124', '2012-10-02 00:00:00', null);
INSERT INTO @TBL_REFS VALUES('000125', '2012-10-02 00:00:00', null);

--solution starts from here
DECLARE @StartCount INT, @TotalCount INT, @REF VARCHAR(6)

SELECT @TotalCount = COUNT(*) - 1 FROM @TBL_REFS;
SET @StartCount = 0;

WHILE(@StartCount <= @TotalCount)
BEGIN
    SELECT @REF = ref FROM (SELECT ROW_NUMBER() over(ORDER BY ref) AS ROWNUM, * FROM @TBL_REFS) as tbl WHERE ROWNUM = @StartCount + 1

    UPDATE @TBL_REFS
    SET nextid = (SELECT nextid + @StartCount FROM @TBLUSETHISID)
    WHERE ref = @REF

    SET @StartCount = @StartCount + 1

END

UPDATE @TBLUSETHISID
SET nextid = (SELECT MAX(nextid) + 1 FROM @TBL_REFS)

SELECT * FROM @TBLUSETHISID
SELECT * FROM @TBL_REFS

修改LOOP更好的解决方案。表模拟和测试值插入保持按照上述解决方案。当然Ingres doesn't support scalar queries的问题仍然存在,所以你必须为此找到解决办法。

UPDATE tbl2
SET nextid = (tbl.nextid + ROWNUM - 1) 
FROM
(SELECT ROW_NUMBER() over(ORDER BY ref) AS ROWNUM, 
ref,
thisdate,
(SELECT nextid FROM @TBLUSETHISID) AS nextid FROM @TBL_REFS) tbl
INNER JOIN @TBL_REFS tbl2
ON tbl.ref = tbl2.ref

希望这有帮助