Domanda

Ho dichiarato la seguente tabella per l'utilizzo da parte di trigger di controllo:

CREATE TABLE audit_transaction_ids (id IDENTITY PRIMARY KEY, uuid VARCHAR UNIQUE NOT NULL, `time` TIMESTAMP NOT NULL);
  1. Il trigger viene richiamato più volte nella stessa transazione.

  2. La prima volta che il grilletto è richiamato, voglio inserire un nuovo riga con l'attuale TRANSACTION_ID() e tempo.

  3. Le volte successive il trigger viene richiamato, voglio tornare l'esistente "id" (invoco Istruzione.getGeneratedKeys() alla fine) senza alterare "uuid" o "tempo".

L'attuale schema sembra avere due problemi.

  1. Quando invoco MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES(TRANSACTION_ID(), NOW()) Ottengo: org.h2.jdbc.JdbcSQLException: Column "ID" contains null values; SQL statement: MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES (TRANSACTION_ID(), NOW()) [90081-155]

  2. Ho il sospetto che la chiamata di UNIRE su una riga esistente alterare "il tempo".

Come faccio a risolvere entrambi questi problemi?

È stato utile?

Soluzione

MERGE analoga è la java.util.Map.put(key, value):si inserisce la riga, se non esiste, e l'aggiornamento della riga, se lo fa.Detto questo, è ancora possibile unire in una tabella contenente AUTO_INCREMENT le colonne così a lungo come si utilizza un'altra colonna come chiave.

Dato customer[id identity, email varchar(30), count int] si potrebbe merge into customer(id, email, count) key(email) values((select max(id) from customer c2 where c2.email='test@acme.com'), 'test@acme.com', 10).Significato, ri-utilizzare l'id di un record esistente, è possibile utilizzare null altrimenti.

Vedi anche https://stackoverflow.com/a/18819879/14731 per un portatile modo per inserire o aggiornare a seconda se una riga già esistente.


1.UNIRE IN audit_transaction_ids (uuid, tempo) KEY(id) VALUES(TRANSACTION_ID(), NOW())

Se si desidera inserire una nuova riga, utilizzare:INSERT INTO audit_transaction_ids (uuid, time) VALUES(TRANSACTION_ID(), NOW())

MERGE senza impostare il valore per la colonna ID non ha senso se ID viene utilizzato come chiave, perché in quel modo non avrebbe mai potuto (anche in teoria) un aggiornamento righe esistenti.Quello che si potrebbe fare è usare un'altra chiave di colonna (nel caso di sopra, non c'è colonna che potrebbe essere utilizzato).Vedere la documentazione per MERGE per ulteriori dettagli.

2.Invocando l'UNIONE in una riga esistente alterare "il tempo"

Non so se ti riferisci al fatto che il valore della colonna "tempo" è alterato.Questo è il comportamento previsto, se si utilizza MERGE ... VALUES(.., NOW()), perché il MERGE istruzione dovrebbe aggiornare la colonna.

O forse vuoi dire che le vecchie versioni di H2 restituito valori diversi all'interno della stessa transazione (a differenza di altri database, che restituiscono lo stesso valore all'interno della stessa transazione).Questo è vero, però con la versione H2 1.3.155 (2011-05-27) e, più tardi, questa incompatibilità è stato risolto.Vedere anche il change log:"CURRENT_TIMESTAMP() e così via ora restituiscono lo stesso valore all'interno di una transazione." Sembra che questo non è il problema nel tuo caso, perché non sembrano utilizzare la versione 1.3.155 (il messaggio di errore [90081-155] comprende la costruzione / numero di versione).

Altri suggerimenti

Risposta Breve:

UNIRE IN AUDIT_TRANSACTION_IDS (uuid, tempo) CHIAVE (uuid, tempo) VALORI (TRANSACTION_ID(), NOW());

po ' di prestazioni di punta:assicurarsi uuid è indicizzato

Risposta Lunga:

MERGE è fondamentalmente un UPDATE che INSERTs quando nessun record trovato per essere aggiornati.

Wikipedia dà una più concisa, standardizzato sintassi di UNIRE ma è necessario fornire il proprio aggiornamento e di inserimento.(Se questo sarà supportato in H2 o meno, non sta a me rispondere)

Così come si aggiorna un record utilizzando MERGE in H2?Si definisce una chiave per essere guardato, se si è constatato che si aggiorna la riga (con i nomi di colonna di fornitura, e si può definire DEFAULT qui, per ripristinare le colonne per i suoi valori di default), altrimenti si inserisce la riga.

Ora, qual è Null? Null significa sconosciuto, non trovato, indefinito, qualcosa che non è quello che stai cercando.

Che è il motivo per cui Null funziona come chiave per essere guardato per.Perché significa che il record non è stato trovato.

MERGE INTO tabella1 (id, col1, col2) KEY(id) VALUES (Null, 1, 2)

Null ha un valore.SI tratta di un valore.

Ora vediamo di SQL.

MERGE INTO tabella1 (id, col1, col2) KEY(id) (VALORI di DEFAULT, 1, 2)

Che cosa è che questo significhi?A me, dice Ho questo [DEFAULT, 1, 2], mi trovi un DEFAULT nella colonna id, quindi aggiornare col1 per 1, col2 per 2, se trovato.in caso contrario, inserire di default per id, Da 1 a col1, 2 a col2.

Vedere quello che ho sottolineato lì?Che cosa vuol dire?Che cosa è DEFAULT?Come si fa a confrontare DEFAULT per id?

DEFAULT è una parola chiave.

Si può fare cose come questa,

MERGE INTO tabella1 (id, col1, timeStampCol) KEY(id) VALUES (Null, 1, Di DEFAULT)

ma non mettere di DEFAULT nella colonna di chiave.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top