通过php调用存储过程时出错。文本与格式字符串不匹配

通过php调用存储过程时出错。文本与格式字符串不匹配,php,oracle,codeigniter,stored-procedures,Php,Oracle,Codeigniter,Stored Procedures,我正在使用Oracle 10g Express Edition和PHP codeigniter 我有一部电影:- CREATE TABLE tbl_movie (movie_id NUMBER(11) PRIMARY KEY, movie_title VARCHAR2(255) NOT NULL, movie_image VARCHAR2(255) NOT NULL, language_id NUMBER(11) NOT NULL REFERENCES tbl_language(la

我正在使用Oracle 10g Express Edition和PHP codeigniter

我有一部电影:-

CREATE TABLE tbl_movie (movie_id NUMBER(11) PRIMARY KEY,
  movie_title VARCHAR2(255) NOT NULL,
  movie_image VARCHAR2(255) NOT NULL,
  language_id NUMBER(11) NOT NULL REFERENCES tbl_language(language_id) ON DELETE CASCADE,
  showtime_id NUMBER(11) NOT NULL REFERENCES tbl_showtime(showtime_id) ON DELETE CASCADE,
  movie_sdate DATE NOT NULL,
  movie_edate DATE NOT NULL,
  movie_add_date DATE NOT NULL
);
现在,我通过Oracle命令行创建了一个过程:-

CREATE OR REPLACE PROCEDURE 
        insertMovie (id IN NUMBER, title IN VARCHAR2, image IN VARCHAR2, language IN NUMBER, showtime IN NUMBER, sdate IN DATE, edate IN DATE, adate IN DATE, message OUT NUMBER) 
    IS
        BEGIN
            INSERT INTO tbl_movie (movie_id, movie_title, movie_image, language_id, showtime_id, movie_sdate, movie_edate, movie_add_date) 
            VALUES ( id, title, image, language, showtime, TO_DATE(sdate, 'YYYY-MM-DD hh24:mi:ss'), TO_DATE(edate, 'YYYY-MM-DD hh24:mi:ss'), TO_DATE(adate, 'YYYY-MM-DD hh24:mi:ss'));
            message := 1;
        EXCEPTION
          WHEN OTHERS THEN
            message := 0;
        END;
/
这是来自我的codeigniter控制器的代码:-

public function testMovie()
{
    $insertData['movie_id'] = 1;
    $insertData['movie_title']= 'test';
    $insertData['movie_image']= 'rfgt';
    $insertData['language_id']= 1;
    $insertData['showtime_id']= 1;
    $insertData['movie_sdate']= '2017-02-24 00:00:00';
    $insertData['movie_edate']= '2017-02-27 00:00:00';
    $insertData['movie_add_date']= '2017-02-20 00:00:00';
    $this->load->model('oracle_model');
    $return = $this->oracle_model->add_movie('movie',$insertData,'');   
}
这是用于调用过程的模型函数:-

function add_movie($entity,$insertData,$time)
{
    print_r($insertData);
    $conn   = oci_connect("xxxxxx", "xxxxxx","xxxxxxxxx");
    if(!$conn)
    {
        echo "connect failed".oci_error();
    }   
    else
    {   
        echo "connect done at".date('d-m-y');

        // calling stored procedure insertMovie
        $insertMovieProcedureSQL = "BEGIN insertMovie(:id, :title, :image, :language, :showtime, :sdate, :edate, :adate, :message); END;";
        $stmt = oci_parse($conn, $insertMovieProcedureSQL);

        //  Bind the input parameter
        oci_bind_by_name($stmt,':id',$insertData['movie_id']);
        oci_bind_by_name($stmt,':title',$insertData['movie_title']);
        oci_bind_by_name($stmt,':image',$insertData['movie_image']);
        oci_bind_by_name($stmt,':language',$insertData['language_id']);
        oci_bind_by_name($stmt,':showtime',$insertData['showtime_id']);
        oci_bind_by_name($stmt,':sdate',$insertData['movie_sdate']);
        oci_bind_by_name($stmt,':edate',$insertData['movie_edate']);
        oci_bind_by_name($stmt,':adate',$insertData['movie_add_date']);

        // Bind the output parameter
        oci_bind_by_name($stmt,':message',$message);

        oci_execute($stmt);
        // $message is now populated with the output value
        echo "$message\n";
    }   
}
运行该函数时,出现以下错误:-

oci_execute(): ORA-01861: literal does not match format string ORA-06512: at line 1
当我试图通过删除所有日期数据类型列来运行该过程时,代码运行良好。我认为主要问题在于日期列

但当我从命令行运行此查询时,数据被成功插入:-

INSERT INTO tbl_movie (movie_id, movie_title, movie_image, language_id, showtime_id, movie_sdate, movie_edate, movie_add_date) 
            VALUES ( 2, 'title', 'image', 2, 3, TO_DATE('2017-02-24 00:00:00', 'YYYY-MM-DD hh24:mi:ss'), TO_DATE('2017-02-27 00:00:00', 'YYYY-MM-DD hh24:mi:ss'), TO_DATE('2017-02-20 00:00:00', 'YYYY-MM-DD hh24:mi:ss'));

我做错了什么?我被困了将近4个小时。

程序参数
sdate
等属于
DATE
数据类型。在您的过程中,您将
应用于_DATE(..,'yyyy-mm-dd hh24:mi:ss')
应用于它们

TO_DATE
用于将字符串转换为日期,而不是日期转换为日期。如果将
TO_DATE
应用于日期,Oracle会首先将日期转换为字符串,以便将其传递给
TO_DATE
。不幸的是,当Oracle进行这种隐式转换时,它并没有使用与您在
TO_DATE
中使用的格式模型相同的格式模型;相反,它使用调用该过程的会话的
nls\u date\u格式。这与迄今为止的
中的模型不同-这会导致您看到的错误

有两种方法可以解决这个问题。一种是不要使用
to_DATE(sdate,…)
,而只在
INSERT
语句中使用
sdate
sdate
和其他日期已经是日期(如果它们首先作为日期正确地传递给过程)

第二个是,如果实际上您的意思是参数作为字符串传递,那么不要在过程声明中将它们声明为
DATE
;声明它们
VARCHAR2
。(并确保这些字符串的格式正确,您应该能够从前端控制它。)

每当您看到应用于
日期
输入的
TO_DATE(..)
时,都会出现类似您所看到的错误。相反,每当您看到这样的错误时,都会将类似于
TO_DATE(..)
的可疑代码应用于某个日期


添加了:还有另一种可能性。如果您实际上是在向过程传递字符串,Oracle必须将其转换为日期(因为它们被声明为日期)。如果字符串的格式与调用过程的会话的
nls\u date\u格式不完全相同,则参数从字符串到日期的初始转换将失败,甚至无法到达
INSERT
语句。

将输入参数的数据类型从
date
更改为
varchar
。在当前场景中,您基本上是将
应用于
日期
数据类型上的\u date
。用
varchar
替换
date
后,剩下的逻辑就可以工作了

CREATE OR REPLACE PROCEDURE 
        insertMovie (id IN NUMBER, title IN VARCHAR2, image IN VARCHAR2, language IN NUMBER, showtime IN NUMBER, sdate IN VARCHAR2, edate IN VARCHAR2, adate IN VARCHAR2, message OUT NUMBER) 
    IS
        BEGIN
            INSERT INTO tbl_movie (movie_id, movie_title, movie_image, language_id, showtime_id, movie_sdate, movie_edate, movie_add_date) 
            VALUES ( id, title, image, language, showtime, TO_DATE(sdate, 'YYYY-MM-DD hh24:mi:ss'), TO_DATE(edate, 'YYYY-MM-DD hh24:mi:ss'), TO_DATE(adate, 'YYYY-MM-DD hh24:mi:ss'));
            message := 1;
        EXCEPTION
          WHEN OTHERS THEN
            message := 0;
        END;
/

先生,我不是专家,但我只是在PHPMyAdmin中创建了一个存储过程,我还因为在存储过程中没有给出正确的分隔符而陷入困境,所以请您尝试检查您的分隔符@萨斯瓦特比我的解释更好:)@Utsav-我刚刚意识到我的解释可能不完整。。。OP也可能传递的是字符串,而不是日期——整个过程在一开始就失败了,它甚至从来没有碰到INSERT语句,因为Oracle将尝试使用NLS_DATE_格式将字符串转换为日期,如果字符串格式不完全正确,则可能会失败。不知道它在内部是如何工作的。感谢您提供有关nls\u日期\u格式的信息。(+1)回到错误的解决方案,如果您看到他的代码,那么看起来他确实在传递字符串。因此,如果我们将输入参数的数据类型更改为字符串,则问题将得到解决。我记得我曾研究过类似的解决方案。无论如何,让我们等待他发表评论。@Utsav-我只看到“当我运行函数时,我得到以下错误:”-我不知道他如何调用函数(特别是,我不知道他是如何传递参数的;函数是用来从前端应用程序传递参数的,否则就不需要函数了)。无论如何,我也提供了这个解决方案——你可以在我的答案中看到。@mathguy,实际上我使用的是php date()函数,它以字符串形式提供日期。mysql datetime接受date()函数返回的值。但与oracle不同。这就是我遇到问题的原因。Amyways,您解决了我的问题。:)