Qu'est-ce que j'ai est en dessous de la table. MAINTENANT, je tire une requête avec des détails ci-dessous, dites p> : strong> Ceci est une même requête. En fait, je mettez en place Modifier à partir de quatre champs de texte. Alors, qu'est-ce que j'aurais utiliser JSF et Java Bean seraient comme ci-dessous. P> Ce que je veux utilisera la requête supérieure, quelles colonnes sont mises à jour. Dans la case ci-dessus, la colonne essentiellement, je le veux pour le but du logement où je voudrais savoir qui a fait la modification et quelle modification est effectuée. Toute idée / suggestion comment faire ce fait? P> Note: strong> Je ne veux pas créer d'autre table comme indiqué dans la réponse par MeEwok. Il suffit d'utiliser la requête, j'aimerais connaître les noms de colonne mises à jour. Strong> em> p> Disons VAL1 code> est mise à jour. P>
=================================================================
whoDid whatDid forWhom whichField whichSection whatTime
=================================================================
userA edit userB emailId User time_whenDid
userA edit userB fullName User time_whenDid
=================================================================
4 Réponses :
Vous pouvez faire l'une des opérations suivantes:
Si vous voulez vraiment le faire en requête, une approche intéressante est l'option 2 ... p>
Ce tableau stockera les valeurs précédentes lorsqu'un changement est effectué. Si aucune modification n'est faite (NULL) sera entrée. P> 3) exécutez une mise à jour à la vue, à l'aide de conditions dans la mise à jour: strong> p> update tableNameView
SET val1_prev = CASE
WHEN val1 = INPUT_VAL1 THEN NULL
WHEN NOT val1 = INPUT_VAL1 THEN val1
END,
val2_prev = CASE
WHEN val2 = INPUT_VAL2 THEN NULL
WHEN NOT val2 = INPUT_VAL2 THEN val2
END,
... ,
val1='newVal1', val2='data2', ... ,
where id = INPUT_ID;
Que diriez-vous de courir quelque chose comme la requête suivante pour créer l'entrée de journal Clause de non-responsabilité: strong> Ceci est au sommet de ma tête et complètement non testée afin qu'il puisse avoir besoin d'un peu de peaufine - devrait être suffisant pour vous aider à aller. P> problème possible: strong> Même si vous exécutez la requête juste Avant la mise à jour, une chance peut avoir changé entre les deux. En fonction de divers facteurs, cela peut ne pas être un problème dans la pratique, mais il convient de mentionner. P> p>
Je vais vérifier cela et vous revenir demain.
Non coché encore ... le fera bientôt ... je suis sangtité dans un autre travail ... Désolé pour une réponse tardive ... j'accepterai une fois terminé ..
Pas encore ... occupé dans un autre emploi ... mais une fois terminé, je vous tiendrai à jour ... mais je pense que cette idée va basculer.
Vous pouvez essayer ce code. Il stocke la journalisation de la classe de stockage. Vous pouvez modifier le stockage en fonction de votre exigence. Ce code ne fonctionne que si le DB est accessible par public static void main(String[] args) {
PreparedStatement psmt = new LoggingPreparedStatement(conn.prepareStatement(
" UPDATE tableName SET val1 =?,val2 =?,val3 =?,val4 =? WHERE id = 1 "));
psmt.setString(1, myValue1);
psmt.setString(2, myValue2);
psmt.setString(3, myValue3);
psmt.setString(4, myValue4);
psmt.execute();
for (Trail trail : Storage.INSTANCE.getTrails()) {
System.out.println(trail);
}
}
public static class Trail {
private final int fieldIdx;
private final String prevValue;
private final String currentValue;
private Trail(int fieldIdx, String prevValue, String currentValue) {
this.fieldIdx = fieldIdx;
this.prevValue = prevValue;
this.currentValue = currentValue;
}
public int getFieldIdx() {
return fieldIdx;
}
public String getPrevValue() {
return prevValue;
}
public String getCurrentValue() {
return currentValue;
}
@Override
public String toString() {
return "Trail{" +
"fieldIdx=" + fieldIdx +
", prevValue='" + prevValue + '\'' +
", currentValue='" + currentValue + '\'' +
'}';
}
}
public enum Storage {
INSTANCE;
private final ConcurrentMap<Integer, String> lastValues = new ConcurrentHashMap<Integer, String>();
private final Queue<Trail> trails = new ConcurrentLinkedQueue<Trail>();
private final Object lock = new Object();
public void putTrailIfNecessary(int idx, String newValue) {
String lastValue = lastValues.get(idx);
if (lastValue == null ? newValue != null : !lastValue.equals(newValue)) {
synchronized (lock) {
String lastValue1 = lastValues.get(idx);
if (lastValue1 == null ? newValue != null : !lastValue1.equals(newValue)) {
lastValues.put(idx, newValue);
trails.add(new Trail(idx, lastValue1, newValue));
}
}
}
}
public List<Trail> getTrails() {
return new ArrayList<Trail>(trails);
}
}
public static class LoggingPreparedStatement
implements PreparedStatement {
private final PreparedStatement delegate;
public LoggingPreparedStatement(PreparedStatement delegate) {
this.delegate = delegate;
}
// this we put audit trail
@Override
public void setString(int parameterIndex, String x)
throws SQLException {
Storage.INSTANCE.putTrailIfNecessary(parameterIndex, x);
delegate.setString(parameterIndex, x);
}
@Override
public ResultSet executeQuery()
throws SQLException {return delegate.executeQuery();}
@Override
public int executeUpdate()
throws SQLException {return delegate.executeUpdate();}
@Override
public void setNull(int parameterIndex, int sqlType)
throws SQLException {delegate.setNull(parameterIndex, sqlType);}
@Override
public void setBoolean(int parameterIndex, boolean x)
throws SQLException {delegate.setBoolean(parameterIndex, x);}
@Override
public void setByte(int parameterIndex, byte x)
throws SQLException {delegate.setByte(parameterIndex, x);}
@Override
public void setShort(int parameterIndex, short x)
throws SQLException {delegate.setShort(parameterIndex, x);}
@Override
public void setInt(int parameterIndex, int x)
throws SQLException {delegate.setInt(parameterIndex, x);}
@Override
public void setLong(int parameterIndex, long x)
throws SQLException {delegate.setLong(parameterIndex, x);}
@Override
public void setFloat(int parameterIndex, float x)
throws SQLException {delegate.setFloat(parameterIndex, x);}
@Override
public void setDouble(int parameterIndex, double x)
throws SQLException {delegate.setDouble(parameterIndex, x);}
@Override
public void setBigDecimal(int parameterIndex, BigDecimal x)
throws SQLException {delegate.setBigDecimal(parameterIndex, x);}
@Override
public void setBytes(int parameterIndex, byte[] x)
throws SQLException {delegate.setBytes(parameterIndex, x);}
@Override
public void setDate(int parameterIndex, Date x)
throws SQLException {delegate.setDate(parameterIndex, x);}
@Override
public void setTime(int parameterIndex, Time x)
throws SQLException {delegate.setTime(parameterIndex, x);}
@Override
public void setTimestamp(int parameterIndex,
Timestamp x)
throws SQLException {delegate.setTimestamp(parameterIndex, x);}
@Override
public void setAsciiStream(int parameterIndex, InputStream x, int length)
throws SQLException {delegate.setAsciiStream(parameterIndex, x, length);}
@Override
public void setUnicodeStream(int parameterIndex, InputStream x, int length)
throws SQLException {delegate.setUnicodeStream(parameterIndex, x, length);}
@Override
public void setBinaryStream(int parameterIndex, InputStream x, int length)
throws SQLException {delegate.setBinaryStream(parameterIndex, x, length);}
@Override
public void clearParameters()
throws SQLException {delegate.clearParameters();}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType)
throws SQLException {delegate.setObject(parameterIndex, x, targetSqlType);}
@Override
public void setObject(int parameterIndex, Object x)
throws SQLException {delegate.setObject(parameterIndex, x);}
@Override
public boolean execute()
throws SQLException {return delegate.execute();}
@Override
public void addBatch()
throws SQLException {delegate.addBatch();}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, int length)
throws SQLException {delegate.setCharacterStream(parameterIndex, reader, length);}
@Override
public void setRef(int parameterIndex, Ref x)
throws SQLException {delegate.setRef(parameterIndex, x);}
@Override
public void setBlob(int parameterIndex, Blob x)
throws SQLException {delegate.setBlob(parameterIndex, x);}
@Override
public void setClob(int parameterIndex, Clob x)
throws SQLException {delegate.setClob(parameterIndex, x);}
@Override
public void setArray(int parameterIndex, Array x)
throws SQLException {delegate.setArray(parameterIndex, x);}
@Override
public ResultSetMetaData getMetaData()
throws SQLException {return delegate.getMetaData();}
@Override
public void setDate(int parameterIndex, Date x, Calendar cal)
throws SQLException {delegate.setDate(parameterIndex, x, cal);}
@Override
public void setTime(int parameterIndex, Time x, Calendar cal)
throws SQLException {delegate.setTime(parameterIndex, x, cal);}
@Override
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
throws SQLException {delegate.setTimestamp(parameterIndex, x, cal);}
@Override
public void setNull(int parameterIndex, int sqlType, String typeName)
throws SQLException {delegate.setNull(parameterIndex, sqlType, typeName);}
@Override
public void setURL(int parameterIndex, URL x)
throws SQLException {delegate.setURL(parameterIndex, x);}
@Override
public ParameterMetaData getParameterMetaData()
throws SQLException {return delegate.getParameterMetaData();}
@Override
public void setRowId(int parameterIndex, RowId x)
throws SQLException {delegate.setRowId(parameterIndex, x);}
@Override
public void setNString(int parameterIndex, String value)
throws SQLException {delegate.setNString(parameterIndex, value);}
@Override
public void setNCharacterStream(int parameterIndex, Reader value, long length)
throws SQLException {delegate.setNCharacterStream(parameterIndex, value, length);}
@Override
public void setNClob(int parameterIndex, NClob value)
throws SQLException {delegate.setNClob(parameterIndex, value);}
@Override
public void setClob(int parameterIndex, Reader reader, long length)
throws SQLException {delegate.setClob(parameterIndex, reader, length);}
@Override
public void setBlob(int parameterIndex, InputStream inputStream, long length)
throws SQLException {delegate.setBlob(parameterIndex, inputStream, length);}
@Override
public void setNClob(int parameterIndex, Reader reader, long length)
throws SQLException {delegate.setNClob(parameterIndex, reader, length);}
@Override
public void setSQLXML(int parameterIndex, SQLXML xmlObject)
throws SQLException {delegate.setSQLXML(parameterIndex, xmlObject);}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength)
throws SQLException {delegate.setObject(parameterIndex, x, targetSqlType, scaleOrLength);}
@Override
public void setAsciiStream(int parameterIndex, InputStream x, long length)
throws SQLException {delegate.setAsciiStream(parameterIndex, x, length);}
@Override
public void setBinaryStream(int parameterIndex, InputStream x, long length)
throws SQLException {delegate.setBinaryStream(parameterIndex, x, length);}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, long length)
throws SQLException {delegate.setCharacterStream(parameterIndex, reader, length);}
@Override
public void setAsciiStream(int parameterIndex, InputStream x)
throws SQLException {delegate.setAsciiStream(parameterIndex, x);}
@Override
public void setBinaryStream(int parameterIndex, InputStream x)
throws SQLException {delegate.setBinaryStream(parameterIndex, x);}
@Override
public void setCharacterStream(int parameterIndex, Reader reader)
throws SQLException {delegate.setCharacterStream(parameterIndex, reader);}
@Override
public void setNCharacterStream(int parameterIndex, Reader value)
throws SQLException {delegate.setNCharacterStream(parameterIndex, value);}
@Override
public void setClob(int parameterIndex, Reader reader)
throws SQLException {delegate.setClob(parameterIndex, reader);}
@Override
public void setBlob(int parameterIndex, InputStream inputStream)
throws SQLException {delegate.setBlob(parameterIndex, inputStream);}
@Override
public void setNClob(int parameterIndex, Reader reader)
throws SQLException {delegate.setNClob(parameterIndex, reader);}
@Override
public ResultSet executeQuery(String sql)
throws SQLException {return delegate.executeQuery(sql);}
@Override
public int executeUpdate(String sql)
throws SQLException {return delegate.executeUpdate(sql);}
@Override
public void close()
throws SQLException {delegate.close();}
@Override
public int getMaxFieldSize()
throws SQLException {return delegate.getMaxFieldSize();}
@Override
public void setMaxFieldSize(int max)
throws SQLException {delegate.setMaxFieldSize(max);}
@Override
public int getMaxRows()
throws SQLException {return delegate.getMaxRows();}
@Override
public void setMaxRows(int max)
throws SQLException {delegate.setMaxRows(max);}
@Override
public void setEscapeProcessing(boolean enable)
throws SQLException {delegate.setEscapeProcessing(enable);}
@Override
public int getQueryTimeout()
throws SQLException {return delegate.getQueryTimeout();}
@Override
public void setQueryTimeout(int seconds)
throws SQLException {delegate.setQueryTimeout(seconds);}
@Override
public void cancel()
throws SQLException {delegate.cancel();}
@Override
public SQLWarning getWarnings()
throws SQLException {return delegate.getWarnings();}
@Override
public void clearWarnings()
throws SQLException {delegate.clearWarnings();}
@Override
public void setCursorName(String name)
throws SQLException {delegate.setCursorName(name);}
@Override
public boolean execute(String sql)
throws SQLException {return delegate.execute(sql);}
@Override
public ResultSet getResultSet()
throws SQLException {return delegate.getResultSet();}
@Override
public int getUpdateCount()
throws SQLException {return delegate.getUpdateCount();}
@Override
public boolean getMoreResults()
throws SQLException {return delegate.getMoreResults();}
@Override
public void setFetchDirection(int direction)
throws SQLException {delegate.setFetchDirection(direction);}
@Override
public int getFetchDirection()
throws SQLException {return delegate.getFetchDirection();}
@Override
public void setFetchSize(int rows)
throws SQLException {delegate.setFetchSize(rows);}
@Override
public int getFetchSize()
throws SQLException {return delegate.getFetchSize();}
@Override
public int getResultSetConcurrency()
throws SQLException {return delegate.getResultSetConcurrency();}
@Override
public int getResultSetType()
throws SQLException {return delegate.getResultSetType();}
@Override
public void addBatch(String sql)
throws SQLException {delegate.addBatch(sql);}
@Override
public void clearBatch()
throws SQLException {delegate.clearBatch();}
@Override
public int[] executeBatch()
throws SQLException {return delegate.executeBatch();}
@Override
public Connection getConnection()
throws SQLException {return delegate.getConnection();}
@Override
public boolean getMoreResults(int current)
throws SQLException {return delegate.getMoreResults(current);}
@Override
public ResultSet getGeneratedKeys()
throws SQLException {return delegate.getGeneratedKeys();}
@Override
public int executeUpdate(String sql, int autoGeneratedKeys)
throws SQLException {return delegate.executeUpdate(sql, autoGeneratedKeys);}
@Override
public int executeUpdate(String sql, int[] columnIndexes)
throws SQLException {return delegate.executeUpdate(sql, columnIndexes);}
@Override
public int executeUpdate(String sql, String[] columnNames)
throws SQLException {return delegate.executeUpdate(sql, columnNames);}
@Override
public boolean execute(String sql, int autoGeneratedKeys)
throws SQLException {return delegate.execute(sql, autoGeneratedKeys);}
@Override
public boolean execute(String sql, int[] columnIndexes)
throws SQLException {return delegate.execute(sql, columnIndexes);}
@Override
public boolean execute(String sql, String[] columnNames)
throws SQLException {return delegate.execute(sql, columnNames);}
@Override
public int getResultSetHoldability()
throws SQLException {return delegate.getResultSetHoldability();}
@Override
public boolean isClosed()
throws SQLException {return delegate.isClosed();}
@Override
public void setPoolable(boolean poolable)
throws SQLException {delegate.setPoolable(poolable);}
@Override
public boolean isPoolable()
throws SQLException {return delegate.isPoolable();}
@Override
public <T> T unwrap(Class<T> iface)
throws SQLException {return delegate.unwrap(iface);}
@Override
public boolean isWrapperFor(Class<?> iface)
throws SQLException {return delegate.isWrapperFor(iface);}
}
Avez-vous envisagé d'utiliser un déclencheur? Ceci est basé sur l'exemple de Wikipedia :
@MAHMOUDGAMALE: J'ai essayé d'écrire une déclaration de mise à jour dans une seule requête. En fait, j'ai 32 champs sous une forme et écrire 32 requêtes pour chaque champ séparément est laid. En outre, dans cet exemple, je sais qu'un seul champ va mettre à jour. Mais par programme, je ne participerai pas à quel domaine à mettre à jour.
@MAHMOUDGAMALE: Voulez-vous dire, je devrais comparer les anciennes données VAL1 avec de nouvelles données VAL1, puis écrivez la requête de mise à jour si elles sont différentes?
Vérifiez vos champs à partir de l'application frontale pour déterminer quelle colonne est mise à jour avec une nouvelle valeur, puis effectuez la mise à jour code> pour ces champs ayant la nouvelle valeur.
@ Alya'agamal: De cette façon, je sens que c'est un long processus pour éditer les données comme d'abord, je vais d'abord comparer les données, puis traiter le travail d'édition. En outre, il augmente le fardeau de la programmation.
@Mahmoudgamal: Exactement. Avec la déclaration ci-dessus, je veux savoir quelles colonnes sont mises à jour. C'est ça.
Ce n'est pas un long processus, vous devez déjà lire les valeurs lorsque vous les affichez sur les champs de formulaire, puis vérifiez les anciennes valeurs des champs et les nouvelles valeurs lorsque vous appuyez sur la touche de mise à jour, puis mettez à jour uniquement le champ qui a une nouvelle valeur.
@ Alya'agamal: J'utilise JSF / Java et je pense que je devrai créer deux variables pour chaque domaine. Et puis comparez .... donc une déclaration avec tous les 32 champs est une bonne option. Par conséquent, je cherchais une façon de voir où MySQL peut me dire quelles colonnes sont mises à jour.
Il semble que @Mahmoudgamal ait un point, ma solution nécessitera un travail supplémentaire, je pense que ce serait mieux et plus facile de faire une déclaration code> code> uniquement.
@MAHMOUDGAMAL: Mon client veut savoir qui a fait l'édition et quelle modifie il a fait. Pour cela, je voudrais savoir quels champs sont édités ..
Qu'en est-il de faire une autre table avec les nouvelles valeurs ?? , alors vous pouvez suivre quelle colonne est mise à jour ?? !!
Donc, fondamentalement, vous souhaitez mettre à jour les champs et répertorier uniquement les champs qui sont à la fois différents des champs précédents?
@meewok: Oui, mais la rangée serait la même et elle serait déjà mise à jour. Donc, je ne peux pas comparer deux rangées ..
@ Alya'agamal: Pourquoi une nouvelle table? Pourquoi plus de programmation?
Pourquoi voulez-vous stocker quelles valeurs ont été modifiées? Comme journal ou enregistrement des changements?
@meewok: Oui, pour le logement .. Mon client voudrait savoir qui a fait la modification et quelle modification a-t-elle fait cet utilisateur ... donc je le veux pour le but de la bande.
@Fahim Parkar, fournissait une réponse à l'aide de la vue Updatible et des conditionnels de la mise à jour pour vous connecter à la deuxième table. La procédure stockée serait également une approche intéressante.
@Fahim Parkar Comment les personnes se connectent-elles avec l'application Java est-ce qu'un nom d'utilisateur et un mot de passe MySQL ou ...
@Raymondn: avec nom d'utilisateur et mot de passe ...
@Fahim Parkar Oui, mais est-ce un nom d'utilisateur et un mot de passe MySQL, ou un nom d'utilisateur et mot de passe de compte?
@RAYMONDN: Évidemment, le nom d'utilisateur est stocké dans la base de données. Je veux suivre le nom d'utilisateur avec lequel la connexion est terminée et que l'édition est terminée par cet utilisateur ...
Avez-vous besoin d'un journal uniquement pour le dernier changement ou une historique des journaux?
@xWoker: voir ma question mise à jour
@Fahimporkar Je suis désolé si c'est une question stupide, mais où est stocké le journal? Dans la base de données ou ailleurs?
@ durron597: évidemment de la base de données ...
Ummm, y a-t-il une raison pour laquelle un déclencheur sur la table qui est mis à jour n'a pas été mentionné? Cela semble être le scénario parfait pour une gâchette.