下面列出了java.sql.Statement#EXECUTE_FAILED 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public ResultSet getBatchGeneratedKeys(Protocol protocol) {
long[] ret = new long[insertIdNumber];
int position = 0;
long insertId;
Iterator<Long> idIterator = insertIds.iterator();
for (Long updateCount : updateCounts) {
if (updateCount != Statement.EXECUTE_FAILED
&& updateCount != RESULT_SET_VALUE
&& (insertId = idIterator.next()) > 0) {
for (int i = 0; i < updateCount; i++) {
ret[position++] = insertId + i * autoIncrement;
}
}
}
return SelectResultSet.createGeneratedData(ret, protocol, true);
}
/**
* Return GeneratedKeys containing insert ids. Insert ids are calculated using autoincrement
* value.
*
* @param protocol current protocol
* @param sql SQL command
* @return a resultSet with insert ids.
*/
public ResultSet getGeneratedKeys(Protocol protocol, String sql) {
long[] ret = new long[insertIdNumber];
int position = 0;
long insertId;
Iterator<Long> idIterator = insertIds.iterator();
Iterator<Long> updateIterator = updateCounts.iterator();
for (int element = 0; element <= moreResults; element++) {
long updateCount = updateIterator.next();
if (updateCount != Statement.EXECUTE_FAILED
&& updateCount != RESULT_SET_VALUE
&& (insertId = idIterator.next()) > 0
&& element == moreResults) {
for (int i = 0; i < updateCount; i++) {
ret[position++] = insertId + i * autoIncrement;
}
}
}
return SelectResultSet.createGeneratedData(ret, protocol, true);
}
@Override
public ResultSet getBatchGeneratedKeys(Protocol protocol) {
long[] ret = new long[insertIdNumber];
int position = 0;
long insertId;
Iterator<Long> idIterator = insertIds.iterator();
for (Long updateCountLong : updateCounts) {
int updateCount = updateCountLong.intValue();
if (updateCount != Statement.EXECUTE_FAILED
&& updateCount != RESULT_SET_VALUE
&& (insertId = idIterator.next()) > 0) {
for (int i = 0; i < updateCount; i++) {
ret[position++] = insertId + i * autoIncrement;
}
}
}
return SelectResultSet.createGeneratedData(ret, protocol, true);
}
/**
* Return GeneratedKeys containing insert ids. Insert ids are calculated using autoincrement
* value.
*
* @param protocol current protocol
* @param sql SQL command
* @return a resultSet with insert ids.
*/
public ResultSet getGeneratedKeys(Protocol protocol, String sql) {
long[] ret = new long[insertIdNumber];
int position = 0;
long insertId;
Iterator<Long> idIterator = insertIds.iterator();
for (Long updateCountLong : updateCounts) {
int updateCount = updateCountLong.intValue();
if (updateCount != Statement.EXECUTE_FAILED
&& updateCount != RESULT_SET_VALUE
&& (insertId = idIterator.next()) > 0) {
for (int i = 0; i < updateCount; i++) {
ret[position++] = insertId + i * autoIncrement;
}
}
}
return SelectResultSet.createGeneratedData(ret, protocol, true);
}
public static void printResults(String query, int[] counts, HttpServletResponse response) throws IOException{
PrintWriter out = response.getWriter();
out.write("<!DOCTYPE html>\n<html>\n<body>\n<p>");
out.write("For query: " + ESAPI.encoder().encodeForHTML(query) + "<br>");
try {
if(counts.length > 0){
if(counts[0] == Statement.SUCCESS_NO_INFO){
out.write("The SQL query was processed successfully but the number of rows affected is unknown.");
System.out.println("The SQL query was processed successfully but the number of rows affected is unknown.");
}else if(counts[0] == Statement.EXECUTE_FAILED){
out.write("The SQL query failed to execute successfully and occurs only if a driver continues to process commands after a command fails");
System.out.println("The SQL query failed to execute successfully and occurs only if a driver continues to process commands after a command fails");
}else{
out.write("The number of affected rows are: " + counts[0]);
System.out.println("The number of affected rows are: " + counts[0]);
}
}
} finally {
out.write("</p>\n</body>\n</html>");
}
}
protected void persistBatch(PreparedStatement ps) throws SQLException {
int[] batchResults = null;
try {
batchResults = ps.executeBatch();
int failCount = 0;
for (int i = 0; i < batchResults.length; i++) {
if (batchResults[i] == Statement.EXECUTE_FAILED) {
failCount++;
}
}
if (failCount > 0) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < batchResults.length; i++) {
if (batchResults[i] == Statement.EXECUTE_FAILED) {
b.append(i).append(" ");
}
}
log.warn("Batch failed to perform " + failCount + " updates, indexes: " + b);
} else if (log.isDebugEnabled()) {
log.debug("Successfully persisted batch of size: " + batchResults.length + " total " + failCount + " failures");
}
} catch (BatchUpdateException be) {
log.warn("Caught BatchUpdateException, one or more batch update have failed: " + be.getMessage(), be);
throw be;
} catch (SQLException sqle) {
log.error("Error committing last batch", sqle);
throw sqle;
}
}
private Vector<String> saveLinkLocalPrivateIPRange(final TransactionLegacy txn, long startIP, final long endIP, final long podId, final long zoneId) {
final String insertSql = "INSERT INTO `cloud`.`op_dc_link_local_ip_address_alloc` (ip_address, data_center_id, pod_id) VALUES (?, ?, ?)";
final Vector<String> problemIPs = new Vector<>();
Connection conn = null;
try {
conn = txn.getConnection();
} catch (final SQLException e) {
System.out.println("Exception: " + e.getMessage());
printError("Unable to start DB connection to save private IPs. Please contact Cloud Support.");
}
final long start = startIP;
try (PreparedStatement stmt = conn.prepareStatement(insertSql)) {
while (startIP <= endIP) {
stmt.setString(1, NetUtils.long2Ip(startIP++));
stmt.setLong(2, zoneId);
stmt.setLong(3, podId);
stmt.addBatch();
}
final int[] results = stmt.executeBatch();
for (int i = 0; i < results.length; i += 2) {
if (results[i] == Statement.EXECUTE_FAILED) {
problemIPs.add(NetUtils.long2Ip(start + (i / 2)));
}
}
} catch (final Exception ex) {
System.out.println("saveLinkLocalPrivateIPRange. Exception: " + ex.getMessage());
}
return problemIPs;
}
/**
* Indicate that result is an Error, to set appropriate results.
*
* @param moreResultAvailable indicate if other results (ResultSet or updateCount) are available.
*/
public void addStatsError(boolean moreResultAvailable) {
if (cmdInformation == null) {
if (batch) {
cmdInformation = new CmdInformationBatch(expectedSize, autoIncrement);
} else if (moreResultAvailable) {
cmdInformation = new CmdInformationMultiple(expectedSize, autoIncrement);
} else {
cmdInformation = new CmdInformationSingle(0, Statement.EXECUTE_FAILED, autoIncrement);
return;
}
}
cmdInformation.addErrorStat();
}
protected void processResult(int[] lastResult) {
boolean foundError = false;
for (int i : lastResult) {
if (i == Statement.EXECUTE_FAILED) foundError = true;
results.add(i);
}
// A little bit of paranoid checking here? Most drivers will throw BatchUpdateException perhaps?
if (batchCount != lastResult.length) {
log.warning("Problem executing batch - expected result length of " + batchCount + " but got " + lastResult.length);
} else if (foundError) {
log.warning("Problem executing batch - at least one result failed in: " + DefaultGroovyMethods.toList(lastResult));
} else {
log.fine("Successfully executed batch with " + lastResult.length + " command(s)");
}
}
/**
* Identify which commands in the batch failed and redirect these on the error port.
* See https://docs.oracle.com/javase/7/docs/api/java/sql/BatchUpdateException.html for more details
*
* @param updateCounts
* @param commandsInBatch
*/
protected void processUpdateCounts(int[] updateCounts, int commandsInBatch)
{
if (updateCounts.length < commandsInBatch) {
// Driver chose not to continue processing after failure.
error.emit(tuples.get(updateCounts.length + batchStartIdx));
errorTuples++;
// In this case, updateCounts is the number of successful queries
tuplesWrittenSuccessfully += updateCounts.length;
// Skip the error record
batchStartIdx += updateCounts.length + 1;
// And process the remaining if any
if ((tuples.size() - batchStartIdx) > 0) {
processBatch();
}
} else {
// Driver processed all batch statements in spite of failures.
// Pick out the failures and send on error port.
tuplesWrittenSuccessfully = commandsInBatch;
for (int i = 0; i < commandsInBatch; i++) {
if (updateCounts[i] == Statement.EXECUTE_FAILED) {
error.emit(tuples.get(i + batchStartIdx));
errorTuples++;
tuplesWrittenSuccessfully--;
}
}
}
}
public static void printResults(String query, int[] counts, List<StringMessage> resp) throws IOException{
resp.add(new StringMessage("Message",
"For query: " + ESAPI.encoder().encodeForHTML(query) + "<br>"
));
try {
if(counts.length > 0){
if(counts[0] == Statement.SUCCESS_NO_INFO){
resp.add(new StringMessage("Message",
"The SQL query was processed successfully but the number of rows affected is unknown."
));
System.out.println("The SQL query was processed successfully but the number of rows affected is unknown.");
}else if(counts[0] == Statement.EXECUTE_FAILED){
resp.add(new StringMessage("Message",
"The SQL query failed to execute successfully and occurs only if a driver continues to process commands after a command fails"
));
System.out.println("The SQL query failed to execute successfully and occurs only if a driver continues to process commands after a command fails");
}else{
resp.add(new StringMessage("Message",
"The number of affected rows are: " + counts[0]
));
System.out.println("The number of affected rows are: " + counts[0]);
}
}
} finally {
resp.add(new StringMessage("Message",
"</p>\n</body>\n</html>"
));
}
}
@Override
protected boolean insertBatch(PreparedStatement pstmt) throws SQLException {
for (JdbcEntryData pendingEntry : TeradataBufferedInserter.this.pendingInserts) {
int i = 1;
for (JdbcEntryDatum datum : pendingEntry) {
Object value = datum.getVal();
if (value != null) {
pstmt.setObject(i, value);
} else {
// Column type is needed for null value insertion
pstmt.setNull(i, columnPosSqlTypes.get(i));
}
i++;
}
pstmt.addBatch();
pstmt.clearParameters();
}
if (LOG.isDebugEnabled()) {
LOG.debug("Executing SQL " + pstmt);
}
int[] execStatus = pstmt.executeBatch();
// Check status explicitly if driver continues batch insertion upon failure
for (int status : execStatus) {
if (status == Statement.EXECUTE_FAILED) {
throw new BatchUpdateException("Batch insert failed.", execStatus);
}
}
return true;
}
private String[] findBatchUpdateFailureSql(int[] statuses, String[] executables) {
List<String> fails = new LinkedList<String>();
int total = 0;
for (int i = 0; i < statuses.length; i++) {
if (statuses[i] == Statement.EXECUTE_FAILED) {
fails.add(Strings.join("[", String.valueOf(++total), "]", executables[i]));
}
}
return fails.toArray(new String[0]);
}
private Vector<String> saveLinkLocalPrivateIPRange(TransactionLegacy txn, long startIP, long endIP, long podId, long zoneId) {
String insertSql = "INSERT INTO `cloud`.`op_dc_link_local_ip_address_alloc` (ip_address, data_center_id, pod_id) VALUES (?, ?, ?)";
Vector<String> problemIPs = new Vector<String>();
Connection conn = null;
try {
conn = txn.getConnection();
} catch (SQLException e) {
System.out.println("Exception: " + e.getMessage());
printError("Unable to start DB connection to save private IPs. Please contact Cloud Support.");
}
long start = startIP;
try(PreparedStatement stmt = conn.prepareStatement(insertSql);)
{
while (startIP <= endIP) {
stmt.setString(1, NetUtils.long2Ip(startIP++));
stmt.setLong(2, zoneId);
stmt.setLong(3, podId);
stmt.addBatch();
}
int[] results = stmt.executeBatch();
for (int i = 0; i < results.length; i += 2) {
if (results[i] == Statement.EXECUTE_FAILED) {
problemIPs.add(NetUtils.long2Ip(start + (i / 2)));
}
}
} catch (Exception ex) {
System.out.println("saveLinkLocalPrivateIPRange. Exception: " + ex.getMessage());
}
return problemIPs;
}
private boolean succ(long updateCount) {
// TODO 2019-10-28 -1?
return updateCount != Statement.EXECUTE_FAILED;
}
/**
* Performs the batch for the given statement, and checks that the specified amount of rows have been changed.
*
* @param statement The prepared statement
* @param numRows The number of rows that should change
* @param table The changed table
*/
// GemStone changes BEGIN
private void executeBatch(PreparedStatement statement, int numRows,
Table table, DynaBean[] batchDynaBeans, Column[] autoIncrColumns)
throws DatabaseOperationException
/* (original code)
private void executeBatch(PreparedStatement statement, int numRows, Table table) throws DatabaseOperationException
*/
// GemStone changes BEGIN
{
if (statement != null)
{
try
{
Connection connection = statement.getConnection();
beforeInsert(connection, table);
int[] results = statement.executeBatch();
// GemStone changes BEGIN
if (batchDynaBeans != null) {
handleAutoIncrementValuesForBatch(statement,
autoIncrColumns, batchDynaBeans, numRows);
}
// GemStone changes END
closeStatement(statement);
afterInsert(connection, table);
boolean hasSum = true;
int sum = 0;
for (int idx = 0; (results != null) && (idx < results.length); idx++)
{
if (results[idx] < 0)
{
hasSum = false;
if (results[idx] == Statement.EXECUTE_FAILED)
{
_log.warn("The batch insertion of row " + idx + " into table " + table.getQualifiedName() + " failed but the driver is able to continue processing");
}
else if (results[idx] != Statement.SUCCESS_NO_INFO)
{
_log.warn("The batch insertion of row " + idx + " into table " + table.getQualifiedName() + " returned an undefined status value " + results[idx]);
}
}
else
{
sum += results[idx];
}
}
if (hasSum && (sum != numRows))
{
_log.warn("Attempted to insert " + numRows + " rows into table " + table.getQualifiedName() + " but changed " + sum + " rows");
}
}
catch (SQLException ex)
{
if (ex instanceof BatchUpdateException)
{
SQLException sqlEx = ((BatchUpdateException)ex).getNextException();
throw new DatabaseOperationException("Error while inserting into the database", sqlEx);
}
else
{
throw new DatabaseOperationException("Error while inserting into the database", ex);
}
}
}
}
/**
* <p>This method can be called with three cases:
*
* <ul>
* <li>Case 1: Success. statementResults contains the number of
* affected rows for all operations.
* <li>Case 2: Failure. statementResults contains the number of
* affected rows for all successful operations that were executed
* before the failed operation.
* <li>Case 3: Failure. statementResults contains the number of
* affected rows for all operations of the batch, i.e. further
* statements were executed after the first failed statement.
* </ul>
*
* <p>See {@link BatchUpdateException#getUpdateCounts()} for the specification
* of cases 2 and 3.
*
* @return all failed operations
*/
protected void postProcessJdbcBatchResult(
Iterator<DbOperation> operationsIt,
int[] statementResults,
Exception failure,
List<DbOperation> failedOperations) {
boolean failureHandled = false;
for (int i = 0; i < statementResults.length; i++) {
int statementResult = statementResults[i];
EnsureUtil.ensureTrue("More batch results than scheduled operations detected. This indicates a bug",
operationsIt.hasNext());
DbOperation operation = operationsIt.next();
if (statementResult == Statement.SUCCESS_NO_INFO) {
if (requiresAffectedRows(operation.getOperationType())) {
throw LOG.batchingNotSupported(operation);
} else {
postProcessOperationPerformed(operation, 1, null);
}
} else if (statementResult == Statement.EXECUTE_FAILED) {
/*
* All operations are marked with the root failure exception; this is not quite
* correct and leads to the situation that we treat all failed operations in the
* same way, whereas they might fail for different reasons.
*
* More precise would be to use BatchUpdateException#getNextException.
* E.g. if we have three failed statements in a batch, #getNextException can be used to
* access each operation's individual failure. However, this behavior is not
* guaranteed by the java.sql javadocs (it doesn't specify that the number
* and order of next exceptions matches the number of failures, unlike for row counts),
* so we decided to not rely on it.
*/
postProcessOperationPerformed(operation, 0, failure);
failureHandled = true;
} else { // it is the number of affected rows
postProcessOperationPerformed(operation, statementResult, null);
}
if (operation.isFailed()) {
failedOperations.add(operation);
}
}
/*
* case 2: The next operation is the one that failed
*/
if (failure != null && !failureHandled) {
EnsureUtil.ensureTrue("More batch results than scheduled operations detected. This indicates a bug",
operationsIt.hasNext());
DbOperation failedOperation = operationsIt.next();
postProcessOperationPerformed(failedOperation, 0, failure);
failedOperations.add(failedOperation);
}
}
/**
* Performs the batch for the given statement, and checks that the specified amount of rows have been changed.
*
* @param statement The prepared statement
* @param numRows The number of rows that should change
* @param table The changed table
*/
// GemStone changes BEGIN
private void executeBatch(PreparedStatement statement, int numRows,
Table table, DynaBean[] batchDynaBeans, Column[] autoIncrColumns)
throws DatabaseOperationException
/* (original code)
private void executeBatch(PreparedStatement statement, int numRows, Table table) throws DatabaseOperationException
*/
// GemStone changes BEGIN
{
if (statement != null)
{
try
{
Connection connection = statement.getConnection();
beforeInsert(connection, table);
int[] results = statement.executeBatch();
// GemStone changes BEGIN
if (batchDynaBeans != null) {
handleAutoIncrementValuesForBatch(statement,
autoIncrColumns, batchDynaBeans, numRows);
}
// GemStone changes END
closeStatement(statement);
afterInsert(connection, table);
boolean hasSum = true;
int sum = 0;
for (int idx = 0; (results != null) && (idx < results.length); idx++)
{
if (results[idx] < 0)
{
hasSum = false;
if (results[idx] == Statement.EXECUTE_FAILED)
{
_log.warn("The batch insertion of row " + idx + " into table " + table.getQualifiedName() + " failed but the driver is able to continue processing");
}
else if (results[idx] != Statement.SUCCESS_NO_INFO)
{
_log.warn("The batch insertion of row " + idx + " into table " + table.getQualifiedName() + " returned an undefined status value " + results[idx]);
}
}
else
{
sum += results[idx];
}
}
if (hasSum && (sum != numRows))
{
_log.warn("Attempted to insert " + numRows + " rows into table " + table.getQualifiedName() + " but changed " + sum + " rows");
}
}
catch (SQLException ex)
{
if (ex instanceof BatchUpdateException)
{
SQLException sqlEx = ((BatchUpdateException)ex).getNextException();
throw new DatabaseOperationException("Error while inserting into the database", sqlEx);
}
else
{
throw new DatabaseOperationException("Error while inserting into the database", ex);
}
}
}
}
/**
* This method sends error records to output and counts errors. If array <i>records</i> is null, only counting of errors is performed
*
* @param records potential rejected records
* @param recCount number of records in batch
* @param ex thrown exception
* @param rejectedPort rejected Port
* @throws IOException
* @throws InterruptedException
*/
private void flushErrorRecords(DataRecord[][] records,int recCount, BatchUpdateException[] ex, OutputPort rejectedPort)
throws IOException,InterruptedException {
// if (records==null) return;
int[] updateCounts;
int count;
SQLException exception;
StringBuilder message = new StringBuilder();
//for each statement exception has occurred
for (int i=0; i < ex.length; i++) {
if (ex[i] != null) {
exception = ex[i];
updateCounts = ex[i].getUpdateCounts();
count = 0;
while(count<updateCounts.length){
if (updateCounts[count] == Statement.EXECUTE_FAILED) {
//increase error counter, fill rejected record and log error message
countError++;
if (records != null && records[i][count] != null) {
if (exception != null) {
if (errMessFieldNum != -1) {
records[i][count].getField(errMessFieldNum).setValue("Exception thrown by: " +
statement[i].getQuery() + ". Message: " + ExceptionUtils.getMessage(exception));
}
if (errorCodeFieldNum != -1){
records[i][count].getField(errorCodeFieldNum).setValue(exception.getErrorCode());
}
}
if (exception != null && countError <= MAX_WARNINGS) {
logger.warn("Exception thrown by: " + statement[i].getQuery() +
". Message: " + ExceptionUtils.getMessage(exception));
} else if (exception == null && countError <= MAX_WARNINGS) {
logger.warn("Record not inserted to database");
} else if (countError == MAX_WARNINGS + 1) {
logger.warn("more errors...");
}
rejectedPort.writeRecord(records[i][count]);
if (exception != null) {
exception = exception.getNextException();
}
}else if (records != null){//records[i][count] == null - it wasn't added to batch, prepare for next batch
records[i][count] = DataRecordFactory.newRecord(rejectedPort.getMetadata());
}
}
count++;
}
// flush rest of the records for which we don't have update counts
message.setLength(0);
Integer errCode = exception != null ? exception.getErrorCode() : null;
while (exception != null) {
message.append(exception.getMessage());
exception = exception.getNextException();
}
while(count<recCount){
if (records != null && records[i][count] != null) {
if (message.length() > 0 && countError <= MAX_WARNINGS) {
logger.warn(message);
} else if (message.length() > 0
&& countError == MAX_WARNINGS + 1) {
logger.warn("more errors...");
}
if (message.length() > 0 && i < recCount) {
if (errMessFieldNum != -1) {
records[i][count].getField(errMessFieldNum).setValue(message);
}
if (errorCodeFieldNum != -1){
records[i][count].getField(errorCodeFieldNum).setValue(errCode);
}
}
message = new StringBuilder("Record not inserted to database");
countError++;
rejectedPort.writeRecord(records[i][count]);
}else if (records != null){
records[i][count] = DataRecordFactory.newRecord(rejectedPort.getMetadata());
}
count++;
}
}
}
//clear errors
Arrays.fill(ex, null);
}
/**
* Sets row as failed.
*
* @param rowNum Row number.
*/
public void setFailed(int rowNum) {
cntPerRow[rowNum] = Statement.EXECUTE_FAILED;
}