SQL-функция Informix внутри курсора FOREACH - PullRequest
0 голосов
/ 01 мая 2018

Informix версии 11.70 - 12.10

Попытка создать хранимую процедуру для получения идентификатора сеанса пользователя, который заблокировал таблицу, а затем выполнить встроенную функцию с использованием этого идентификатора сеанса. Я не пишу слишком много процедур в Informix.

Получение синтаксической ошибки вокруг WITH RESUME.

Любая помощь?

CREATE PROCEDURE sp_kill_lock ()

RETURNING
  INT as User_Session
;

-- declaration of variables
DEFINE rsUser_Session INT;

-- SELECT each User Session that has a lock on a table
SELECT DISTINCT s.sid AS User_Session
FROM sysmaster:syslocks l, sysmaster:syssessions s 
WHERE s.sid = l.owner 
   AND dbsname <> 'sysmaster' 
ORDER BY 1 
INTO TEMP tempSession;

--Cursor
FOREACH 
   SELECT User_Session
   INTO rsUser_Session
   FROM tempSession

RETURN
rsUser_Session;

--kill the session returned
EXECUTE FUNCTION sysadmin:task("onmode","z",rsUser_Session)

WITH RESUME
;

END FOREACH
END PROCEDURE;


 -- Permissions for routine "sp_kill_lock"
 grant execute on function sp_kill_lock to 'public';

Я изменил код, и, по крайней мере, больше не получаю синтаксическую ошибку. Теперь говорится, что функция возвращает слишком много значений:

CREATE PROCEDURE sp_kill_lock ()

RETURNING
  INT as User_Session
;

-- declaration of variables
DEFINE rsUser_Session INT;

-- SELECT each User Session that has a lock on a table
SELECT DISTINCT s.sid AS User_Session
FROM sysmaster:syslocks l, sysmaster:syssessions s 
WHERE s.sid = l.owner 
   AND dbsname <> 'sysmaster' 
ORDER BY 1 
INTO TEMP tempSession;

--Cursor
FOREACH 
   SELECT User_Session
   INTO rsUser_Session
   FROM tempSession

--removed this RETURN
--RETURN
--rsUser_Session;

--kill the session returned
EXECUTE FUNCTION sysadmin:admin("onmode","z",rsUser_Session);

--removed the WITH RESUME

END FOREACH
END PROCEDURE;

Для проверки заблокированной таблицы:

BEGIN WORK;
LOCK TABLE mytable IN EXCLUSIVE MODE

1 Ответ

0 голосов
/ 01 мая 2018

WITH RESUME является частью оператора RETURN, поэтому в вашем первом примере это должно быть:

RETURN rsUser_Session WITH RESUME;

Но при запуске он все равно выдаст ошибку, потому что PROCEDURE не может возвращать значения. Вам нужно изменить его на CREATE FUNCTION.

Тогда он, вероятно, не делает то, что вам нужно, потому что он возвращается до того, как выполнит onmode -z, поэтому, например, если нужно убить только 1 сеанс, он никогда не выполнит onmode -z. Кроме того, он оставляет временную таблицу позади.

Итак, давайте перепишем его, чтобы всегда выполнять onmode -z и не использовать временную таблицу (я использую Informix 12.10.FC10DE):

CREATE FUNCTION sp_kill_lock ()
RETURNING
    INT AS user_session
    , INT AS admin_result
;
-- declaration of variables
DEFINE rsuser_session INT;
DEFINE rsadmin_result INT;

-- SELECT each User Session that has a lock on a table
FOREACH 
    SELECT DISTINCT 
        s.sid AS user_session
    INTO
        rsuser_session
    FROM 
        sysmaster:syslocks AS l
        INNER JOIN 
        sysmaster:syssessions AS s 
        ON
            s.sid = l.owner
    WHERE  
        dbsname <> 'sysmaster' 
    ORDER BY 1 

   LET rsadmin_result = sysadmin:admin('onmode', 'z', rsuser_session);
   -- returning session id and admin execute result which is the value of cmd_number in the table sysadmin:command_history
   RETURN rsuser_session, rsadmin_result WITH RESUME;

END FOREACH
END FUNCTION;
  1. Инструкции SPL Informix
  2. Взаимосвязь Informix между подпрограммами, функциями и процедурами
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...