我的思绪一片空白......我错过了一些明显的尝试写一个小脚本的东西:
我有一张桌子上有各种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来更新原始表。我希望我的格式是正确的,我认为代码是可读性的。
答案 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
希望这有帮助