Как возвратить набор результатов / курсор из МН Oracle / SQL анонимный блок, который выполняет Динамический SQL?

У меня есть эта таблица:

ALLITEMS
---------------
ItemId  | Areas
---------------
1       | EAST
2       | EAST
3       | SOUTH
4       | WEST

DDL:

drop table allitems;

Create Table Allitems(ItemId Int,areas Varchar2(20));
Insert Into Allitems(Itemid,Areas) Values(1,'east');
Insert Into Allitems(ItemId,areas) Values(2,'east');
insert into allitems(ItemId,areas) values(3,'south');
insert into allitems(ItemId,areas) values(4,'east');

В MSSQL для получения курсора от динамического SQL я могу сделать:

DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT 

В Oracle я должен использовать МН Блок / Блок SQL:

SET AUTOPRINT ON;
DECLARE
 V_Sqlstatement Varchar2(2000);
 outputData SYS_REFCURSOR;
BEGIN
 V_Sqlstatement := 'SELECT * FROM ALLITEMS';
 OPEN outputData for v_Sqlstatement; 
End;
--result is : anonymous block completed

** Но все, что я получаю,

анонимный блок завершается".

Как я заставляю это возвращать курсор?

(Я знаю, что, если я делаю AUTOPRINT, он распечатает информацию в REFCURSOR (он не печатает в коде выше, но это - другая проблема)),

Я буду называть этот Динамический SQL из кода (ODBC, C++), и мне нужен он для возврата курсора. Как?

23
задан ΩmegaMan 16 September 2019 в 20:40
поделиться

3 ответа

Вы можете написать функцию PL / SQL для возврата этого курсора (или вы можете поместить эту функцию в пакет, если у вас есть больше, связанный с этим):

CREATE OR REPLACE FUNCTION get_allitems
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR SELECT * FROM allitems;
  RETURN my_cursor;
END get_allitems;

Это вернет курсор.

Убедитесь, что не кладут ваш , выберите -String в цитаты в PL / SQL, когда это возможно. Положив его в строки означает, что его нельзя проверить во время компиляции, и что он должен быть проанализирован, когда вы его используете.


Если вам действительно нужно использовать динамический SQL, вы можете поместить запрос в отдельные кавычки:

  OPEN my_cursor FOR 'SELECT * FROM allitems';

Эта строка должна быть проанализирована всякий раз, когда вызывается функция, которая обычно будет медленнее и скрывает ошибки в вашем запросе до выполнения времени.

Обязательно используйте переменные связывания, где можно избежать жестких анализа :

  OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;
41
ответ дан 29 November 2019 в 01:55
поделиться

в SQL*Plus также можно использовать REFCURSOR переменную:

SQL> VARIABLE x REFCURSOR
SQL> DECLARE
  2   V_Sqlstatement Varchar2(2000);
  3  BEGIN
  4   V_Sqlstatement := 'SELECT * FROM DUAL';
  5   OPEN :x for v_Sqlstatement;
  6  End;
  7  /

ProcÚdure PL/SQL terminÚe avec succÞs.

SQL> print x;

D
-
X
8
ответ дан 29 November 2019 в 01:55
поделиться

Как обстоит дело:

SELECT CAST(CAST(@number AS float) AS varchar(10))

Однако сначала вы можете проверить это с помощью необработанных данных.

-121--3107603-

Используйте инструменты профилирования, такие как YureKit , JProfiler и HPROF (это инструмент командной строки).

-121--3894439-

Вы должны иметь возможность объявить курсор как переменную привязки (называемую параметрами в других СУБД ')

, как написал Винсент, вы можете сделать что-то подобное:

begin
  open :yourCursor
    for 'SELECT "'|| :someField ||'" from yourTable where x = :y'
      using :someFilterValue;
end;

Вам придется связать 3 vars с этим сценарием. Входная последовательность для «someField», значение для «someFilterValue» и курсор для «yureCursor», который должен быть объявлен как output var.

К сожалению, я понятия не имею, как это сделать из C++. (Можно сказать, к счастью для меня.; -))

В зависимости от того, какую библиотеку доступа вы используете, это может быть королевская боль или прямо вперед.

1
ответ дан 29 November 2019 в 01:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: