2014-04-10 16 views
8

Come sappiamo, c'è un modo semplice per lanciare qualsiasi record di tipo composito corrispondente PostgreSQL, in questo modo:PostgreSQL getto record tipo composito

CREATE TYPE test.t_test AS (
    mytext text, 
    myint integer 
); 

SELECT ('text', 10)::test.t_test; -- will succeed 

Ma un inconveniente con questo è che - se il tipo di destinazione viene modificato (si aggiunge ad esempio un campo) - il cast sarà poi pausa :(

ALTER TYPE test.t_test ADD ATTRIBUTE mychar char(1); 

SELECT ('text', 10)::test.t_test; -- will fail 

CREATE CAST per questo caso può aiutare ma non può passare una pseudo-tipo come RECORD come argomento di una funzione di casting. E né l'ereditarietà del tipo né il tipo composito anche i valori predefiniti (come la tabella) funzionano. C'è un altro modo per ottenere la compatibilità qui?

Naturalmente è possibile utilizzare del cast-funzioni esplicite come CREATE FUNCTION test.to_t_test(t text, i integer, c char DEFAULT '') RETURNS test.t_test e poi fare

SELECT test.to_t_test('text', 10) -- OK 
SELECT test.to_t_test('text', 10, '1') -- OK 

quindi utilizzare i valori dei parametri predefiniti. Ma in questo modo non è né chiaro né confortevole.

risposta

2

La mia raccomandazione è che se avete bisogno di fare questo poi prendere uno dei seguenti approcci:

  1. dinamica scoperta della struttura (utilizzando la tabella di catalogo pg_attribute). Questo non è garantito per essere sicuro in futuro, ma probabilmente lo è. Ha anche un sacco di trucchi (non usare attributi con un contenuto inferiore a 0 per esempio). Questo di solito è l'approccio che prendo e ho librerie scritte in Perl per fare tale scoperta sul client-end.

  2. Creare un tipo di utilizzo e un tipo di archiviazione e disporre di un cast tra di loro In questo modo è possibile eseguire un SELECT ('testo', 10) :: test.used_test :: test.stored_test e funzionerà correttamente. Ma c'è un motivo per cui non puoi trasmettere record a un tipo composito.

Problemi correlati