Data Backfill
RETURNING ... INTO returns field values as part of a write, without an additional SELECT. INSERT returns inserted values, UPDATE returns updated values, and DELETE returns values from the deleted row.
In dbVisitor, use JdbcTemplate.call to execute a BEGIN ... END; anonymous block and read OUT parameters. Do not treat it as a SELECT. No stored procedure needs to be created beforehand.
Return Inserted Fields
The examples below use the same table in sequence:
CREATE TABLE user_info (
id NUMBER(10) PRIMARY KEY,
name VARCHAR2(100),
age NUMBER(3)
);
The database converts the name to uppercase during insertion and returns the stored name and age:
import java.util.Map;
import net.hasor.dbvisitor.jdbc.core.JdbcTemplate;
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
Map<String, Object> result = jdbc.call("""
BEGIN
INSERT INTO user_info (id, name, age)
VALUES (#{id}, UPPER(#{name}), #{age})
RETURNING name, age INTO #{savedName,mode=out,jdbcType=varchar},
#{savedAge,mode=out,jdbcType=integer};
END;
""", Map.of("id", 918101, "name", "alice", "age", 20));
String name = (String) result.get("savedName"); // ALICE
Integer age = (Integer) result.get("savedAge"); // 20
mode=out declares an output parameter; jdbcType specifies its receiving type. The returned Map uses output parameter names as keys. To update an entity, assign these values to its properties.
Return Updated Fields
Increment the age and return its new value. SQL%ROWCOUNT also supplies the number of updated rows:
Map<String, Object> result = jdbc.call("""
BEGIN
UPDATE user_info SET age = age + 1 WHERE id = #{id}
RETURNING age INTO #{savedAge,mode=out,jdbcType=integer};
#{rows,mode=out,jdbcType=integer} := SQL%ROWCOUNT;
END;
""", Map.of("id", 918101));
if ((Integer) result.get("rows") == 1) {
Integer age = (Integer) result.get("savedAge"); // 21
}
Return Deleted Fields
Delete the row and retrieve its name:
Map<String, Object> result = jdbc.call("""
BEGIN
DELETE FROM user_info WHERE id = #{id}
RETURNING name INTO #{deletedName,mode=out,jdbcType=varchar};
#{rows,mode=out,jdbcType=integer} := SQL%ROWCOUNT;
END;
""", Map.of("id", 918101));
if ((Integer) result.get("rows") == 1) {
String name = (String) result.get("deletedName"); // ALICE
}
- These examples use scalar output parameters. Updates and deletes target a single primary key; this pattern is not for returning multiple rows.
- If no row matches, do not read the returned fields. Check that
rowsis1first.
See Stored Procedure Calls for output parameters and Key Generation for automatic identity-key backfill. For syntax, see Oracle RETURNING INTO.