@@ -507,15 +507,37 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
507507 }
508508 plsqlBuilder .WriteString ("\n BULK COLLECT INTO l_affected_records;\n " )
509509
510- // Add OUT parameter population
510+ // Add OUT parameter population (JSON serialized to CLOB)
511511 outParamIndex := len (stmt .Vars )
512512 for rowIdx := 0 ; rowIdx < len (createValues .Values ); rowIdx ++ {
513513 for _ , column := range allColumns {
514514 if field := findFieldByDBName (schema , column ); field != nil {
515- stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
516- plsqlBuilder .WriteString (fmt .Sprintf (" IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d)." , rowIdx , outParamIndex + 1 , rowIdx + 1 ))
517- db .QuoteTo (& plsqlBuilder , column )
518- plsqlBuilder .WriteString ("; END IF;\n " )
515+ if isJSONField (field ) {
516+ if isRawMessageField (field ) {
517+ // Column is a BLOB, return raw bytes; no JSON_SERIALIZE
518+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : new ([]byte )})
519+ plsqlBuilder .WriteString (fmt .Sprintf (
520+ " IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d)." ,
521+ rowIdx , outParamIndex + 1 , rowIdx + 1 ,
522+ ))
523+ writeQuotedIdentifier (& plsqlBuilder , column )
524+ plsqlBuilder .WriteString ("; END IF;\n " )
525+ } else {
526+ // datatypes.JSON (text-based) -> serialize to CLOB
527+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : new (string )})
528+ plsqlBuilder .WriteString (fmt .Sprintf (
529+ " IF l_affected_records.COUNT > %d THEN :%d := JSON_SERIALIZE(l_affected_records(%d)." ,
530+ rowIdx , outParamIndex + 1 , rowIdx + 1 ,
531+ ))
532+ writeQuotedIdentifier (& plsqlBuilder , column )
533+ plsqlBuilder .WriteString (" RETURNING CLOB); END IF;\n " )
534+ }
535+ } else {
536+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
537+ plsqlBuilder .WriteString (fmt .Sprintf (" IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d)." , rowIdx , outParamIndex + 1 , rowIdx + 1 ))
538+ writeQuotedIdentifier (& plsqlBuilder , column )
539+ plsqlBuilder .WriteString ("; END IF;\n " )
540+ }
519541 outParamIndex ++
520542 }
521543 }
@@ -613,7 +635,7 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
613635 }
614636 plsqlBuilder .WriteString ("\n BULK COLLECT INTO l_inserted_records;\n " )
615637
616- // Add OUT parameter population
638+ // Add OUT parameter population (JSON serialized to CLOB)
617639 outParamIndex := len (stmt .Vars )
618640 for rowIdx := 0 ; rowIdx < len (createValues .Values ); rowIdx ++ {
619641 for _ , column := range allColumns {
@@ -622,9 +644,29 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
622644 quotedColumn := columnBuilder .String ()
623645
624646 if field := findFieldByDBName (schema , column ); field != nil {
625- stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
626- plsqlBuilder .WriteString (fmt .Sprintf (" IF l_inserted_records.COUNT > %d THEN :%d := l_inserted_records(%d).%s; END IF;\n " ,
627- rowIdx , outParamIndex + 1 , rowIdx + 1 , quotedColumn ))
647+ if isJSONField (field ) {
648+ if isRawMessageField (field ) {
649+ // Column is a BLOB, return raw bytes; no JSON_SERIALIZE
650+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : new ([]byte )})
651+ plsqlBuilder .WriteString (fmt .Sprintf (
652+ " IF l_inserted_records.COUNT > %d THEN :%d := l_inserted_records(%d).%s; END IF;\n " ,
653+ rowIdx , outParamIndex + 1 , rowIdx + 1 , quotedColumn ,
654+ ))
655+ } else {
656+ // datatypes.JSON (text-based) -> serialize to CLOB
657+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : new (string )})
658+ plsqlBuilder .WriteString (fmt .Sprintf (
659+ " IF l_inserted_records.COUNT > %d THEN :%d := JSON_SERIALIZE(l_inserted_records(%d).%s RETURNING CLOB); END IF;\n " ,
660+ rowIdx , outParamIndex + 1 , rowIdx + 1 , quotedColumn ,
661+ ))
662+ }
663+ } else {
664+ stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
665+ plsqlBuilder .WriteString (fmt .Sprintf (
666+ " IF l_inserted_records.COUNT > %d THEN :%d := l_inserted_records(%d).%s; END IF;\n " ,
667+ rowIdx , outParamIndex + 1 , rowIdx + 1 , quotedColumn ,
668+ ))
669+ }
628670 outParamIndex ++
629671 }
630672 }
0 commit comments