Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.03.19;
Скачать: CL | DM;

Вниз

PHP & Oracle. Помогите выполнить блок   Найти похожие ветки 

 
SergP.   (2006-02-23 16:17) [0]

Вобщем делаю так:

...
$fn="declare
   p1 date := to_date("$dpb","dd.mm.yyyy");
   p2 date := to_date("$dpe","dd.mm.yyyy");
   p5 date := to_date("$dmb","dd.mm.yyyy");
   p6 date := to_date("$dme","dd.mm.yyyy");
   p7 number := 1;
   p9 number := 300;
   p10 number := 1;
   p11 number := 1;

begin                                
   for abc in
   (                                
       select distinct c.ModDate, c.PerType, f.CharCode
       from card c,".""FORM""." f, ( select distinct CharCode From FormRow ) fr
       where c.".""FORM""." = f.code
         and f.CharCode = fr.CharCode
         and c.PerDate between p1 and p2
         and c.ModDate between p5 and p6    
   ) loop
   DataOutput(
                  par1 => p1,          par2 => p2,
                  par3 => abc.PerType, par4 => abc.CharCode,
                  par5 => abc.ModDate, par6 => abc.ModDate
                 );
   end loop;
end;";

         $c1 = ocilogon($scheme,$password,$db);
         $stmt=oci_parse($c1,$fn);
         OCI_execute($stmt);
...


Без всяких проверок, но это пока потому что нужно отладить чтобы заработало...

Пробовал в $fn подставлять какой-нить запрос типа select * from ... - работает без проблем, а вышеуказанный блок не хочет..., хотя если запускать его в sqlplus, то работает...

А когда запускаю из PHP - получаю:


Warning: oci_execute() [function.oci-execute]: OCIStmtExecute: ORA-06550: line 1, column 8: PLS-00103: Encountered the symbol "" when expecting one of the following: begin function package pragma procedure subtype type use <an identifier> <a double-quoted delimited-identifier> form current cursor The symbol "" was ignored. ORA-06550: line 2, column 51: PLS-00103: Encountered the symbol "" when expecting one of the following: begin function package pragma procedure subtype type use <an identifier> <a double-quoted delimited-identifier> form current in c:\MWEB\HTDOCS\best\index.php on line 51


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


 
SergP.   (2006-02-23 17:30) [1]

Или подскажите какой-нить хороший форум по сабжу...


 
McSimm ©   (2006-02-23 17:33) [2]

а вообще есть возможность выполнять несколько statements одним вызовом?
С Oracle я не работал, но для некоторых других так делать нельзя.


 
by ©   (2006-02-23 17:45) [3]

SergP.   (23.02.06 17:30) [1]
а вообще есть возможность выполнять несколько statements одним вызовом

Судя по всему это не несколько statements, а блок pl|sql кода в котором используется select с inline view.
А версия Oracle какая?
И судя по ошибкам, тут пролемы с кавычками, что данная фраза значит? ,".""FORM""." - это имя таблицы? так зачем сколько кавычек?


 
SergP.   (2006-02-23 19:03) [4]


> by ©   (23.02.06 17:45) [3]


Oracle9i

в PHP используется php_oci8.dll

да, это блок PL/SQL


> И судя по ошибкам, тут пролемы с кавычками, что данная фраза
> значит? ,".""FORM""." - это имя таблицы? так зачем сколько
> кавычек?


пробовал без кавычек, все равно не работает... А в sqlplus и с кавычками работает...


 
SergP ©   (2006-02-24 09:13) [5]


> OCIStmtExecute: ORA-06550: line 1, column 8: PLS-00103:
> Encountered the symbol ""


Я так понял что ругается вовсе не на кавычки, а на какие-то другие символы. Я так понимаю что line 1, column 8: -  это то что идет после declare, так как в declare 7 символов,  т.е. это  или пробел или перевод строки и возврат каретки или вообще черт знает что там (приду на работу и сразу же гляну)


 
Desdechado ©   (2006-02-24 10:56) [6]

> to_date("$dpb","dd.mm.yyyy");
что ты пытаешься тут сделать? $dpb - это PHP-шная переменная, что ли? Но оракл о твоем PHP Понятия не имеет, так что передавай нормально. А оракл ожидает там увидеть строку, которая удовлетворяет формату, заданному во втором параметре функции.


 
McSimm ©   (2006-02-24 11:15) [7]


> Desdechado ©   (24.02.06 10:56) [6]

