У меня есть таблица с именем Table1. В нем много столбцов, один из них - столбец1. Я не знаю других столбцов, иногда они могут меняться. Существует строго типизированный тип курсора ref, который возвращает Table1% rowtype с именем cur_Table1. У меня есть хранимая процедура с именем SP1, у которой есть параметр out типа cur_Table1. Я вызываю эту хранимую процедуру SP1 из другой базы данных, которая видит только эту хранимую процедуру, но не таблицу или сам тип. Как выбрать только Column1 из возвращаемого курсора? Я знаю, что могу получить запись или столько переменных, сколько курсор имеет столбцы, но я знаю только о существовании одного столбца, поэтому я не могу объявить полную запись или правильное количество переменных.Oracle - выберите конкретный столбец из курсора ref
ответ
Вы можете сделать это с помощью DBMS_SQL
, но это не очень.
Таблица и примеры данных (COLUMN1 имеет число 1 - 10):
create table table1(column1 number, column2 date, column3 varchar2(1000), column4 clob);
insert into table1
select level, sysdate, level, level from dual connect by level <= 10;
commit;
Пакет с процедурой, которая открывает реф курсор и выбирает все:
create or replace package test_pkg is
type cur_Table1 is ref cursor return table1%rowtype;
procedure sp1(p_cursor in out cur_table1);
end;
/
create or replace package body test_pkg is
procedure sp1(p_cursor in out cur_table1) is
begin
open p_cursor for select column1, column2, column3, column4 from table1;
end;
end;
/
PL/SQL, который считывает данные COLUMN1 из курсора ref:
--Basic steps are: call procedure, convert cursor, describe and find columns,
--then fetch rows and retrieve column values.
--
--Each possible data type for COLUMN1 needs to be added here.
--Currently only NUMBER is supported.
declare
v_cursor sys_refcursor;
v_cursor_number number;
v_columns number;
v_desc_tab dbms_sql.desc_tab;
v_position number;
v_typecode number;
v_number_value number;
begin
--Call procedure to open cursor
test_pkg.sp1(v_cursor);
--Convert cursor to DBMS_SQL cursor
v_cursor_number := dbms_sql.to_cursor_number(rc => v_cursor);
--Get information on the columns
dbms_sql.describe_columns(v_cursor_number, v_columns, v_desc_tab);
--Loop through all the columns, find COLUMN1 position and type
for i in 1 .. v_desc_tab.count loop
if v_desc_tab(i).col_name = 'COLUMN1' then
v_position := i;
v_typecode := v_desc_tab(i).col_type;
--Pick COLUMN1 to be selected.
if v_typecode = dbms_types.typecode_number then
dbms_sql.define_column(v_cursor_number, i, v_number_value);
--...repeat for every possible type.
end if;
end if;
end loop;
--Fetch all the rows, then get the relevant column value and print it
while dbms_sql.fetch_rows(v_cursor_number) > 0 loop
if v_typecode = dbms_types.typecode_number then
dbms_sql.column_value(v_cursor_number, v_position, v_number_value);
dbms_output.put_line('Value: '||v_number_value);
--...repeat for every possible type
end if;
end loop;
end;
/
Вау ... и я подумал, что это будет нечто тривиальное, как «select column1 from cursor». – fejesjoco
Не знаете, является ли это опцией или нет, но не лучшим решением было бы создать функцию, которая возвращает нужное значение, которое вы ищете? Это позволяет избежать накладных расходов на отправку дополнительных данных. Кроме того, вы можете определить курсор с набором известных в нем полей, о которых знают обе стороны.
У меня нет контроля над базой данных SP, мне просто нужно позвонить ему из другого места в качестве стороннего клиента. – fejesjoco
Учитывая исходный вопрос, ответ jonearles по-прежнему верен, поэтому я оставлю его помеченным как таковой, но я закончил делать что-то совершенно другое и намного лучше.
Проблема заключалась в том, что я не контролирую базу данных SP1, мне просто нужно позвонить ей из другого места в качестве стороннего клиента. Теперь мне удалось получить разрешение видеть не только SP, но и тип курсора. Я до сих пор не видите таблицу, но теперь есть намного чище решение:
В другой базе данных я был предоставлен доступ к этому типу сейчас:
type cur_Table1 is ref cursor return Table1%rowtype;
Так в моей базе данных я могу сделать это сейчас:
mycursor OtherDB.cur_Table1;
myrecord mycursor%rowtype;
...
OtherDB.SP1(mycursor);
fetch mycursor into myrecord;
dbms_output.put_line(myrecord.Column1);
См., Мне все еще не нужен доступ к таблице, я вижу только курсор. Ключ состоит в том, что магический% rowtype работает и для курсоров, а не только для таблиц. Он не работает на sys_refcursor, но он работает на строго типизированном. Учитывая этот код, мне не нужно волноваться, если что-то изменится с другой стороны, мне не нужно определять все столбцы или записи вообще, я просто указываю один интересующий меня столбец.
Мне очень нравится это отношение ООП к Oracle.
- 1. Возвращение курсора ref из функции Oracle
- 2. Вывод результатов из курсора Oracle Ref
- 3. выберите конкретный столбец из pandas DataFrame MultiIndex
- 4. Выберите конкретный столбец из laravel eloquent model
- 5. Ebean Выберите только конкретный столбец
- 6. sqlalchemy Oracle REF CURSOR
- 7. закрытие курсора ref от coldfusion
- 8. Изменение Oracle Ref Cursor
- 9. Laravel выберите конкретный столбец при загрузке коллекции
- 10. Oracle - Как получить параметр курсора ref в хранимой процедуре?
- 11. Выберите конкретный столбец из SQL-запроса как определенный массив?
- 12. Выберите конкретный столбец в DF и случайный столбец (python3, pandas)
- 13. Oracle Ref Cursor Vs Выберите в с обработкой исключений
- 14. Получение курсора Ref с помощью классического ASP
- 15. Проблема с определением слабо определенного курсора ref
- 16. Выберите конкретный номер из массива?
- 17. Выберите конкретный элемент из списка
- 18. Выберите конкретный ключ из массива
- 19. извлечь конкретный столбец из Listview
- 20. Выберите из нескольких столов oracle
- 21. PHP Oracle Ref Cursor
- 22. Выбрать оператор REF oracle
- 23. REF CURSOR получить столбец из процедуры
- 24. Выберите записи из таблицы Oracle, где единственный столбец уникален
- 25. Выберите столбец BLOB из Oracle DB с помощью mybatis
- 26. выберите из таблицы oracle, где столбец в таблице sqlserver
- 27. Oracle: Выберите из отобранного
- 28. Выберите Distinct столбец и другой столбец - Oracle Hibernate
- 29. Oracle читает n-й столбец с помощью курсора
- 30. Oracle SQL: обновить столбец из списка
Просьба пояснить, как вы предлагаете вызывать процедуру в другой базе данных (или любой другой базе данных, если на то пошло), не имея возможности видеть типы аргументов. –
Я выполнил «предоставление выполнения на SP другому», но не предоставил ничего другого, кроме таблицы или типа. И это работает. – fejesjoco
О, и на вызывающей стороне я, конечно, поместил параметр out из SP в sys_refcursor. – fejesjoco