Existe uma maneira de usar condicionalmente valores de coluna padrão em uma instrução Insert .. Selecione?
-
23-09-2019 - |
Pergunta
Eu tenho código semelhante ao seguinte em um procedimento armazenado que insere uma linha em uma tabela, gostaria de definir a última coluna (Fieldd) como @PRMSomeValue, a menos que seja nulo; caso contrário, basta usar o valor padrão definido para isso coluna.
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
Isso funciona, mas viola o princípio seco. Estou tentando encontrar uma maneira de fazer isso com uma única declaração de inserção. Algo na linha do seguinte pseudocódigo.
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,ISNULL(@prmSomeValue,DEFAULT)
FROM MyOtherTable
Alguém tem alguma ideia?
Atualização - mais uma torção
A restrição padrão não é um valor literal, mas uma função como mostrado abaixo.
...DEFAULT (suser_sname()) FOR [FieldD]
Atualizar
Finalmente, puntei e escolhi o menor dos males e apenas copiei a função de valor padrão na minha consulta em vez de cair no padrão configurado para a coluna. Eu não amo isso, mas faz o trabalho com menos repetição em minha consulta.
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,ISNULL(@prmSomeValue,suser_sname())
FROM MyOtherTable
Solução
Como essencialmente é isso que o SQL Server está fazendo, você pode fazer algo assim para evitar pelo menos duas declarações quase idênticas (pseudo-código):
INSERT (columnA,B,C) ... ;
IF @prmSomeValue IS NOT NULL
UPDATE ... ;
Eu não acho que exista uma maneira de coalescer com o valor padrão.
Outras dicas
Eu diria que seu método está bem. Uma verificação simples seguida de uma inserção. Se você está preocupado com seco, encapsule a chamada para que ela seja chamada repetidamente.
Eu diria que inserções/atualizações em um banco de dados podem ser caras em algumas tabelas (depende da meta de design); portanto, se você precisar escrever um código extra para lidar com esse cenário, não vejo nenhum problema com a troca.
este poderia Trabalho, depende se você quer dizer o valor padrão definido em uma restrição padrão ou no código? Se "restrição" falhar, se "código", ele funciona. Editar: você quer dizer restrição. 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
Qual é a maneira que você deseja fazer isso, especificando uma coluna na cláusula de inserção requer um valor.
Então, sua primeira solução é o que você faz ...
Algo assim pode funcionar (não é muito bonito):
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