'run a query using EXECUTE BLOCK to prepair a column for an unique-Index

I have a column in a table that I want to use for an unique-index.

My script should make the data unique by concat the id of a record, if the data of current record is duplicate.

I've learned that I need to put this inside a EXECUTE BLOCK.

EXECUTE BLOCK 
AS 
    DECLARE VARIABLE ID BI;
    DECLARE VARIABLE REASON XTXT;
    DECLARE VARIABLE LAST_REASON XTXT = '';

BEGIN
FOR SELECT 
            ID_STATEMENT, 
            REASON 
    FROM 
            STATEMENT
    WHERE
            ID_STATEMENT > 0
    ORDER BY
            REASON ASC
    INTO    :ID, 
            :REASON
DO BEGIN
IF ( REASON = LAST_REASON ) THEN
    UPDATE
          STATEMENT
    SET 
          REASON = :REASON || ' X' || :ID
    WHERE
          ID_STATEMENT = :ID;
END
LAST_REASON = REASON;
END

But I am getting an error-message:

-104 Dynamic SQL Error SQL error code = -104 Token unknown - line 18, column 13

In line 18 starts the into-part, column 13 is the ':' in front of :ID,

I try this under PHP, driver is PDO.



Solution 1:[1]

I've gotten a little further now.

The syntax problem with the colon has been resolved.

The reason I keep getting an error message is because of the colon in the INTO line is a bug in the PDO-driver I use under PHP.

Purely by coincidence, while researching another topic, I have learn that this bug has existed since PHP version 5.6 and at least not yet been eliminated by version 7.3.

This "EXECUTE BLOCK" is running very well:

EXECUTE BLOCK 
AS 
    DECLARE VARIABLE ID BI;
    DECLARE VARIABLE REASON XTXT;
    DECLARE VARIABLE LAST_REASON XTXT = '';
BEGIN
      FOR SELECT 
                  ID_STATEMENT, 
                  REASON 
          FROM 
                  STATEMENT
          WHERE
                  ID_STATEMENT > 0
          ORDER BY
                  REASON ASC
          INTO    :ID, 
                  :REASON
      DO 
        BEGIN
              IF (REASON = LAST_REASON) THEN BEGIN
                  UPDATE
                        STATEMENT
                  SET 
                        REASON = :REASON || ' X' || :ID
                  WHERE
                        ID_STATEMENT = :ID;
              END
              LAST_REASON = REASON;
        END
END

Driver: PHP Interbase- / Firebird-Driver

Important is the "BEGIN" after the "THEN" in the IF-Statement !!!

Solution 2:[2]

As far as I understand you want to make field REASON unique. In this case it is simple:

EXECUTE BLOCK 
AS 
    DECLARE VARIABLE ID BLOB;
    DECLARE VARIABLE REASON XTXT;

BEGIN
FOR SELECT 
            REASON || LIST(ID_STATEMENT, 'X'),
            REASON 
    FROM 
            STATEMENT
    WHERE
            ID_STATEMENT > 0
    GROUP BY
            REASON
    HAVING
            COUNT(*) > 1
    INTO    :ID, 
            :REASON
DO BEGIN
    DELETE FROM
          STATEMENT
    WHERE
          REASON = :REASON;
    INSERT INTO
          STATEMENT
    VALUES
          (:ID, :REASON);
END
END

After that in the table you'll have records with unique REASONs and concatenated IDs.

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
Solution 2 user13964273