2017-02-25 2 views
1

PHP codeigniterでOracle 10g Express Editionを使用しています。PHPでストアドプロシージャを呼び出す際にエラーが発生しました。リテラルが書式文字列と一致しません

私はテーブルtbl_movieている: -

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時間近く立ち往生しています。

+0

先生、私は専門家ではないですが、単にPHPMyAdminの中のストアプロシージャを作成して、私はまた、あなたはあなたの区切り文字をチェックしてみてくださいすることができて、ストアドプロシージャでの正しい区切り記号を与えていないため動けなくなります。 @Saswat –

答えて

1

手順パラメータsdateなどは、DATEデータ型です。手続きの中で、TO_DATE(...., 'yyyy-mm-dd hh24:mi:ss')を適用します。

TO_DATEはない日付の日付に、日付に文字列を変換するために使用されます。 TO_DATEを日付に適用すると、Oracleは最初に日付を文字列に変換し、TO_DATEに渡すことができます。残念ながら、Oracleが暗黙の変換を行う場合、TO_DATEにある同じ形式モデルは使用されません。むしろ、プロシージャを呼び出すセッションのnls_date_formatを使用します。 TO_DATEのモデルと同じではありません。これはあなたが見たエラーの原因となります。

これを解決するには2通りの方法があります。 1つはTO_DATE(sdate, ...)を使用せず、INSERTステートメントではsdateを使用することです。 sdateと他のものは既に日付です(最初にプロシージャの日付として正しく渡された場合)。

2つ目は、引数が文字列として渡されることを意味する場合は、手続き宣言でDATEと宣言しないでください。それらを宣言するVARCHAR2。 (そして、それらの文字列が正しい形式で正確ある二重確認してください - 。あなたは、フロントエンドからそれを制御することができるはずです)

をあなたはDATE入力に印加TO_DATE(....)を見るたびに、のようなエラーを期待あなたが見た人。逆に、そのようなエラーが表示された場合は、TO_DATE(....)のような疑わしいコードが日付に適用されます。

:別の可能性もあります。実際にプロシージャに文字列を渡している場合、Oracleはそれらを日付に変換する必要があります(これらは宣言されているためです)。文字列が、プロシージャを呼び出すセッションのnls_date_formatの形式に正確にない場合、文字列から日付へのこの初期変換は失敗し、INSERTステートメントにも到達しません。

+0

もっとよく説明してくれてありがとうございます:) – Utsav

+0

@Utsav - 私の説明が完全ではないかもしれないことに気がつきました... OPも日付ではなく文字列を渡している可能性もあります。 Oracleは文字列をNLS_DATE_FORMATを使用して日付に変換しようとするため、文字列が正しい形式でないと失敗する可能性があるため、INSERT文にもヒットしません。 – mathguy

+0

内部的にどのように動作するのかわかりませんでした。 'nls_date_format'に関する情報をありがとう。 (+1)エラーの解決に戻ると、彼のコードが見れば、彼は本当に文字列を渡しているように見えます。したがって、入力パラメータのデータ型をstringに変更すると、問題は解決されます。私は似たような種類のソリューションの開発を覚えています。とにかく、彼がコメントするのを待つことができます。 – Utsav

1

入力パラメータのデータ型をdateからvarcharに変更します。現在のシナリオでは、基本的にはをdateデータ型に適用しています。 datevarcharに置き換えると、残りのロジックが機能するはずです。

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; 
/
関連する問題