Форум: "Прочее";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
Вниз
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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.02 c