VirtualBox

Ignore:
Timestamp:
Jun 6, 2016 5:53:01 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
107838
Message:

testmanager: Testboxes can now be members of more than one scheduling group.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/core/testbox.pgsql

    r61468 r61502  
    2626
    2727
    28 ---
    29 -- Checks if the test box name is unique, ignoring a_idTestCaseIgnore.
    30 -- Raises exception if duplicates are found.
    31 --
    32 -- @internal
    33 --
    34 CREATE OR REPLACE FUNCTION TestBoxLogic_checkUniqueName(a_sName TEXT, a_idTestBoxIgnore INTEGER)
    35     RETURNS VOID AS $$
    36     DECLARE
    37         v_cRows INTEGER;
    38     BEGIN
    39         SELECT  COUNT(*) INTO v_cRows
    40         FROM    TestBoxes
    41         WHERE   sName      =  a_sName
    42             AND tsExpire   =  'infinity'::TIMESTAMP
    43             AND idTestBox <> a_idTestBoxIgnore;
    44         IF v_cRows <> 0 THEN
    45             RAISE EXCEPTION 'Duplicate test box name "%" (% times)', a_sName, v_cRows;
    46         END IF;
    47     END;
    48 $$ LANGUAGE plpgsql;
    49 
    50 
    51 ---
    52 -- Historize a row.
    53 -- @internal
    54 --
    55 CREATE OR REPLACE FUNCTION TestBoxLogic_historizeEntry(a_idGenTestBox INTEGER, a_tsExpire TIMESTAMP WITH TIME ZONE)
    56     RETURNS VOID AS $$
    57     DECLARE
    58         v_cUpdatedRows INTEGER;
    59     BEGIN
    60         UPDATE  TestBoxes
    61           SET   tsExpire        = a_tsExpire
    62           WHERE idGenTestBox    = a_idGenTestBox
    63             AND tsExpire        = 'infinity'::TIMESTAMP;
    64         GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT;
    65         IF v_cUpdatedRows <> 1 THEN
    66             IF v_cUpdatedRows = 0 THEN
    67                 RAISE EXCEPTION 'Test box generation ID % is no longer valid', a_idGenTestBox;
    68             END IF;
    69             RAISE EXCEPTION 'Integrity error in TestBoxes: % current rows with idGenTestBox=%', v_cUpdatedRows, a_idGenTestBox;
    70         END IF;
    71     END;
    72 $$ LANGUAGE plpgsql;
    73 
    74 
    75 ---
    76 -- Translate string via the string table.
    77 --
    78 -- @returns NULL if a_sValue is NULL, otherwise a string ID.
    79 --
    80 CREATE OR REPLACE FUNCTION TestBoxLogic_lookupOrFindString(a_sValue TEXT)
    81     RETURNS INTEGER AS $$
    82     DECLARE
    83         v_idStr        INTEGER;
    84         v_cRows        INTEGER;
    85     BEGIN
    86         IF a_sValue IS NULL THEN
    87             RETURN NULL;
    88         END IF;
    89 
    90         SELECT      idStr
    91             INTO    v_idStr
    92             FROM    TestBoxStrTab
    93             WHERE   sValue = a_sValue;
    94         GET DIAGNOSTICS v_cRows = ROW_COUNT;
    95         IF v_cRows = 0 THEN
    96             INSERT INTO TestBoxStrTab (sValue)
    97                 VALUES (a_sValue)
    98                 RETURNING idStr INTO v_idStr;
    99         END IF;
    100         RETURN v_idStr;
    101     END;
    102 $$ LANGUAGE plpgsql;
    103 
    104 
    105 ---
    106 -- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
    107 --
    108 CREATE OR REPLACE function TestBoxLogic_addEntry(a_uidAuthor            INTEGER,
     28--
     29-- Old type signatures.
     30--
     31DROP FUNCTION IF EXISTS TestBoxLogic_addEntry(a_uidAuthor            INTEGER,
    10932                                                 a_ip                   inet,
    11033                                                 a_uuidSystem           uuid,
     
    12043                                                 OUT r_idTestBox        INTEGER,
    12144                                                 OUT r_idGenTestBox     INTEGER,
    122                                                  OUT r_tsEffective      TIMESTAMP WITH TIME ZONE
    123                                                  ) AS $$
    124     DECLARE
    125          v_idStrDescription INTEGER;
    126          v_idStrComment     INTEGER;
    127     BEGIN
    128         PERFORM TestBoxLogic_checkUniqueName(a_sName, -1);
    129 
    130         SELECT TestBoxLogic_lookupOrFindString(a_sDescription) INTO v_idStrDescription;
    131         SELECT TestBoxLogic_lookupOrFindString(a_sComment)     INTO v_idStrComment;
    132 
    133         INSERT INTO TestBoxes (
    134                     tsEffective,         -- 1
    135                     uidAuthor,           -- 2
    136                     ip,                  -- 3
    137                     uuidSystem,          -- 4
    138                     sName,               -- 5
    139                     idStrDescription,    -- 6
    140                     idSchedGroup,        -- 7
    141                     fEnabled,            -- 8
    142                     enmLomKind,          -- 9
    143                     ipLom,               -- 10
    144                     pctScaleTimeout,     -- 11
    145                     idStrComment,        -- 12
    146                     enmPendingCmd )      -- 13
    147             VALUES (CURRENT_TIMESTAMP,   -- 1
    148                     a_uidAuthor,         -- 2
    149                     a_ip,                -- 3
    150                     a_uuidSystem,        -- 4
    151                     a_sName,             -- 5
    152                     v_idStrDescription,  -- 6
    153                     a_idSchedGroup,      -- 7
    154                     a_fEnabled,          -- 8
    155                     a_enmLomKind,        -- 9
    156                     a_ipLom,             -- 10
    157                     a_pctScaleTimeout,   -- 11
    158                     v_idStrComment,      -- 12
    159                     a_enmPendingCmd )    -- 13
    160             RETURNING idTestBox, idGenTestBox, tsEffective INTO r_idTestBox, r_idGenTestBox, r_tsEffective;
    161     END;
    162 $$ LANGUAGE plpgsql;
    163 
    164 ---
    165 -- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
    166 --
    167 CREATE OR REPLACE function TestBoxLogic_editEntry(a_uidAuthor           INTEGER,
     45                                                 OUT r_tsEffective      TIMESTAMP WITH TIME ZONE);
     46DROP FUNCTION IF EXISTS TestBoxLogic_editEntry(a_uidAuthor           INTEGER,
    16847                                                  a_idTestBox           INTEGER,
    16948                                                  a_ip                  inet,
     
    17958                                                  a_enmPendingCmd       TestBoxCmd_T,
    18059                                                  OUT r_idGenTestBox    INTEGER,
     60                                                  OUT r_tsEffective     TIMESTAMP WITH TIME ZONE);
     61DROP FUNCTION IF EXISTS TestBoxLogic_removeEntry(INTEGER, INTEGER, BOOLEAN);
     62DROP FUNCTION IF EXISTS TestBoxLogic_addGroupEntry(a_uidAuthor           INTEGER,
     63                                                   a_idTestBox           INTEGER,
     64                                                   a_idSchedGroup        INTEGER,
     65                                                   a_iSchedPriority      INTEGER,
     66                                                   OUT r_tsEffective     TIMESTAMP WITH TIME ZONE);
     67DROP FUNCTION IF EXISTS    TestBoxLogic_editGroupEntry(a_uidAuthor          INTEGER,
     68                                                       a_idTestBox          INTEGER,
     69                                                       a_idSchedGroup       INTEGER,
     70                                                       a_iSchedPriority     INTEGER,
     71                                                       OUT r_tsEffective    INTEGER);
     72
     73
     74---
     75-- Checks if the test box name is unique, ignoring a_idTestCaseIgnore.
     76-- Raises exception if duplicates are found.
     77--
     78-- @internal
     79--
     80CREATE OR REPLACE FUNCTION TestBoxLogic_checkUniqueName(a_sName TEXT, a_idTestBoxIgnore INTEGER)
     81    RETURNS VOID AS $$
     82    DECLARE
     83        v_cRows INTEGER;
     84    BEGIN
     85        SELECT  COUNT(*) INTO v_cRows
     86        FROM    TestBoxes
     87        WHERE   sName      =  a_sName
     88            AND tsExpire   =  'infinity'::TIMESTAMP
     89            AND idTestBox <> a_idTestBoxIgnore;
     90        IF v_cRows <> 0 THEN
     91            RAISE EXCEPTION 'Duplicate test box name "%" (% times)', a_sName, v_cRows;
     92        END IF;
     93    END;
     94$$ LANGUAGE plpgsql;
     95
     96
     97---
     98-- Checks that the given scheduling group exists.
     99-- Raises exception if it doesn't.
     100--
     101-- @internal
     102--
     103CREATE OR REPLACE FUNCTION TestBoxLogic_checkSchedGroupExists(a_idSchedGroup INTEGER)
     104    RETURNS VOID AS $$
     105    DECLARE
     106        v_cRows INTEGER;
     107    BEGIN
     108        SELECT  COUNT(*) INTO v_cRows
     109        FROM    SchedGroups
     110        WHERE   idSchedGroup = a_idSchedGroup
     111            AND tsExpire     =  'infinity'::TIMESTAMP;
     112        IF v_cRows <> 1 THEN
     113            IF v_cRows = 0 THEN
     114                RAISE EXCEPTION 'Scheduling group with ID % was not found', a_idSchedGroup;
     115            END IF;
     116            RAISE EXCEPTION 'Integrity error in SchedGroups: % current rows with idSchedGroup=%', v_cRows, a_idSchedGroup;
     117        END IF;
     118    END;
     119$$ LANGUAGE plpgsql;
     120
     121
     122---
     123-- Checks that the given testbxo + scheduling group pair does not currently exists.
     124-- Raises exception if it does.
     125--
     126-- @internal
     127--
     128CREATE OR REPLACE FUNCTION TestBoxLogic_checkTestBoxNotInSchedGroup(a_idTestBox INTEGER, a_idSchedGroup INTEGER)
     129    RETURNS VOID AS $$
     130    DECLARE
     131        v_cRows INTEGER;
     132    BEGIN
     133        SELECT  COUNT(*) INTO v_cRows
     134        FROM    TestBoxesInSchedGroups
     135        WHERE   idTestBox    = a_idTestBox
     136            AND idSchedGroup = a_idSchedGroup
     137            AND tsExpire     =  'infinity'::TIMESTAMP;
     138        IF v_cRows <> 0 THEN
     139            RAISE EXCEPTION 'TestBox % is already a member of scheduling group %', a_idTestBox, a_idSchedGroup;
     140        END IF;
     141    END;
     142$$ LANGUAGE plpgsql;
     143
     144
     145---
     146-- Historize a row.
     147-- @internal
     148--
     149CREATE OR REPLACE FUNCTION TestBoxLogic_historizeEntry(a_idGenTestBox INTEGER, a_tsExpire TIMESTAMP WITH TIME ZONE)
     150    RETURNS VOID AS $$
     151    DECLARE
     152        v_cUpdatedRows INTEGER;
     153    BEGIN
     154        UPDATE  TestBoxes
     155          SET   tsExpire        = a_tsExpire
     156          WHERE idGenTestBox    = a_idGenTestBox
     157            AND tsExpire        = 'infinity'::TIMESTAMP;
     158        GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT;
     159        IF v_cUpdatedRows <> 1 THEN
     160            IF v_cUpdatedRows = 0 THEN
     161                RAISE EXCEPTION 'Test box generation ID % is no longer valid', a_idGenTestBox;
     162            END IF;
     163            RAISE EXCEPTION 'Integrity error in TestBoxes: % current rows with idGenTestBox=%', v_cUpdatedRows, a_idGenTestBox;
     164        END IF;
     165    END;
     166$$ LANGUAGE plpgsql;
     167
     168
     169---
     170-- Historize a in-scheduling-group row.
     171-- @internal
     172--
     173CREATE OR REPLACE FUNCTION TestBoxLogic_historizeGroupEntry(a_idTestBox INTEGER,
     174                                                            a_idSchedGroup INTEGER,
     175                                                            a_tsExpire TIMESTAMP WITH TIME ZONE)
     176    RETURNS VOID AS $$
     177    DECLARE
     178        v_cUpdatedRows INTEGER;
     179    BEGIN
     180        UPDATE  TestBoxesInSchedGroups
     181          SET   tsExpire        = a_tsExpire
     182          WHERE idTestBox       = a_idTestBox
     183            AND idSchedGroup    = a_idSchedGroup
     184            AND tsExpire        = 'infinity'::TIMESTAMP;
     185        GET DIAGNOSTICS v_cUpdatedRows = ROW_COUNT;
     186        IF v_cUpdatedRows <> 1 THEN
     187            IF v_cUpdatedRows = 0 THEN
     188                RAISE EXCEPTION 'TestBox ID % / SchedGroup ID % is no longer a valid combination', a_idTestBox, a_idSchedGroup;
     189            END IF;
     190            RAISE EXCEPTION 'Integrity error in TestBoxesInSchedGroups: % current rows for % / %',
     191                v_cUpdatedRows, a_idTestBox, a_idSchedGroup;
     192        END IF;
     193    END;
     194$$ LANGUAGE plpgsql;
     195
     196
     197---
     198-- Translate string via the string table.
     199--
     200-- @returns NULL if a_sValue is NULL, otherwise a string ID.
     201--
     202CREATE OR REPLACE FUNCTION TestBoxLogic_lookupOrFindString(a_sValue TEXT)
     203    RETURNS INTEGER AS $$
     204    DECLARE
     205        v_idStr        INTEGER;
     206        v_cRows        INTEGER;
     207    BEGIN
     208        IF a_sValue IS NULL THEN
     209            RETURN NULL;
     210        END IF;
     211
     212        SELECT      idStr
     213            INTO    v_idStr
     214            FROM    TestBoxStrTab
     215            WHERE   sValue = a_sValue;
     216        GET DIAGNOSTICS v_cRows = ROW_COUNT;
     217        IF v_cRows = 0 THEN
     218            INSERT INTO TestBoxStrTab (sValue)
     219                VALUES (a_sValue)
     220                RETURNING idStr INTO v_idStr;
     221        END IF;
     222        RETURN v_idStr;
     223    END;
     224$$ LANGUAGE plpgsql;
     225
     226
     227---
     228-- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
     229--
     230CREATE OR REPLACE function TestBoxLogic_addEntry(a_uidAuthor            INTEGER,
     231                                                 a_ip                   inet,
     232                                                 a_uuidSystem           uuid,
     233                                                 a_sName                TEXT,
     234                                                 a_sDescription         TEXT,
     235                                                 a_fEnabled             BOOLEAN,
     236                                                 a_enmLomKind           LomKind_T,
     237                                                 a_ipLom                inet,
     238                                                 a_pctScaleTimeout      INTEGER,  -- Actually smallint, but default typing fun.
     239                                                 a_sComment             TEXT,
     240                                                 a_enmPendingCmd        TestBoxCmd_T,
     241                                                 OUT r_idTestBox        INTEGER,
     242                                                 OUT r_idGenTestBox     INTEGER,
     243                                                 OUT r_tsEffective      TIMESTAMP WITH TIME ZONE
     244                                                 ) AS $$
     245    DECLARE
     246         v_idStrDescription INTEGER;
     247         v_idStrComment     INTEGER;
     248    BEGIN
     249        PERFORM TestBoxLogic_checkUniqueName(a_sName, -1);
     250
     251        SELECT TestBoxLogic_lookupOrFindString(a_sDescription) INTO v_idStrDescription;
     252        SELECT TestBoxLogic_lookupOrFindString(a_sComment)     INTO v_idStrComment;
     253
     254        INSERT INTO TestBoxes (
     255                    tsEffective,         -- 1
     256                    uidAuthor,           -- 2
     257                    ip,                  -- 3
     258                    uuidSystem,          -- 4
     259                    sName,               -- 5
     260                    idStrDescription,    -- 6
     261                    fEnabled,            -- 7
     262                    enmLomKind,          -- 8
     263                    ipLom,               -- 9
     264                    pctScaleTimeout,     -- 10
     265                    idStrComment,        -- 11
     266                    enmPendingCmd )      -- 12
     267            VALUES (CURRENT_TIMESTAMP,   -- 1
     268                    a_uidAuthor,         -- 2
     269                    a_ip,                -- 3
     270                    a_uuidSystem,        -- 4
     271                    a_sName,             -- 5
     272                    v_idStrDescription,  -- 6
     273                    a_fEnabled,          -- 7
     274                    a_enmLomKind,        -- 8
     275                    a_ipLom,             -- 9
     276                    a_pctScaleTimeout,   -- 10
     277                    v_idStrComment,      -- 11
     278                    a_enmPendingCmd )    -- 12
     279            RETURNING idTestBox, idGenTestBox, tsEffective INTO r_idTestBox, r_idGenTestBox, r_tsEffective;
     280    END;
     281$$ LANGUAGE plpgsql;
     282
     283
     284CREATE OR REPLACE function TestBoxLogic_addGroupEntry(a_uidAuthor           INTEGER,
     285                                                      a_idTestBox           INTEGER,
     286                                                      a_idSchedGroup        INTEGER,
     287                                                      a_iSchedPriority      INTEGER,
     288                                                      OUT r_tsEffective     TIMESTAMP WITH TIME ZONE
     289                                                      ) AS $$
     290    BEGIN
     291        PERFORM TestBoxLogic_checkSchedGroupExists(a_idSchedGroup);
     292        PERFORM TestBoxLogic_checkTestBoxNotInSchedGroup(a_idTestBox, a_idSchedGroup);
     293
     294        INSERT INTO TestBoxesInSchedGroups (
     295                    idTestBox,
     296                    idSchedGroup,
     297                    tsEffective,
     298                    tsExpire,
     299                    uidAuthor,
     300                    iSchedPriority)
     301            VALUES (a_idTestBox,
     302                    a_idSchedGroup,
     303                    CURRENT_TIMESTAMP,
     304                    'infinity'::TIMESTAMP,
     305                    a_uidAuthor,
     306                    a_iSchedPriority)
     307            RETURNING tsEffective INTO r_tsEffective;
     308    END;
     309$$ LANGUAGE plpgsql;
     310
     311
     312---
     313-- Only adds the user settable parts of the row, i.e. not what TestBoxLogic_updateOnSignOn touches.
     314--
     315CREATE OR REPLACE function TestBoxLogic_editEntry(a_uidAuthor           INTEGER,
     316                                                  a_idTestBox           INTEGER,
     317                                                  a_ip                  inet,
     318                                                  a_uuidSystem          uuid,
     319                                                  a_sName               TEXT,
     320                                                  a_sDescription        TEXT,
     321                                                  a_fEnabled            BOOLEAN,
     322                                                  a_enmLomKind          LomKind_T,
     323                                                  a_ipLom               inet,
     324                                                  a_pctScaleTimeout     INTEGER, -- Actually smallint, but default typing fun.
     325                                                  a_sComment            TEXT,
     326                                                  a_enmPendingCmd       TestBoxCmd_T,
     327                                                  OUT r_idGenTestBox    INTEGER,
    181328                                                  OUT r_tsEffective     TIMESTAMP WITH TIME ZONE
    182329                                                  ) AS $$
     
    204351        v_Row.sName             := a_sName;
    205352        v_Row.idStrDescription  := v_idStrDescription;
    206         v_Row.idSchedGroup      := a_idSchedGroup;
    207353        v_Row.fEnabled          := a_fEnabled;
    208354        v_Row.enmLomKind        := a_enmLomKind;
     
    225371
    226372
    227 DROP FUNCTION IF EXISTS TestBoxLogic_removeEntry(INTEGER, INTEGER, BOOLEAN);
     373CREATE OR REPLACE function TestBoxLogic_editGroupEntry(a_uidAuthor          INTEGER,
     374                                                       a_idTestBox          INTEGER,
     375                                                       a_idSchedGroup       INTEGER,
     376                                                       a_iSchedPriority     INTEGER,
     377                                                       OUT r_tsEffective    TIMESTAMP WITH TIME ZONE
     378                                                       ) AS $$
     379    DECLARE
     380        v_Row               TestBoxesInSchedGroups%ROWTYPE;
     381        v_idStrDescription  INTEGER;
     382        v_idStrComment      INTEGER;
     383    BEGIN
     384        PERFORM TestBoxLogic_checkSchedGroupExists(a_idSchedGroup);
     385
     386        -- Fetch and historize the current row - there must be one.
     387        UPDATE      TestBoxesInSchedGroups
     388            SET     tsExpire     = CURRENT_TIMESTAMP
     389            WHERE   idTestBox    = a_idTestBox
     390                AND idSchedGroup = a_idSchedGroup
     391                AND tsExpire     = 'infinity'::TIMESTAMP
     392            RETURNING * INTO STRICT v_Row;
     393
     394        -- Modify the row with the new data.
     395        v_Row.uidAuthor         := a_uidAuthor;
     396        v_Row.iSchedPriority    := a_iSchedPriority;
     397        v_Row.tsEffective       := v_Row.tsExpire;
     398        r_tsEffective           := v_Row.tsExpire;
     399        v_Row.tsExpire          := 'infinity'::TIMESTAMP;
     400
     401        -- Insert the modified row.
     402        INSERT INTO TestBoxesInSchedGroups VALUES (v_Row.*);
     403    END;
     404$$ LANGUAGE plpgsql;
     405
     406
    228407CREATE OR REPLACE FUNCTION TestBoxLogic_removeEntry(a_uidAuthor INTEGER, a_idTestBox INTEGER, a_fCascade BOOLEAN)
    229408    RETURNS VOID AS $$
     
    242421            RAISE EXCEPTION 'CASCADE test box deletion is not implemented';
    243422        END IF;
     423
     424        --
     425        -- Delete all current groups, skipping history since we're also deleting the testbox.
     426        --
     427        UPDATE      TestBoxesInSchedGroups
     428            SET     tsExpire = CURRENT_TIMESTAMP
     429            WHERE   idTestBox   = a_idTestBox
     430                AND tsExpire    = 'infinity'::TIMESTAMP;
    244431
    245432        --
     
    271458        WHEN TOO_MANY_ROWS THEN
    272459            RAISE EXCEPTION 'Integrity error in TestBoxes: Too many current rows for %', a_idTestBox;
     460    END;
     461$$ LANGUAGE plpgsql;
     462
     463
     464CREATE OR REPLACE FUNCTION TestBoxLogic_removeGroupEntry(a_uidAuthor INTEGER, a_idTestBox INTEGER, a_idSchedGroup INTEGER)
     465    RETURNS VOID AS $$
     466    DECLARE
     467        v_Row           TestBoxesInSchedGroups%ROWTYPE;
     468        v_tsEffective   TIMESTAMP WITH TIME ZONE;
     469    BEGIN
     470        --
     471        -- To preserve the information about who deleted the record, we try to
     472        -- add a dummy record which expires immediately.  I say try because of
     473        -- the primary key, we must let the new record be valid for 1 us. :-(
     474        --
     475        SELECT  * INTO STRICT v_Row
     476        FROM    TestBoxesInSchedGroups
     477        WHERE   idTestBox    = a_idTestBox
     478            AND idSchedGroup = a_idSchedGroup
     479            AND tsExpire     = 'infinity'::TIMESTAMP;
     480
     481        v_tsEffective := CURRENT_TIMESTAMP - INTERVAL '1 microsecond';
     482        IF v_Row.tsEffective < v_tsEffective THEN
     483            PERFORM TestBoxLogic_historizeGroupEntry(a_idTestBox, a_idSchedGroup, v_tsEffective);
     484
     485            v_Row.tsEffective   := v_tsEffective;
     486            v_Row.tsExpire      := CURRENT_TIMESTAMP;
     487            v_Row.uidAuthor     := a_uidAuthor;
     488            INSERT INTO TestBoxesInSchedGroups VALUES (v_Row.*);
     489        ELSE
     490            PERFORM TestBoxLogic_historizeGroupEntry(a_idTestBox, a_idSchedGroup, CURRENT_TIMESTAMP);
     491        END IF;
     492
     493    EXCEPTION
     494        WHEN NO_DATA_FOUND THEN
     495            RAISE EXCEPTION 'TestBox #% does is not currently a member of scheduling group #%', a_idTestBox, a_idSchedGroup;
     496        WHEN TOO_MANY_ROWS THEN
     497            RAISE EXCEPTION 'Integrity error in TestBoxesInSchedGroups: Too many current rows for % / %',
     498                a_idTestBox, a_idSchedGroup;
    273499    END;
    274500$$ LANGUAGE plpgsql;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette