C'è un modo per utilizzare i valori delle colonne condizionale di default in una dichiarazione INSERT..SELECT?
-
23-09-2019 - |
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
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