У меня есть эта таблица:
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++), и мне нужен он для возврата курсора. Как?
Вы можете написать функцию 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;
в 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
Как обстоит дело:
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++. (Можно сказать, к счастью для меня.; -))
В зависимости от того, какую библиотеку доступа вы используете, это может быть королевская боль или прямо вперед.