¿Hay una manera de utilizar condicionalmente valores de columna por defecto en un comunicado INSERT..SELECT?

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

Pregunta

Tengo un código similar al siguiente en un procedimiento almacenado que inserta una fila en una tabla, me gustaría establecer la última columna (FieldD) a @prmSomeValue a menos que sea nula, de lo contrario sólo tiene que utilizar el valor por defecto definido para esa columna.

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

Esto funciona, pero viola el principio DRY. Estoy tratando de encontrar la manera de hacer esto con una sola instrucción de inserción. Algo a lo largo de las líneas de la siguiente pseudocódigo.

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

Alguien tiene alguna idea?

Actualizar - Una vuelta de tuerca más
La restricción predeterminada no es un valor literal, sino una función tal como se muestra a continuación.

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

Actualizar
Finalmente despejaron y elegimos el menor de los males y acaba de copiar la función de valor por defecto en mi consulta en lugar de caer hasta el valor estándar configurado para la columna. No me encanta, pero hace el trabajo con menos repetición en mi consulta.

   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,ISNULL(@prmSomeValue,suser_sname())
      FROM MyOtherTable
¿Fue útil?

Solución

Dado que en esencia esto es lo que SQL Server está haciendo, usted podría hacer algo como esto para evitar por lo menos dos declaraciones casi idénticas (pseudo-código):

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

IF @prmSomeValue IS NOT NULL
    UPDATE ... ;

No creo que hay un camino a fundirse con el valor predeterminado.

Otros consejos

Yo diría que su método está muy bien. Una sencilla comprobación seguida por una pieza de inserción. Si usted está preocupado por SECO, encapsular la llamada para que se llama repetidamente.

Yo diría que las inserciones / actualizaciones en una base de datos puede ser costoso en algunas mesas (depende del objetivo de diseño) por lo que si usted tiene que escribir código adicional para manejar este escenario luego veo ningún problema con la solución de compromiso.

Este fuerza trabajo, depende de si usted quiere decir el valor predeterminado definido en una restricción predeterminada, o en el código? Si "restricción" se produce un error, si el "código" funciona. Editar : que la restricción 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

Sea cual sea la forma en que desea hacerlo, especificando una columna en la cláusula INSERT es necesario un valor.

Así que su primera solución es hacer lo que has ...

Algo así como este trabajo podría (aunque no muy bonita):

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top