|
|
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Переходя с MSSQL на Oracle, спотыкаешься на каждом элементарном действии. Создаю хранимую процедуру (для теста упрощенный вариант): Код: plaintext 1. 2. 3. 4. Процедура создается без ошибок. Но когда пытаюсь выполнить ее через SQL+: Код: plaintext 1. Возвращается ругань: Код: plaintext 1. 2. 3. 4. Что я делаю не так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 17:33:36 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
во первых наверное надо быть взять ParamId тоже в кавычки. Оракл преобразует имена в верхний регистр, чтобы это предотвратить надо брать их в кавычки. CREATE OR REPLACE PROCEDURE "GetDBParamsById" ("ParamId" IN number) AS BEGIN EXECUTE IMMEDIATE 'SELECT * FROM "TDBParams" WHERE F_PARAMID = : ParamId' using "ParamId"; END; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:14:40 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
EXECUTE IMMEDIATE 'SELECT * FROM "TDBParams" WHERE F_PARAMID = '||ParamId; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:15:11 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:23:26 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
А как лучше execute immediate 'select param_nm from params where param_id = :ParamID' или EXECUTE IMMEDIATE 'SELECT * FROM "TDBParams" WHERE F_PARAMID= ' || ParamId; Первый вариант снижает количество hard parse? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:28:35 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
на синтаксические ошибки вам уже указали, но главная ошибка, ИМХО - идеологическая! Oracle не позволяет делать простой SELECT (с выводом результата клиенту !) в PL/SQL блоке, коим является любая процедура почитайте о REF CURSOR ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:32:31 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
2 Violina Лучше 1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:34:04 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
2 Violina: Yes, you are correct it will reduce number of hard parses. However, in some cases, using bind variable in CBO can limit CBO abilities to choose "best" plan. For example: Код: plaintext and Код: plaintext Assuming table emp has been analyzed, CBO knows the HIGH and LOW values of 'EMPNO'. For the first of these statements CBO can determine a 'selectivity' of the clause 'WHERE empno > 9999', but for the second it does not know if ':bind1' is '1' or '9999' and thus uses a default selectivity. This is true even when using histograms as CBO does NOT KNOW the value of the bind variable. Hence, the resulting execution plans can be very different. SY ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 18:44:17 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Спасибо за ответы, но вопрос не особо прояснился. Но самый главный вопрос: Мне нужна технология использования хранимых процедур, для которых в результате можно получить ADO Recordset (обычно на основе использования Command(имя SP). Кто-нибудь, кто использует ADO, наверняка уже решал такую проблеиму? 1. Как я понял, лучше сразу писать имена параметров в верхнем регистре, во избежание дальнейших проблем. 2. Вопрос в том, как вернуть данные: использование курсора в MSSQL я всегда старался избегать, т.к. это лишние "тормоза". Разве в Oracle это не так? 3. К тому же, практически взятый один в один пример из доки не желает работать: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 10:50:24 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
to SY Все как всегда оказалось не однозначным. to Finder CREATE OR REPLACE PROCEDURE "GetDBParamsById" (PARAMID IN number) AS CURSOR cur_tdbparams IS SELECT * FROM "TDBParams" WHERE F_PARAMID = PARAMID; BEGIN FOR cur_tdbparams IN cur_tdbparams LOOP DBMS_OUTPUT.put_line(cur_tdbparams.F_PARAMID); END LOOP; CLOSE cur_tdbparams; убрать !!! конструкция FOR сама закрывает курсор END; PS Странно думала что вместо AS надо IS писать, но и с AS тоже работает. Это что альтернативный синтаксис? to all использование курсора в MSSQL я всегда старался избегать, т.к. это лишние "тормоза". Разве в Oracle это не так? А можно в Оракл как то еще кроме как курсором фетчить данные на клиенте? Насколько я поняла при любом селекте используется курсор, просто неявно, или это не так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:05:50 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
to Finder Да и еще FOR cur_tdbparams IN cur_tdbparams LOOP используй другое имя для переменной не совпадающее с курсором. PS Где ж ты такую доку нашел?:-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:11:20 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Гм... С именем переменной действительно ошибочка вышла. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. При запуске из SQL+ Код: plaintext 1. 2. - а данных не выводит!!! Если же напрямую написать SELECT * FROM "TDBParams" WHERE F_PARAMID = 245; запись нормально возвращается. 1. В чем дело? 2. Как вывести все поля записи, не приьегая к явному их перечислению, что то типа DBMS_OUTPUT.put_line(var_tdbparams.*) ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:37:15 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
единственное предположение, что в твоей таблице есть поле PARAMID, тогда используется оно а не параметр PARAMID. Вот пример работающей процедуры, смотри по нему Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:54:23 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
1.\r Код: plaintext 1. 2. 3. \r 2. А куда и где именно все это надо вывести? Упоминалось ADO, вот это не поможет? /topic/31528 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:55:06 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Если же напрямую написать SELECT * FROM "TDBParams" WHERE F_PARAMID = 245; я подумала что ты имеешь ввиду CURSOR cur_tdbparams IS SELECT * FROM "TDBParams" WHERE F_PARAMID = 245; И при этом не выводится. А так ser serverout on должно помочь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 12:02:32 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
> Странно думала что вместо AS надо IS писать, но и с AS тоже работает. Это что альтернативный синтаксис? Разницы нет. Синтаксис PL/SQL создавался на основе Ады, в которой принято IS. AS -- это ближе к стандарту SQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 14:46:48 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
SET SERVEROUT ON вроде помогло, а на указанный в одном из линков вариант \r SET SERVEROUTPUT ON 1000000 шла ругань на неверный параметр "1000000".\r \r В общем, что-то уже начинает получаться. Для работы с хранимой процедурой, возвращающей набор записей (и обработкой его в Recordset):\r \r 1. Создаем пакет с типом курсора\r Код: plaintext 1. 2. 3. 4. 5. \r 2. Создаем ХП, возвращающую REF CURSOR (одно неудобство - чтобы потом протестировать работу ХП в SQL+, в SELECT приходится явно перечислять поля) - как-то все же можно это ограничение обойти?\r Код: plaintext 1. 2. 3. 4. 5. 6. 7. \r 3. Если в ХП явно перечислить поля, ее работу можно протестировать по SQL+:\r Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. \r 4. Заполнить ADO Recordset можно несколько извращенным (с моей точки зрения) способом:\r Код: plaintext 1. 2. 3. Работает! Но хотелось бы разобраться с получением Recordser через Command.\r :(\r \r 5. А вот получить ADO Recordset на основе Command не получается. В стандартном варианте (как это работает с MSSQL) в Command (перед Execute) генерируется строка Command->CommandText вида:\r Код: plaintext 1. 2. - в таком варианте конечно идет ругань о несоответсвии параметров. Здесь каким-то образом надо предварительно добавить выходной параметр типа REF CURSOR - но КАК ЭТО СДЕЛАТЬ???!!!\r \r В /topic/31528 каким-то шаманством с классом TestResultSet это было достигнуто за счет CallableStatement stmt = conn.prepareCall("BEGIN GetEmpRS(?, ?); END;"); \r stmt.setInt(1, 30); // DEPTNO \r stmt.registerOutParameter(2, OracleTypes.CURSOR); //REF CURSOR \r ... но мне эти действия непонятны... к тому же VBA а не VC... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 16:02:08 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
За ADO не скажу, не работал, а в SQLPlus тестирование таких вещей несколько проще (SYS_REFCURSOR - оракловый тип, появившийся в Oracle 9i, иначе подставляй свой пекетный): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 16:19:18 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Тестирование резултатов ХП так действительно работает, и код намного короче. Спасибо! Код: plaintext 1. 2. 3. 4. 5. 6. 7. А вот что делать с ADO Command? Есть версия что надо устанавливать Command->Properties("PLSQLRSet")->Value = COleVariant(true); - только вот свойтсва я такого у Command не нашел. Кто-нибудь работал с ADO? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 16:33:06 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Ты перепутал REFCURSOR и SYS_REFCURSOR. Первое - специальное слово SQL*Plus, второе- тип PL/SQL. Сравни, в 8i придется написать так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 16:40:08 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Я еще много чего путаю. ;) Например, какую команду все же давать для вывода результатов: Код: plaintext 1. 2. 3. 4. ? А по поводу использования Command с REF CURSOR народ молчит. Видимо, или никто не работает с Oracle через ADO, или топик уже слишком большой и никто его не читает... :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 17:15:39 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Смотри: SQL*Plus User's Guide and Reference SET SERVEROUT[PUT] http://technet.oracle.com/docs/products/oracle9i/doc_library/release2/server.920/a90842/ch13.htm#1012919 А про работу Command с REF CURSOR скорее ответят в форумах по Visual C++, либо в туториалах. На MSDN-то ничего нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 17:29:04 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
блин, нельзя ж быть таким ленивым - первая же ссылка на гугле по "REF CURSOR ADO": http://www.google.com.ru/search?q=cache:5jg89SZ-7NEJ:doug.burns.tripod.com/ado.doc+REF+CURSOR+ado&hl=ru&ie=UTF-8 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 17:32:22 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
set serveroutput on; или set serveroutput on size 10000 набери в SQL Plus help set test@ORCL.LOCAL> help set получишь описание команды set ... SERVEROUT[PUT] {ON|OFF} [SIZE n] [FOR[MAT] {WRA[PPED] | WOR[D_WRAPPED] | TRU[NCATED]}] ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 20:22:04 |
|
||
|
EXECUTE StoredProcedure...
|
|||
|---|---|---|---|
|
#18+
Спасибо за ссылки. С SQL+ все понятно, а вот по ADO + REF CURSOR... Проблемы... В приведенной выше ссылке речь шла о провайдере OraOLEDB.Oracle (и там действительно проблема решается устновкой свойства "PLSQLRSet"). В моем же случае надо заставить поддерживать REF CURSOR объект Command для MSDAORA.1! Так что заранее прошу прощения за подробности применения ADO... На буржуйских сайтах предлагают решить проблему с REF CURSOR для Command по-разному: 1. Кто-то скачивает некую утилиту для MSDAORA с http://www.aboves.com/downloads, после этого CommandText перед Execute() приобретает вид типа "begin GETPARAMSDATA (?,{resultset 0,CUR})}". Но этот вариант мне не понравился - какая-то внешняя программа... 2. Кто-то просто подменяет CommandText, т.е. зная заранее о необходимости поддержки REF CURSOR, можно Код: plaintext 1. 2. 3. 4. казалось бы, все просто, но сделать это невозможно. Дело в том что PutCommandText() производит дополнительный парсинг - добавляет слева "{ call" и справа "(?) }: PARAMID=245, ". В итоге при выполнении поучается полная ерунда: Код: plaintext 1. 2. Если установить adCmdText, при дополнительном парсинге добавляются только значения параметров, но там другой синтаксис и куда поместить "{resultset 0,CUR}" совершенно непонятно... Единственный случай, когда вариант 2 заработал - если никаких параметров, кроме REF CURSOR, не требуется. Вариант с подменой CommandText при adCmdStoredProc на "GETPARAMSDATA ({resultset 0,CUR})" работает прекрасно. Но в итоге - использовать подмену CommandText тольком не удалось. 3. Предлагалось заранее зачитывать инфу о параметрах процедуры: Код: plaintext 1. 2. однако это не помогло, т.к. хотя Command и узнает о наличии параметра REF CURSOR, что с ним делать он совершенно не знает и формирует CommandText вида (пример при ХП с одним параметров - REF CURSOR): Код: plaintext 1. такая гениальная строка конечно приводит к ошибке "неверное имя/номер переменной". Так что тоже не помогло. Народ! По-прежнему надеюсь на вашу помощь!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2003, 13:43:51 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=32180803&tid=1989796]: |
0ms |
get settings: |
9ms |
get forum list: |
21ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
228ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
69ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 555ms |

| 0 / 0 |
