Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用sqlplus的php system()命令会导致php挂起_Php_Oracle_Command Line Interface_Sqlplus - Fatal编程技术网

调用sqlplus的php system()命令会导致php挂起

调用sqlplus的php system()命令会导致php挂起,php,oracle,command-line-interface,sqlplus,Php,Oracle,Command Line Interface,Sqlplus,我有一个简单的php脚本,它调用sqlplus sqlldr文件并将数据转储到oracle中的表中。我已经把问题缩小到我认为是什么原因导致我的php脚本挂起。。。即: 当我从PHPCLI运行时,系统命令不会返回php,而是挂起在sqlplus land中。当从浏览器运行时,脚本将按预期执行,我将获得打印到浏览器的最终echo命令:我现在已完成运行 现在。。。问题是这会导致我的php程序挂起,我无法再回到php脚本。如何退出sqlplus CLI以返回正在运行的php脚本 SQLPLUS中典型的e

我有一个简单的php脚本,它调用sqlplus sqlldr文件并将数据转储到oracle中的表中。我已经把问题缩小到我认为是什么原因导致我的php脚本挂起。。。即: 当我从PHPCLI运行时,系统命令不会返回php,而是挂起在sqlplus land中。当从浏览器运行时,脚本将按预期执行,我将获得打印到浏览器的最终echo命令:我现在已完成运行

现在。。。问题是这会导致我的php程序挂起,我无法再回到php脚本。如何退出sqlplus CLI以返回正在运行的php脚本

SQLPLUS中典型的exit命令就是“exit”,正如您在上面看到的,我已经尝试过了。。。当手动运行时,会产生以下结果:

Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning and Oracle Label Security options
如何退出sqlplus并重新进入应该继续的脚本?非常感谢您的帮助

调用此sqlplus脚本并再次调用的实际方法—在从浏览器调用时工作得非常好,但在从CLI调用时,它在返回之前挂起在此方法中

private function loadTempData($object) {
$this->getLog()->appendLogFile('Constructed Control File: '.$object->getTempData()->getQaveLoadControl()->getFullPathFileName());
$this->getLog()->appendLogFile('Result saved in: '.$object->getTempData()->getExportFile()->getFullPathFileName());
    $object->getInsertCommandFile()->appendContent('$ sqlldr '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' control='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().' log='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().'.log');
$this->getLog()->appendLogFile('Loading data to Temp Table');
    $command = 'sqlplus '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' @'.$object->insertCommandFile->getFullPathFileName();
$this->getLog()->appendLogFile($command);
    system($command,$output);
// this line does not make it into the log...
    $this->getLog()->appendLogFile($output);
// this method does not return when run from CLI
    return true;
}

首先,您应该始终将动态输出转义到shell命令。其次,系统不会返回程序的输出,而是直接显示它。第二个参数由程序的返回值填充,成功执行时通常为0。要收集日志文件中使用的完整输出并获取返回值,请使用exec


最后,确保您在SQL文件中使用实际的exit语句指示程序退出

您需要使用可以非交互运行的程序。系统运行命令,系统退出;就我所知,sqlplus在非交互模式下运行没有问题。如果我不是从CLI运行php,即从命令行调用脚本,那么这个脚本工作得非常好。当我从浏览器调用时,sqlplus打开运行我的.ctl文件将数据加载到远程数据库表,然后继续通过php脚本记录输出等。。。问题似乎是,当我从命令行运行php脚本时,我得到了不同的行为。而且我没有看到它运行脚本或任何东西,只是启动了程序sqlplus用户名/password@tnsNameOfDatabase. 您缺少参数吗?为了清楚起见,我删除了它运行的脚本。我将用实际的代码片段更新它…我添加了调用系统命令的实际方法。。。这里有很多日志记录用于调试目的。所有构造的字符串都得到了正确的构造。转义字符也很合理——目前我正在硬编码凭证并登录。我很感激这一教训。但是,我尝试了exec、shell_exec和系统,所有这些都无法从CLI运行。我不熟悉您尝试运行的程序;你试过在SQL脚本中放一个实际的出口吗?找到了这个--它很有效。因此,是的,将exit命令添加到shell脚本中就是回答这个问题的方法——感谢第二组代码!
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning and Oracle Label Security options
private function loadTempData($object) {
$this->getLog()->appendLogFile('Constructed Control File: '.$object->getTempData()->getQaveLoadControl()->getFullPathFileName());
$this->getLog()->appendLogFile('Result saved in: '.$object->getTempData()->getExportFile()->getFullPathFileName());
    $object->getInsertCommandFile()->appendContent('$ sqlldr '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' control='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().' log='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().'.log');
$this->getLog()->appendLogFile('Loading data to Temp Table');
    $command = 'sqlplus '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' @'.$object->insertCommandFile->getFullPathFileName();
$this->getLog()->appendLogFile($command);
    system($command,$output);
// this line does not make it into the log...
    $this->getLog()->appendLogFile($output);
// this method does not return when run from CLI
    return true;
}
<?php
$credentials = escapeshellarg("username/password@tnsNameOfDatabase");
$scriptfile = escapeshellarg("@/my/sqlldr/file");
exec("sqlplus $credentials $scriptfile", $output, $return);
// $output contains every line of output from the program, as an array
// $return contains the numeric exit code from the program
echo 'I am done running now';