2009-04-02 12 views
13

Estoy trabajando con una antigua base de datos SQL 2000 y no tengo mucha experiencia SQL en mi haber. Cuando se agrega una nueva fila a una de mis tablas, necesito asignar un valor de tiempo predeterminado basado en una columna para la categoría de trabajo.Cómo establecer un valor predeterminado para una columna en SQL basado en otra columna

Por ejemplo, la categoría de trabajo Un asignaría un valor de tiempo de 1 hora, la categoría B sería de 2 horas, etc ...

Sólo debe establecer el valor si el usuario no introduce manualmente el tiempo que se los llevó a hacer el trabajo. Pensé en hacer esto con una restricción predeterminada, pero no creo que funcione si el valor predeterminado tiene una dependencia.

¿Cuál sería la mejor manera de hacerlo?

Respuesta

9

Utilizaría un disparador en Insertar.

Simplemente verifique si se ha asignado un valor, y si no, vaya a buscar el correcto y úselo.

+0

Cómo sabe si la creación de tales desencadenantes afecta a la velocidad de inserción de base de datos de alguna manera? – ziddarth

+0

Eso depende de la lógica y/o consulta que tenga en el desencadenador. Sin embargo, espero que no haya un impacto discernible por el usuario. Sin embargo, si no está usando SQL 2000 (como se indica en el OP), consideraría usar una función de escalador definida por el usuario en el atributo DEFAULT en lugar de un desencadenador. –

1

Sí, gatillo.

Naturalmente, en lugar de codificar los valores predeterminados, los buscará desde una tabla.

Ampliando esto, la nueva tabla a continuación, se convierte en la tabla work_category (id, nombre, default_hours), y tabla original mantiene una clave externa a ella, transformando FOM (id, work_category, horas) a (id, work_category_id , horas).

0

Generalmente me alejo de los factores desencadenantes. Casi todos los dbms tienen algún tipo de soporte para constraints.

Me resultan más fáciles de entender, depurar y mantener.

+0

Si, como entiendo la solicitud, solo desea modificar este valor al insertar, use una restricción. Si desea cambiarlo en cualquier fila, use un disparador. – Karl

+0

[Restricciones de PostgreSQL] (http://www.postgresql.org/docs/9.3/static/ddl-constraints.html) parece que solo generan errores, no establece un valor predeterminado. – ma11hew28

2

Asegúrese de escribir el disparador para que pueda manejar inserciones de varias hileras. No procese una fila a la vez en un desencadenador o suponga que solo habrá una fila en la tabla insertada.

+0

esto es un comentario, no una respuesta –

1

Así, por ejemplo, en una tabla TAG (donde las etiquetas se aplican a las publicaciones) si desea contar una etiqueta como otra ... pero de forma predeterminada contar nuevas etiquetas como ellas, tendría un disparador como este:

CREATE TRIGGER [dbo].[TR_Tag_Insert] 
    ON [dbo].[Tag] 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    UPDATE dbo.Tag 
    SET [CountAs] = I.[ID] 
    FROM INSERTED AS I 
    WHERE I.[CountAs] IS NULL 
    AND dbo.Tag.ID = I.ID 
END 
6

utilizar un disparador según lo sugerido por Stephen Wrighton:

CREATE TRIGGER [myTable_TriggerName] ON dbo.myTable FOR INSERT   
AS 
SET NOCOUNT ON 
UPDATE myTable 
SET 
    timeValue = '2 hours' -- assuming string values 
where ID in (
    select ID 
    from INSERTED 
    where 
     timeValue = '' 
     AND workCategory = 'A' 
) 
2

Si lo que busca es definir una definición de columna basada en otra columna que puede hacer algo como esto:

create table testable 
(
    c1 int, 
    c2 datetime default getdate(), 
    c3 as year(c2) 
); 

insert into testable (c1) select 1 

select * from testable; 

Su conjunto de resultados debe tener este aspecto:

c1 | c2      | c3 
1 | 2013-04-03 17:18:43.897 | 2013 

Como se puede ver AS (en la definición de columna) hace el truco;) Espero que ayudó.

+0

'AS' no parece ser válido en PostgreSQL. – ma11hew28

+0

La pregunta fue para SQL Server 2000, no mencionó nada acerca de PostgreSQL. Lo siento. – Sergiu

+0

Funcionó como un encanto para mí. ¡Gracias! – jcsilva87

0

puedo pensar en dos formas:

  1. desencadena
  2. valor predeterminado o vinculante (esto debería funcionar con una dependencia)

disparadores parecen bien explicado aquí, así que no lo haré elaborar. Pero, en general, trato de evitar los desencadenantes para este tipo de cosas, ya que son más apropiados para otras tareas

"valor predeterminado o enlace" se puede lograr mediante la creación de una función, p.

CREATE FUNCTION [dbo].[ComponentContractor_SortOrder]() 
RETURNS float 
AS 
BEGIN 
RETURN (SELECT MAX(SortOrder) + 5 FROM [dbo].[tblTender_ComponentContractor]) 
END 

Y a continuación, establecer el "valor por defecto o vinculante" para esa columna a ([dbo] .ComponentContractor_SortOrder)

Cuestiones relacionadas