@@ -513,11 +513,25 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
513513 for _ , column := range allColumns {
514514 if field := findFieldByDBName (schema , column ); field != nil {
515515 if isJSONField (field ) {
516- // JSON -> text bind
517- stmt .Vars = append (stmt .Vars , sql.Out {Dest : new (string )})
518- plsqlBuilder .WriteString (fmt .Sprintf (" IF l_affected_records.COUNT > %d THEN :%d := JSON_SERIALIZE(l_affected_records(%d)." , rowIdx , outParamIndex + 1 , rowIdx + 1 ))
519- writeQuotedIdentifier (& plsqlBuilder , column )
520- plsqlBuilder .WriteString (" RETURNING CLOB); END IF;\n " )
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+ }
521535 } else {
522536 stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
523537 plsqlBuilder .WriteString (fmt .Sprintf (" IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d)." , rowIdx , outParamIndex + 1 , rowIdx + 1 ))
@@ -631,12 +645,21 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
631645
632646 if field := findFieldByDBName (schema , column ); field != nil {
633647 if isJSONField (field ) {
634- // JSON -> text bind
635- stmt .Vars = append (stmt .Vars , sql.Out {Dest : new (string )})
636- plsqlBuilder .WriteString (fmt .Sprintf (
637- " IF l_inserted_records.COUNT > %d THEN :%d := JSON_SERIALIZE(l_inserted_records(%d).%s RETURNING CLOB); END IF;\n " ,
638- rowIdx , outParamIndex + 1 , rowIdx + 1 , quotedColumn ,
639- ))
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+ }
640663 } else {
641664 stmt .Vars = append (stmt .Vars , sql.Out {Dest : createTypedDestination (field )})
642665 plsqlBuilder .WriteString (fmt .Sprintf (
0 commit comments