Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Выполнение хранимой процедуры Oracle, возвращающей REF CURSOR, с использованием SqlAlchemy

Автор вопроса: zmouserОтветов: 1

У меня есть хранимая процедура, которую я определил в Oracle. В этой процедуре мне нужно вернуть набор записей. Для этого я использую SYS_REFCURSOR, который отлично работает внутри Oracle (и с cx_Oracle, если уж на то пошло). В моем приложении я использую сеансы с областью действия SqlAlchemy для поддержки многопоточности.

Как я могу использовать сеанс с ограниченной областью действия, чтобы вернуть REF CURSOR? Единственный способ, которым я смог заставить это работать, - это объявить курсор вывода с курсором, который активен в сеансе, а затем выполнить хранимую процедуру, как показано ниже:

sql = """
    BEGIN
        example('%s', '%s', '%s', :cur);
    END;
""" % (cid, show, type)

conn = sa_tool.session.connection()
in_cur = conn._Connection__connection.cursor()
out_cur = conn._Connection__connection.cursor()
in_cur.execute(sql, cur=out_cur)
results = out_cur.fetchall()

В идеале я хотел бы избежать использования объекта подключения таким образом и выполнять процедуру, позволяя SqlAlchemy управлять курсорами. Если это невозможно, есть ли причина, по которой выборка займет так много времени?

Спасибо

  • Ну, медлительность, конечно, моя вина, и плохой запрос в хранимой процедуре. Остается вопрос: есть ли лучший способ вызвать хранимую процедуру в SqlAlchemy, используя Oracle REF CURSOR? zmouser 06.12.2011

oraclestored-proceduressqlalchemy

Ответы

Ответ 1 · Roberto Hernandez

Я увидел этот вопрос, на который не ответили, и решил вмешаться. Прежде всего, позвольте мне просто сказать, что для вашего сценария нет лучшего варианта, чем SYS_REFCURSOR. Конечно, у вас есть альтернативы.

Курсор Oracle - это область памяти, в которой хранится инструкция по выполнению оператора SQL. Курсор Ref - это просто указатель на местоположение курсора. SYS_REFCURSOR - это конкретный оракул, определенный типом курсора ref. Таким образом, когда вы возвращаете переменную SYS_REFCURSOR клиенту, вы возвращаете указатель на область памяти, где находится инструкция для выполнения SQL. Теперь ваш клиент может выполнить инструкцию с помощью операции FETCH и получить строки. Так что это наилучший способ вернуть результирующий набор клиенту.

В качестве альтернативы вы можете использовать КОНВЕЙЕРНУЮ ФУНКЦИЮ, но я могу заверить вас, что вы не получите лучшей производительности. У AskTom есть отличное объяснение этого сравнения в этой статье.

https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532870400346178516

Другой сценарий заключается в том, хотите ли вы проанализировать, где потребляется время, либо на этапе EXECUTE, либо на этапе FETCH. Если у вас много времени в FETCH, возможно, вы могли бы рассмотреть возможность передачи данных клиенту другим способом. Если у вас есть проблемы с ВЫПОЛНЕНИЕМ, вам нужно выполнить упражнение по настройке вашей процедуры.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы