1515
1616use CodeIgniter \Database \BaseConnection ;
1717use CodeIgniter \Database \Exceptions \DatabaseException ;
18+ use CodeIgniter \Database \Exceptions \UniqueConstraintViolationException ;
1819use CodeIgniter \Database \Query ;
1920use CodeIgniter \Database \TableName ;
2021use ErrorException ;
@@ -236,10 +237,27 @@ protected function execute(string $sql)
236237
237238 oci_set_prefetch ($ this ->stmtId , 1000 );
238239
239- $ result = oci_execute ($ this ->stmtId , $ this ->commitMode ) ? $ this ->stmtId : false ;
240+ $ result = oci_execute ($ this ->stmtId , $ this ->commitMode ) ? $ this ->stmtId : false ;
241+
242+ if ($ result === false ) {
243+ // ORA-00001: unique constraint violated
244+ $ error = $ this ->error ();
245+ $ exception = $ error ['code ' ] === 1
246+ ? new UniqueConstraintViolationException ((string ) $ error ['message ' ], $ error ['code ' ])
247+ : new DatabaseException ((string ) $ error ['message ' ], $ error ['code ' ]);
248+
249+ if ($ this ->DBDebug ) {
250+ throw $ exception ;
251+ }
252+
253+ $ this ->lastException = $ exception ;
254+
255+ return false ;
256+ }
257+
240258 $ insertTableName = $ this ->parseInsertTableName ($ sql );
241259
242- if ($ result && $ insertTableName !== '' ) {
260+ if ($ insertTableName !== '' ) {
243261 $ this ->lastInsertedTableName = $ insertTableName ;
244262 }
245263
@@ -254,9 +272,17 @@ protected function execute(string $sql)
254272 'trace ' => render_backtrace ($ trace ),
255273 ]);
256274
275+ // ORA-00001: unique constraint violated
276+ $ error = $ this ->error ();
277+ $ exception = $ error ['code ' ] === 1
278+ ? new UniqueConstraintViolationException ((string ) $ error ['message ' ], $ error ['code ' ], $ e )
279+ : new DatabaseException ((string ) $ error ['message ' ], $ error ['code ' ], $ e );
280+
257281 if ($ this ->DBDebug ) {
258- throw new DatabaseException ( $ e -> getMessage (), $ e -> getCode (), $ e ) ;
282+ throw $ exception ;
259283 }
284+
285+ $ this ->lastException = $ exception ;
260286 }
261287
262288 return false ;
@@ -615,25 +641,25 @@ protected function bindParams($params)
615641 */
616642 public function error (): array
617643 {
618- // oci_error() returns an array that already contains
619- // 'code' and 'message' keys, but it can return false
620- // if there was no error ....
621- $ error = oci_error ();
644+ // oci_error() is resource-specific: check each resource in priority order
645+ // and return the first one that actually has an error. This ensures that
646+ // e.g. oci_parse() failures ( error on connID) are found even when stmtId
647+ // holds a stale valid resource from the previous successful query.
622648 $ resources = [$ this ->cursorId , $ this ->stmtId , $ this ->connID ];
623649
624650 foreach ($ resources as $ resource ) {
625651 if (is_resource ($ resource )) {
626652 $ error = oci_error ($ resource );
627- break ;
653+
654+ if (is_array ($ error )) {
655+ return $ error ;
656+ }
628657 }
629658 }
630659
631- return is_array ($ error )
632- ? $ error
633- : [
634- 'code ' => '' ,
635- 'message ' => '' ,
636- ];
660+ $ error = oci_error ();
661+
662+ return is_array ($ error ) ? $ error : ['code ' => '' , 'message ' => '' ];
637663 }
638664
639665 public function insertID (): int
0 commit comments