@@ -226,7 +226,7 @@ final class OracleStatementImpl implements Statement {
226226 */
227227 @ Override
228228 public Statement bind (int index , Object value ) {
229- requireNonNull (value , "value must not be null" );
229+ requireNonNull (value , "value is null" );
230230 requireValidIndex (index );
231231 bindValues [index ] = convertToJdbcBindValue (value );
232232 return this ;
@@ -249,11 +249,13 @@ public Statement bind(int index, Object value) {
249249 * syntax.
250250 * </p><p>
251251 * If the specified {@code identifier} matches more than one parameter name,
252- * this method binds the {@code value} to the first matching parameter that
253- * appears when the SQL command is read from left to right. (Note: It is
254- * not recommended to use duplicate parameter names. Use
255- * {@link #bind(int, Object)} to set a value for a duplicate parameter name
256- * at a given index).
252+ * then this method binds the {@code value} to all parameters having a
253+ * matching name. For instance, when {@code 9} is bound to the parameter
254+ * named "x", the following SQL would return all names having a birthday on
255+ * the 9th day of the 9th month:
256+ * <pre>
257+ * SELECT name FROM birthday WHERE month=:x AND day=:x
258+ * </pre>
257259 * </p>
258260 * @throws IllegalArgumentException {@inheritDoc}
259261 * @throws IllegalArgumentException If the {@code identifier} does match a
@@ -264,9 +266,9 @@ public Statement bind(int index, Object value) {
264266 */
265267 @ Override
266268 public Statement bind (String identifier , Object value ) {
267- requireNonNull (identifier , "identifier must not be null" );
268- requireNonNull (value , "value must not be null" );
269- bindValues [ indexOfIdentifier (identifier )] = convertToJdbcBindValue ( value );
269+ requireNonNull (identifier , "identifier is null" );
270+ requireNonNull (value , "value is null" );
271+ bindNamedParameter (identifier , value );
270272 return this ;
271273 }
272274
@@ -281,7 +283,7 @@ public Statement bind(String identifier, Object value) {
281283 */
282284 @ Override
283285 public Statement bindNull (int index , Class <?> type ) {
284- requireNonNull (type , "class type must not be null" );
286+ requireNonNull (type , "type is null" );
285287 requireValidIndex (index );
286288 bindValues [index ] = null ;
287289 return this ;
@@ -310,16 +312,26 @@ public Statement bindNull(int index, Class<?> type) {
310312 * duplicate parameter names. Use {@link #bindNull(int, Class)} to set the
311313 * SQL {@code NULL} value for a duplicate parameter name at a given index).
312314 * </p>
315+ * </p><p>
316+ * If the specified {@code identifier} matches more than one parameter name,
317+ * then this method binds the SQL {@code NULL} value to all parameters
318+ * having a matching name. For instance, when {@code NULL} is bound to the
319+ * parameter named "x", the following SQL would create a birthday with
320+ * {@code NULL} values for month and day:
321+ * <pre>
322+ * INSERT INTO birthday (name, month, day) VALUES ('Plato', :x, :x)
323+ * </pre>
324+ * </p>
313325 * @throws IllegalArgumentException {@inheritDoc}
314326 * @throws IllegalArgumentException If the {@code identifier} does match a
315327 * case sensitive parameter name that appears in this {@code Statement's}
316328 * SQL command.
317329 */
318330 @ Override
319331 public Statement bindNull (String identifier , Class <?> type ) {
320- requireNonNull (identifier , "identifier must not be null" );
321- requireNonNull (type , "class type must not be null" );
322- bindValues [ indexOfIdentifier (identifier )] = null ;
332+ requireNonNull (identifier , "identifier is null" );
333+ requireNonNull (type , "type is null" );
334+ bindNamedParameter (identifier , null ) ;
323335 return this ;
324336 }
325337
@@ -694,21 +706,26 @@ else if (index >= parameterNames.size()) {
694706 }
695707
696708 /**
697- * Returns the 0-based index of a named parameter matching the specified
698- * {@code identifier }. The match is case-sensitive.
699- * @param identifier A parameter identifier
700- * @return The 0-based parameter index of the {@code identifier}
709+ * Binds a {@code value} to all named parameters matching the specified
710+ * {@code name }. The match is case-sensitive.
711+ * @param name A parameter name. Not null.
712+ * @param value A value to bind. May be null.
701713 * @throws IllegalArgumentException if no named parameter matches the
702714 * {@code identifier}
703715 */
704- private int indexOfIdentifier (String identifier ) {
705- int index = parameterNames .indexOf (identifier );
706- if (index == -1 ) {
707- throw new IllegalArgumentException (
708- "Unrecognized parameter identifier: " + identifier );
716+ private void bindNamedParameter (String name , Object value ) {
717+ boolean isMatched = false ;
718+
719+ for (int i = 0 ; i < parameterNames .size (); i ++) {
720+ if (name .equals (parameterNames .get (i ))) {
721+ isMatched = true ;
722+ bindValues [i ] = convertToJdbcBindValue (value );
723+ }
709724 }
710- else {
711- return index ;
725+
726+ if (! isMatched ) {
727+ throw new IllegalArgumentException (
728+ "Unrecognized parameter identifier: " + name );
712729 }
713730 }
714731
@@ -730,7 +747,7 @@ private int indexOfIdentifier(String identifier) {
730747 */
731748 private Object convertToJdbcBindValue (Object bindValue ) {
732749 if (bindValue == null ) {
733- return bindValue ;
750+ return null ;
734751 }
735752 else if (bindValue instanceof io .r2dbc .spi .Blob ) {
736753 return convertBlobBind ((io .r2dbc .spi .Blob ) bindValue );
0 commit comments