'SQL Loop through table, get max number and increment at insert
I have two tables, and I'm looping though table1 to see if any records from table2 exists in there. If the table1.IMAGE_NUMBER already exists for that person, add max(table2.IMAGE_NUMBER) + table1.IMAGE_NUMBER before inserting a new record, otherwise just insert without incrementing the IMAGE_NUMBER.
The goal is to not have duplicate IMAGE_NUMBER
Here is my code:
DECLARE @NAME NVARCHAR(50), @ID INT, @IMAGE_NUMBER INT, AGE INT
DECLARE MY_CURSOR CURSOR FOR SELECT NAME, IMAGE_NUMBER, AGE FROM PEOPLE
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @NAME, @ID, @IMAGE_NUMBER, @AGE
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT EXISTS(SELECT R.NAME, RG.ID, R.IMAGE_NUMBER, R.DOB, R.PHONE
FROM REGISTRATION R
LEFT JOIN PEOPLE P ON R.ID = P.ID
WHERE P.NAME = R._NAME
AND P.IMAGE_NUMBER = R.IMAGE_NUMBER
AND P.IS_ACTIVE = 1)
BEGIN
-- how do I increment the image_number + max(R.IMAGE_NUMBER) from registration???
INSERT INTO REGISTRATION(NAME, IMAGE_NUMBER, DOB, AGE)
VALUES(@NAME, @IMAGE_NUMBER, @DOB, @AGE)
END
ELSE IF EXIST(SELECT R.NAME, RG.ID, R.IMAGE_NUMBER, R.DOB, R.PHONE
FROM REGISTRATION R
LEFT JOIN PEOPLE P ON R.ID = P.ID
WHERE P.NAME = R._NAME
AND P.IMAGE_NUMBER = R.IMAGE_NUMBER
AND P.IS_ACTIVE = 1)
BEGIN
UPDATE REGISTRATION SET DATE_PROCESSED=GETUTCDATE()
END
FETCH NEXT FROM MY_CURSOR INTO @NAME, @ID, @IMAGE_NUMBER, @AGE
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
Solution 1:[1]
Ideally you wouldn't bother storing an actual number per each NAME. Just use ROW_NUMBER to calculate a numbering when you query it.
Be that as it may, there are quite a few issues with your current code:
- There is absolutely no need for a cursor (there rarely is), you can do this in one batch operation.
- Even if you wanted a cursor there are major bugs which would prevent your code from working.
- Your first
EXISTSisn't actually comparing each row, it's comparing all rows, so it wouldn't work anyway. LEFT JOINfollowed byWHEREon the same table converts it to anINNER JOINlogically.- Unclear why you need both
DOBandAGE, in fact I don't know why you would store age at all given you can calculate it from the DOB. - Unclear why you have a separate
UPDATEstatement
I'm not exactly sure of your table schema, but it seems you want something like this.
INSERT INTO REGISTRATION (NAME, IMAGE_NUMBER, DOB, AGE, DATE)
SELECT
P.NAME,
ISNULL(R.MAX_NUMBER + 1, P.IMAGE_NUMBER),
P.DOB,
P.AGE,
GETUTCDATE()
FROM PEOPLE P
LEFT JOIN ( -- pre-aggregate existing images and get the max number
SELECT MAX(R.IMAGE_NUMBER) MAX_NUMBER
FROM REGISTRATION R
GROUP BY R.NAME
) R ON P.NAME = R._NAME
WHERE P.IS_ACTIVE = 1;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Charlieface |
