2012-01-02 2 views
1

Я хотел бы вернуть несколько курсоров в одну процедуру, основанную на другой.PLSQL: процедура вывода нескольких курсоров

Мои в настоящее время код:

TYPE REFCURSOR IS REF CURSOR; 

PROCEDURE GETCARS(oCARS OUT REFCURSOR) 
BEGIN 
    OPEN oCARS FOR SELECT * FROM CARS; 
END GETCARS; 

Я не уверен, если это Возможное, но я хочу сделать что-то вроде:

PROCEDURE GETCARS(oCARS OUT REFCURSOR, oREPAIRS OUT REFCURSOR) 
BEGIN 
    OPEN oCARS FOR SELECT * FROM CARS; 
    ..??.. 
END GETCARS; 

, который будет возвращать в качестве второго параметра все ремонты, связанные с в настоящее время выбрана строка oCARS. (Ремонт стола имеет FK для id_car из автомобилей)

Теперь я делаю это на стороне C#, когда я беру одну строку из курсора oCARS. Я вызываю вторую процедуру, которая дает мне список ремонтов, но, возможно, это возможно сделать это в одной процедуре (что дало бы мне выигрыш в производительности? - Я не хочу использовать присоединиться, потому что она возвращает умноженные автомобили для каждого ремонта)

+0

Почему бы не пройти 2 процедуры (getcars и getrepairs)? Или еще лучше, просто выберите то, что вам нужно, когда вам это нужно: выберите * из автомобилей вместо exec getcars() – tbone

+0

Вызов плоскости выбора менее безопасен, чем вызов параметризованной процедуры (защита от вторжения sql). Я ДУМАЮ, что вызов двух процедур менее эффективен. У меня была надежда на некоторый опыт других здесь. –

+1

Вызов корректно параметризованного оператора select не менее безопасен, чем вызов процедуры. Пока вы не объединяете значения параметров в оператор select, вектора для SQL-инъекции нет. – Allan

ответ

1

Простой ответ заключается в том, что вы не можете делать то, что вы пытаетесь.

Курсоры в основном просто указывают на начало набора результатов, содержащего результаты запроса. Пока вы не получите строку, нет способа узнать, что будет содержать эта строка. Поскольку ваше приложение, а не код PL/SQL, делает выборку, часть PL/SQL не знает возвращаемых значений.

Чтобы сделать то, что вы пытаетесь сделать, база данных должна будет обнаружить выборку из первого запроса, создать новый результирующий набор, используя второй запрос, затем поместить новый результирующий набор по адресу, который первоначально была возвращена процедуре второй курсор. Базы данных просто не предназначены для такого рода операций.

2

Как о

PROCEDURE GETCARS(oCARS OUT SYS_REFCURSOR, oREPAIRS OUT SYS_REFCURSOR, oCHARGES OUT SYS_REFCURSOR) 
BEGIN 
    OPEN oCARS FOR SELECT * FROM CARS; 
    OPEN oREPAIRS FOR SELECT * FROM REPAIRS; 
    OPEN oCHARGES FOR SELECT * FROM CHARGES; 
END GETCARS; 

Делите и наслаждайтесь.

+0

Это хорошо, почти хорошо, когда я хочу вернуть все oCars. Но, если я добавлю дополнительный код, для разбивки на страницы или даты на некоторые поля, курсоры отдыха вернут мне больше, чем мне нужно. Я надеялся на какую-то идею, которая позволила бы мне привязаться к идентификатору текущей выборки в oCars и на основе этого изменения, возвращающего oRepairs. Что-то вроде: OPEN oRepairs для выбора * от ремонта, где id_car = ocars.id_car Я не уверен, что это возможно. –

+2

@XXs - почему бы вам не рассказать * все ваше требование * вместо того, чтобы тратить время людей на это «да, но» schtick? – APC

+0

узнайте, как читать ", который будет возвращать в качестве второго параметра все исправления, связанные с текущей выведенной строкой oCARS.". Да, я хотел улучшить производительность, вернув всю БД курсорами .. -.- Ага, и когда я задаю вопрос здесь, я прошу раздвижное решение, а не простейшее. –

Смежные вопросы