1

My mind has gone blank...I am missing something obvious trying to write a small script:

I have one table with various ID's:

TBL_USETHISID
nextid int

I have another table with references:

TBL_REFS
ref varchar(6)
thisdate datetime
nextid int

I want to take the ID from TBL_USETHISID and then update TBL_REFS so each row's ID is one more than the previous. I will then select the max(nextid) from TBL_REFS and update TBL_USETHISID with the highest.

I am struggling a bit with this, we have to use this instead of auto-incrememnt fields as these ID's are used across multiple tables.

Obviously I have tried:

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

Thanks for all your help in advance.

EDIT - Sample data:

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 

After update:

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

Then I would UPDATE TBL_USETHISID FROM TBL_REFS a set nextid = max(a.nextid)+1 to update the original table. I hope my formatting is correct, i idented like code for readability.

n34_panda
  • 2,577
  • 5
  • 24
  • 40
  • not getting completely. You want to update nextid of all records of tbl_refs with max(nextid) of tblusethisid. Is it correct? – Roopesh May 12 '14 at 10:02
  • Hi, thanks for replying. Ah, I want to update TBL_REFS with the nextid from TBL_USETHISID. However I am updating a number of records and I want to increase this NEXTID number by 1 each time.... – n34_panda May 12 '14 at 10:04
  • Hi, Provide the sample data and expected output to make the question more clear. Syntactically your query is incorrect. The syntax is `Update TBLREFS SET nextid = TBLUSETHISID.nextid + 1 from TBL_USETHISID`. But it does not seem to fit in your requirement. – Roopesh May 12 '14 at 10:11
  • I will do - I am afraid Ingres uses slightly different Syntax than SQL Server etc and my syntax is correct (I hope). EDIT - original post updated. – n34_panda May 12 '14 at 10:14
  • In SQL server, you can achieve this using CTE. The query is : `;with cte As ( select ref, thisdate, nextid, ROW_NUMBER() over(order by ref) rno from TBL_REFS ) Update cte set nextid = thisid.nextid + rno from tblusethisid thisid` – Roopesh May 12 '14 at 10:33

3 Answers3

2

I would strongly advise you to use SEQUENCEs. That is idiomatic Ingres approach (actually, sequences are SQL:2003 standard, if I remember well, so every good RDBMS which supports SQL should support them).

Unfortunately Actian moved the documentation to a new system which makes it very difficult to create a direct link to a page describing something, so I can't really give you a link here. Please go to http://docs.actian.com , pick Ingres 10 docs (in Options), and open the SQL reference.

In short, make a sequence called, say TBL_REFS_SEQ:

CREATE SEQUENCE TBL_REFS_SEQ; -- Also grant it

Then you can do something like:

UPDATE TBL_REFS 
FROM TBL_USETHISID 
SET nextid = TBL_REFS_SEQ.NEXTVAL;

Sequence also has the CURVAL property.

NOTE: Keep in mind that you need to grant privileges to this newly created sequence if you want it to be accessable by certain users/roles.

From the Ingres 10.0 SQL Reference Guide:

A NEXT VALUE or CURRENT VALUE expression on a particular sequence is evaluated once per row inserted by an INSERT statement, updated by an UPDATE statement, or added to the result set of a SELECT statement. If several occurrences of a NEXT VALUE or CURRENT VALUE expression on the same sequence are coded in a single statement, only one value is computed for each row touched by the statement. If a NEXT VALUE expression and a CURRENT VALUE expression are coded on the same sequence in the same statement, the NEXT VALUE expression is evaluated first, then the CURRENT VALUE expression (assuring they return the same value), regardless of their order in the statement syntax.

DejanLekic
  • 18,787
  • 4
  • 46
  • 77
  • Thanks, I actually forgot to reply here and I did get it working using SEQUENCES. I should note that I wanted the SEQUENCE to start from a specific value from another table and column within the database (max(nextid)) - to achieve this I simply selected the value into a session table, copied it to a file, cat it into a variable in the shell script and then simply used the CREATE SEQUENCE seq_name START WITH $VARIABLE_NAME INCREME.....(is this the best way - it works well but it seems a little long-winded, I couldn't find any documentation to make it easier). Thanks again :P – n34_panda May 23 '14 at 23:04
  • I wonder if `CREATE SEQUENCE` can have subselect... :) That would help you. Try and see. – DejanLekic May 23 '14 at 23:54
  • I did without success, incorrect syntax every time. Not the end of the world, my current method is working - cheers – n34_panda May 24 '14 at 07:46
0

try this,

UPDATE tbl_refs  SET nextid=(SELECT nextid+1 FROM tbl_usethisid)
ravikumar
  • 893
  • 1
  • 8
  • 12
0

The most simplest way is through LOOPS although not the most efficient way. Also not sure about the syntax in ingres as I have never worked on it.

It is also possible through a CTE (again not sure if CTEs work in ingres). Will try and give a solution for that as well.

Till then Check the below code

--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

EDIT: A better solution than LOOP. The table simulation and test value insertion remains as per the above solution. Of course the problem of Ingres doesn't support scalar queries remains so you have to find a work around for this.

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

Hope this helps

samar
  • 5,021
  • 9
  • 47
  • 71
  • I will give this ago but unfortunately i think it will fail for the same reason as the other answer - Ingres (or at least my version) doesn't support scalar queries :(. – n34_panda May 12 '14 at 12:20
  • I think you are talking about this line SET nextid = (SELECT nextid + @StartCount FROM @TBLUSETHISID). For that you can assign the inner select value to a variable and use that variable in the update statement – samar May 12 '14 at 12:23
  • Of course, will try that instead. I've also just read that the OVER clause are not available in Ingres either (trying to find out if they have an alternative). – n34_panda May 12 '14 at 12:25
  • I'll try and get some help converting it to Ingres just now. Note Ingres 10 does support Scalar queries I "think". – n34_panda May 12 '14 at 14:24