эта переменная распарсится при присваивании

$fn = "...."$dpb"...."; присвоит строку со значением $dbp


 
Desdechado ©   (2006-02-24 11:25) [8]

> переменная распарсится при присваивании
если б она была в кавычках
или я чего-то не понимаю?


 
McSimm ©   (2006-02-24 11:33) [9]


> $fn = "...."$dpb"....";

все что внутри двойных кавычек проходит специальный лексический анализ.
В данном случае, если в $dbp к примеру имеет значение 12345, то переменная $fn примет значение ...."12345"....


 
SergP.   (2006-02-24 11:40) [10]


> Desdechado ©   (24.02.06 10:56) [6]
> > to_date("$dpb","dd.mm.yyyy");
> что ты пытаешься тут сделать? $dpb - это PHP-шная переменная,
>  что ли? Но оракл о твоем PHP Понятия не имеет, так что
> передавай нормально. А оракл ожидает там увидеть строку,
>  которая удовлетворяет формату, заданному во втором параметре
> функции.


$dpb - это переменная в которой находится дата в требуемом формате...

С этим все нормально... Я просматривал значение переменной $fn - там все ОК...

Но только что попробовал вместо

$fn="declare
  p1 date := to_date("$dpb","dd.mm.yyyy");
  p2 date := to_date("$dpe","dd.mm.yyyy");
  p5 date := to_date("$dmb","dd.mm.yyyy");
  p6 date := to_date("$dme","dd.mm.yyyy");
  p7 number := 1;
...


сделать


$fn="declare p1 date := to_date("$dpb","dd.mm.yyyy"); "
   ."p2 date := to_date("$dpe","dd.mm.yyyy"); "
   ."p5 date := to_date("$dmb","dd.mm.yyyy"); "
   ."p6 date := to_date("$dme","dd.mm.yyyy"); "
   ."p7 number := 1; "
   ."p9 number := 300; "
   ."p10 number := 1; "
   ."p11 number := 1; "
...


Т.е. избавился от переводов строки и возвратов каретки..
Теперь все заработало...

Но есть еще вопросик:

Данный блок может выполняться очень долго (в зависимости от от исходных данных)... Например даже до 1 часа..
Как можно сделать отображение хода выполнения блока...
В блоке в цикл можно вставить вывод определенных данных. Но как сделать чтобы это отображалось в браузере... Допустим при каждой итерации чтобы у меня на страничке добавлялась строчка в которой было отображено то что на данный момент выполнено?


 
McSimm ©   (2006-02-24 11:44) [11]

print "";//вывод строки
flush();


 
McSimm ©   (2006-02-24 12:07) [12]

еще надо проверить настройку
var_dump(ini_get("output_buffering"));

если отлична от нуля, то либо изменить в 0 в php.ini либо в .htaccess написать
php_flag output_buffering off


 
SergP.   (2006-02-24 12:37) [13]


> McSimm ©   (24.02.06 11:44) [11]
> print "";//вывод строки
> flush();


У меня должен выполняться PL/SQL блок, а вывод нужно сделать в самом блоке, но как передавать данные в PHP из блока в процессе его выполнения?

Есть конечно вариант такой: переделать блок, чтобы цикл выполнялся не в блоке а в PHP. Но интересует можно ли все-таки сделать вышеупомянутій вариант?


 
McSimm ©   (2006-02-24 13:17) [14]

Т.к. блок выполняется в рамках вызова одной функции
OCI_execute($stmt);
и никаких callback механизмов я в документации поверхностным взглядом не увидел. Если их нет, то сделать так невозможно.


 
SergP.   (2006-02-24 13:46) [15]


> McSimm ©   (24.02.06 13:17) [14]
> Т.к. блок выполняется в рамках вызова одной функции
> OCI_execute($stmt);
> и никаких callback механизмов я в документации поверхностным
> взглядом не увидел. Если их нет, то сделать так невозможно.
>


 
SergP.   (2006-02-24 13:48) [16]

предыдущее сообщение случайно запостилось...


> McSimm ©   (24.02.06 13:17) [14]
> Т.к. блок выполняется в рамках вызова одной функции
> OCI_execute($stmt);


Да.. Пока именно так...


> и никаких callback механизмов я в документации поверхностным
> взглядом не увидел. Если их нет, то сделать так невозможно.
>


Значит как я понял, лучше перенести цикл в ПХП?

Или может у кого еще какие мысли есть?


 
McSimm ©   (2006-02-24 14:06) [17]

