2009-02-17 12 views
5

¿Existe alguna manera especial de declarar una columna DateCreated en una tabla de servidor MS Sql para que la complete automáticamente con la marca de tiempo apropiada cuando se cree?Columna DateCreated en el servidor Sql?

O ... ¿Tengo que proporcionarle la fecha y hora cuando realizo la consulta, de forma manual?

Respuesta

10

Puede establecer el valor predeterminado de la columna de "getdate()"

+1

Tenga en cuenta que los usuarios pueden omitir esto ya que el valor predeterminado no se tiene en cuenta cuando inserta un valor real. Y también puede ser actualizado por los usuarios también. Probablemente sea lo suficientemente bueno si puedes controlar qué SQL se ejecuta (y no puedes :-) pero no es seguro. – paxdiablo

+0

Eso es realmente una buena cosa, porque si un usuario tiene una fecha específica que necesita poner allí, probablemente debería permitirse a menos que tenga reglas que rijan lo contrario. – James

+0

Respetuosamente no estoy de acuerdo, @James. ¿No has oído hablar de Sarbanes-Oxley? :-) Si tiene una columna DateCreated, debe establecerse en la fecha en que se creó la fila. Si desea una columna modificable por el usuario, debe llamarse DateCreatedForPurposesOfFraud o algo similar. – paxdiablo

15

Los valores por defecto adolecen de dos inconvenientes importantes.

  • si la instrucción de inserción especifica un valor para la columna, no se utiliza el valor predeterminado.
  • la columna se puede actualizar en cualquier momento.

Esto significa que no puede estar seguro de que los valores no se hayan modificado fuera de su control.

Si desea integridad de datos verdadera (de modo que esté seguro de que la fecha de la fila es la fecha de creación), debe usar activadores.

Un desencadenador de inserción para establecer la columna a la fecha actual y un activador de actualización para evitar cambios en esa columna (o, más precisamente, establecerlo en su valor actual) son la forma de implementar una columna DateCreated.

Un inserto y activador de actualización para establecer la columna a la fecha actual es la forma de implementar una columna DateModified.

(edición de usuario Gabriel - aquí está mi intento de implementar esto como descrito - no estoy seguro al 100% de que es correcta pero estoy esperando el PO lo revisa ...):

CREATE TRIGGER [dbo].[tr_Affiliate_IU] 
    ON [dbo].[Affiliate] 
    AFTER INSERT, UPDATE 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Get the current date. 
    DECLARE @getDate DATETIME = GETDATE() 

    -- Set the initial values of date_created and date_modified. 
    UPDATE 
     dbo.Affiliate 
    SET 
     date_created = @getDate 
    FROM 
     dbo.Affiliate A 
     INNER JOIN INSERTED I ON A.id = I.id 
     LEFT OUTER JOIN DELETED D ON I.id = D.id 
    WHERE 
     D.id IS NULL 

    -- Ensure the value of date_created does never changes. 
    -- Update the value of date_modified to the current date. 
    UPDATE 
     dbo.Affiliate 
    SET 
     date_created = D.date_created 
     ,date_modified = @getDate 
    FROM 
     dbo.Affiliate A 
     INNER JOIN INSERTED I ON A.id = I.id 
     INNER JOIN DELETED D ON I.id = D.id 
END 
+0

Si controla el entorno y la aplicación, entonces controla el acceso al nivel de datos. Las dos preocupaciones se vuelven irrelevantes. –

+0

Realmente, ¿no crees que alguien pueda simplemente conectarse al DBMS con un controlador JDBC? Y una de las principales ventajas de n-tier es hacer que cada nivel sea responsable de su propia integridad. NUNCA asume que el DB está protegido por la aplicación cuando puede protegerse. Eso es pedir problemas. – paxdiablo

+0

@Pax: No, yo no. Una conexión ad-hoc no se puede conectar a un entorno adecuadamente protegido. La seguridad no es la única responsabilidad del DMBS (sí proporciona un punto de partida), ya que debe ser una estrategia de plataforma/cooperativa. –

0

Ciertamente es.

Aquí hay un ejemplo en acción para usted.

Create table #TableName 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(), 
    SomeDate VARCHAR(100) 
) 

INSERT INTO #TableName (SomeDate) 
SELECT 'Some data one' UNION ALL SELECT 'some data two' 

SELECT * FROM #TableName 

DROP TABLE #TableName 
+0

¿Y qué sucede cuando un empleado descontento aparece con "ACTUALIZACIÓN #TABLE SET CREATEDDATE = GETDATE()"? Bang, ahí va toda tu información valiosa sobre cuándo se crearon las filas. – paxdiablo

+2

@Pax: No sucedería en mi territorio, sin embargo, en el improbable caso de que lo hiciera, simplemente implementaría nuestros procedimientos de DR y recuperaría los datos. Parece que necesita ver su estrategia de seguridad y la moral del personal :-) –

+1

"Moral", pero tal vez su moral también debe examinarse :-) De todos modos, la prevención siempre es mejor que la recuperación. Es la diferencia entre el tiempo de inactividad y el tiempo de inactividad (ninguno es mejor que cualquier cantidad). Probablemente sea más el entorno en el que trabajo, DB2 en System z, siempre estamos paranoicos. – paxdiablo

2

Nos tiene defecto en CreatedDate y no hacen cumplir con disparadores

Hay momentos en que queremos establecer explícitamente la fecha - por ejemplo, si importamos datos de alguna otra fuente.

Hay un riesgo de que Bug aplicación podría meterse con el CreateDate, o un DBA contrariedad para el caso (que no tenemos no los administradores de bases de conexión directa a nuestra DB)

supongo que se podría establecer Columna permisos de nivel en CreateDate.

Un medio camino puede ser que un INSERT TRIGGER cree una fila en una tabla 1: 1, de modo que esa columna quede fuera de la tabla principal. La segunda tabla podría tener permisos SELECT, donde la tabla principal tiene permisos de ACTUALIZACIÓN, y por lo tanto no necesita un activador de ACTUALIZACIÓN para evitar cambios en CreateDate, lo que eliminaría algo de "peso" al actualizar las filas normalmente.

supongo que coul tiene un UPDATE/DELETE gatillo de la segunda tabla para evitar el cambio (que nunca sería ejecutado en circunstancias normales, por lo que "ligero")

poco de dolor para tener la mesa extra, aunque ... podría tener una tabla para todos los CreateDates - TableName, PK, CreateDate.Sin embargo, la mayoría de los arquitectos de bases de datos odiarán eso ...

Cuestiones relacionadas