C'è un modo per utilizzare i valori delle colonne condizionale di default in una dichiarazione INSERT..SELECT?

StackOverflow https://stackoverflow.com/questions/2366580

Domanda

devo codice simile al seguente in una stored procedure che inserisce una riga in una tabella, mi piacerebbe impostare l'ultima colonna (FieldD) per @prmSomeValue meno che non sia nulla, altrimenti basta usare il valore di default definito per quella colonna.

IF (@prmSomeValue IS NULL)
   INSERT INTO MyTable (fieldA,FieldB,FieldC)  
      SELECT A,B,C 
      FROM MyOtherTable
ELSE
   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,@prmSomeValue 
      FROM MyOtherTable

Questo funziona, ma viola il principio DRY. Sto cercando di trovare un modo per fare questo con una sola istruzione di inserimento. Qualcosa sulla falsariga di quanto segue pseudocodice.

   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,ISNULL(@prmSomeValue,DEFAULT)
      FROM MyOtherTable

Qualcuno ha qualche idea?

Aggiornamento - Ancora una torsione
Il vincolo predefinito non è un valore letterale, ma una funzione come mostrato di seguito.

...DEFAULT (suser_sname()) FOR [FieldD]

Aggiorna
Ho finalmente punted e scelto il minore dei mali e appena copiato la funzione valore predefinito nella mia domanda invece di cadere attraverso il predefinito configurato per la colonna. Non mi piace, ma ottiene il lavoro fatto con meno ripetizioni nella mia interrogazione.

   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,ISNULL(@prmSomeValue,suser_sname())
      FROM MyOtherTable
È stato utile?

Soluzione

Dal momento che in sostanza questo è quello che SQL Server sta facendo, si potrebbe fare qualcosa di simile per almeno evitare due dichiarazioni quasi identiche (pseudo-codice):

INSERT (columnA,B,C) ... ;

IF @prmSomeValue IS NOT NULL
    UPDATE ... ;

Non credo ci sia un modo per COALESCE con il valore predefinito.

Altri suggerimenti

direi il metodo va bene. Un semplice controllo seguito da un inserto. Se siete preoccupati per SECCO, incapsulare la chiamata in modo da essere chiamato più volte.

Direi che gli inserti / aggiornamenti su un db può essere costoso in alcune tabelle (dipende dal obiettivo di progettazione), quindi se si deve scrivere codice aggiuntivo per gestire questo scenario, allora non vedo alcun problema con il compromesso.

Questo potrebbe il lavoro, dipende se si intende il valore di default definito in un vincolo di default, o nel codice? Se "vincolo" fallisce, se "codice" funziona. Modifica : si vincolo media. doh!

SELECT A,B,C,@prmSomeValue
      FROM MyOtherTable
      WHERE @prmSomeValue IS NOT NULL
UNION ALL
SELECT A,B,C,DEFAULT
      FROM MyOtherTable
      WHERE @prmSomeValue IS NULL

In qualunque modo si vuole farlo, specificando una colonna nella clausola INSERT richiede un valore.

Quindi la tua prima soluzione è quello che avete fare ...

Qualcosa di simile a questo lavoro potrebbe (tho non molto carina):

INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
SELECT A,B,C,
    case when @prmSomeValue is null 
then
        (SELECT text FROM syscomments WHERE id IN (SELECT cdefault FROM syscolumns
            WHERE id = object_id('MyTable') AND cdefault > 0))
    else @prmSomeValue
    end
FROM MyOtherTable
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top