смотря что считать "лучше".
если вывод в браузер действительно очень нужен - то конечно, цикл надо в PHP переносить.
но если это значительно увеличитвремя работы, то может и не стоит :)

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


 
by ©   (2006-02-24 15:15) [18]

SergP.   (24.02.06 13:48) [16]
Значит как я понял, лучше перенести цикл в ПХП?

Или может у кого еще какие мысли есть?

Оставить все в блоке как есть, добавить
dbms_application_info.set_module("php", "some log process");
  for abc in
  (                                
      select distinct c.ModDate, c.PerType, f.CharCode
      from card c,".""FORM""." f, ( select distinct CharCode From FormRow ) fr
      where c.".""FORM""." = f.code
        and f.CharCode = fr.CharCode
        and c.PerDate between p1 and p2
        and c.ModDate between p5 and p6
  ) loop
   i := i+1;
   dbms_application_info.set_client_info("rec number "||i);

А потом в паралельном процессе читать данные из предстваления V$SESSION и отображать прогресс.
Но для этого нужно что бы у процесса который читает, были права на чтение из V$SESSION


 
SergP.   (2006-02-24 16:56) [19]


> McSimm ©   (24.02.06 11:44) [11]
> print "";//вывод строки
> flush();
> <Цитата>
>
>
> McSimm ©   (24.02.06 12:07) [12]
> еще надо проверить настройку
> var_dump(ini_get("output_buffering"));
>
> если отлична от нуля, то либо изменить в 0 в php.ini либо
> в .htaccess написать
> php_flag output_buffering off


Кстати нашел в инете на одном из форумов такое:
(ничего перенастраивать не требуется)

Цитирую как там написано было:

ob_flush();
flush();

Из области шаманства но работает...


попробовал - работает, хотя просто flush() ничего не давал (у меня в настройках стоит размер буфера 4096. Просто не хочется ничего менять...
Толькопочему автор писал что "Из области шаманства"? И как Вы относитесь к применению такой конструкции?


 
SergP.   (2006-02-24 17:15) [20]

> by ©   (24.02.06 15:15) [18]
> McSimm ©   (24.02.06 14:06) [17]

Я сделал уже цикл в ПХП... Значительно время работы это не увеличит, так как процедура выполняющаяся в цикле сама выполняется приблизительно от 0,5с до нескольких секунд. не думаю что то что я перенес основной цикл в ПХП заметно повлияет на время выполнения...

Но есть еще один вопросик. Думаю последний...

Допустим юзер запускает скрипт. Скрипт работает и процесс отображается в браузере... Но вдруг юзеру взбрело в голову закрыть браузер, а потом снова открыть. Нужно чтобы если скрипт запущеный ранее еще выполняется запретить юзеру запускать его снова. пусть ждет пока предыдущая копия закончит работу. Есть ли какие-нить методы позволяющие из ПХП определить работает ли в данный момент какой-нить ПХП-шный скрипт?
И еще: Как в открытом второй раз браузере показывать процесс выполнения запущеного ранее скрипта?


 
McSimm ©   (2006-02-24 17:30) [21]

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

Для определения работает ли другой процесс можно использовать семафоры. Можно просто создать какой-то tratata.lock file и на время работы делать на него flock() и использовать как признак. Когда скрипт доработает либо снять блокировку с файла, либо она снимется автоматически если процесс умрет аварийно.


 
SergP.   (2006-02-24 17:49) [22]


> McSimm ©   (24.02.06 17:30) [21]
> Придется использовать сессии чтобы пользователя зашедшего
> повторно можно было идентифицировать как того-же самого.
>


ИМХО пользователя идентифицировать не нужно... Дело в том, что если один пользователь запустил скрипт, то его не должен запускать не только тот же самій пользователь, а и все остальные...



Страницы: 1 вся ветка

Текущий архив: 2006.03.19;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.232 c
15-1140772595
evgenij_
2006-02-24 12:16
2006.03.19
Хелп для Делфи


2-1141648283
mrAndersen
2006-03-06 15:31
2006.03.19
Работа с текстом в файле.


5-1127369126
Vcoder
2005-09-22 10:05
2006.03.19
Динамический массив в методе компонента


15-1140533892
Fl@sh
2006-02-21 17:58
2006.03.19
Книга по FireBird 1.0.3 or 1.5..


1-1140081895
syte_ser78
2006-02-16 12:24
2006.03.19
переименовка группы Action в ActionManager