문제

마지막으로 업데이트되거나 삽입 된 시간의 시간의 경우 데이터베이스 테이블이 있다고 가정합니다. 바람직한 것 :

  1. 트리거 업데이트 필드가 있어야합니다.
  2. 삽입/업데이트를 수행하는 프로그램이 필드를 설정하도록하십시오.

첫 번째 옵션은 내가 그것을하기 위해 다시 컴파일 할 필요조차 없기 때문에 가장 쉬운 것 같습니다. 그 외에는 다른 사람보다 한 가지 이유를 생각하는 데 어려움을 겪고 있습니다. 제안이 있습니까?

도움이 되었습니까?

해결책

데이터베이스가 필드를 유지하기 때문에 첫 번째 옵션은 더 강력 할 수 있습니다. 이것은 트리거 사용의 가능한 오버 헤드와 함께 제공됩니다.

앞으로 다른 앱이 자체 인터페이스를 통해이 테이블에 다른 앱을 작성할 수 있다면 트리거를 사용하여 다른 곳에서 해당 논리를 반복하지 않을 것입니다.

앱이 거의 없거나 다른 앱이 동일한 Datalayer를 통해 데이터베이스에 액세스하는 경우 트리거가 데이터 층 (SQL, ORM, 저장된 Procs 등)에 직접 논리를 유도하고 직접 넣을 수있는 악몽을 피할 수 있습니다. ).

물론 시간 소스 (앱, 사용자의 PC, SQL 서버)가 정확한지 확인해야합니다.


내가 트리거를 좋아하지 않는 이유에 관해 :

아마도 나는 그들을 악몽이라고 부르면서 발진이었다. 다른 모든 것들과 마찬가지로, 그들은 적당히 적절합니다. 이와 같은 매우 간단한 일에 사용한다면 탑승 할 수 있습니다.

트리거 코드가 복잡해지고 비싸지 않아 트리거가 많은 문제를 일으키기 시작합니다. 실행중인 모든 인서트/업데이트/삭제 쿼리에 숨겨진 세금입니다 (트리거 유형에 따라 다름). 그 세금이 허용되면 직무에 적합한 도구가 될 수 있습니다.

다른 팁

당신은 언급하지 않았습니다 3. 저장된 절차를 사용하여 테이블을 업데이트하십시오. 절차는 타임 스탬프를 원하는대로 설정할 수 있습니다.

아마도 그것은 당신에게는 실현 가능하지 않지만, 나는 그것이 언급되지 않았습니다.

누군가가 앱 외에 무언가를 사용하여 테이블을 업데이트하는 경우를 대비하여 Trigger라고 말합니다. 아마도 LastupdatedBy를 사용하고 suser_sname ()을 사용하고 싶을 것입니다.

내가 신뢰하는 트리거에서 DBMS를 사용하는 한, 나는 항상 트리거 옵션을 가지고 갈 것입니다. 그것은 DBM이 가능한 많은 것들을 처리 할 수있게 해줍니다. 이는 일반적으로 좋은 것입니다.

모든 상황에서 타임 스탬프 열에 올바른 값이 있는지 확인하십시오. 오버 헤드는 무시할 수 있습니다.

트리거에 반대하는 유일한 것은 이식성입니다. 그것이 문제가되지 않는다면, 나는 어떤 방향으로 가야하는지 의문이 있다고 생각하지 않습니다.

나는 모든 것에 대한 저장 절차의 지지자입니다. 업데이트 Proc에는 열에 대한 getDate ()가 포함될 수 있습니다.

그리고 나는 이런 종류의 업데이트에 대한 트리거를 좋아하지 않습니다. 트리거의 가시성 부족은 혼란을 유발하는 경향이 있습니다.

이것은 나에게 비즈니스 논리처럼 들립니다 ... 나는 이것을 코드에 넣는 데 더 배치 될 것입니다. 데이터베이스가 데이터 저장을 관리하도록하십시오.

방아쇠는 축복과 저주입니다.

축복 : 백엔드 시스템 지식이나 변경없이 모든 종류의 사용자 정의 제약 조건 검사 및 데이터 관리를 가능하게하는 데 사용할 수 있습니다.

저주 : 등 뒤에서 무슨 일이 일어나고 있는지 모릅니다. 추가 물체에 의한 동시성 문제/교착 상태는 원래 예상되지 않은 거래로 가져옵니다. 세션 환경 변경, 신뢰할 수없는 행 계산을 포함한 팬텀 동작. 조건의 과도한 트리거링 .. additional 핫스팟/성능 처벌.

이 질문에 대한 답변 (업데이트 날짜는 암시 적으로 (트리거) 또는 명시 적으로 (코드)) 컨텍스트에 크게 가중치를 부여합니다. 예를 들어, 마지막 변경 날짜를 정보 필드로 사용하는 경우 '사용자'가 실제로 행을 단순히 변경하는 경우에만 변경할 수 있습니다. .

변경 동기화를 위해 트리거를 사용하고 있거나 트리거를 실행하는 코드를 제어 할 수없는 경우 훨씬 더 의미가 있습니다.

트리거에 대한 나의 조언은 그것을 조심스럽게 사용합니다. 대부분의 시스템을 사용하면 작동 및 필드가 변경된 필터를 필터링 할 수 있습니다. 트리거 후 '이전'vs '를 올바르게 사용하면 상당한 성능에 영향을 줄 수 있습니다.

마지막으로 일부 시스템은 여러 변경 사항 (트랜잭션 내에서 영향을받는 다중 행)에서 단일 트리거를 실행할 수 있습니다. 코드는 여러 행으로 대량 업데이트로 적용 할 수 있도록 준비해야합니다.

일반적으로 데이터베이스 측면에서 말하지만 응용 프로그램에 따라 다릅니다. LINQ-to-SQL을 사용하는 경우 필드를 타임 스탬프로 설정하고 동시성을 위해 타임 스탬프 필드를 사용하도록 할 수 있습니다. 자동으로 처리하므로 코드를 반복 해야하는 것은 비 이벤트입니다.

당신이 당신의 dal을 직접 작성한다면, 나는 사용자 인터페이스를 훨씬 더 유연하게 만들기 때문에 데이터베이스 측면에서 이것을 처리 할 가능성이 더 높습니다. "액세스와 테이블이 잠겨 있습니다 - 당신은 테이블에 직접 글을 쓰면 광대가 와서 저장된 절차를 우회하는 것을 원하지 않습니다 ... 향후 애플리케이션이 액세스하는 데 사용해야하는 독립형 구성 요소를 만들 계획이 아니라면 데이터베이스 (이 경우 DAL)로 직접 코딩 할 수 있습니다. 물론 데이터베이스에 액세스하는 모든 사람이 DAL 구성 요소를 통해 그렇게하고 있음을 보장 할 수있는 경우에만이 작업을 수행해야합니다.

데이터베이스에 "공개"액세스가 테이블에 삽입 할 수 있도록 "공개"액세스를 허용하려면 누구나 테이블에 단일 필드를 삽입/업데이트 할 수 있고 업데이트 된 필드가 업데이트 될 수 없기 때문에 트리거와 함께 이동해야합니다. .

데이터베이스, 즉 트리거, 저장 프로 시저 등의 날짜가 유지 될 것입니다. 대부분의 데이터베이스 중심 애플리케이션에서 사용자 앱이 비즈니스 사용자가 데이터를 얻는 유일한 수단이되지 않을 것입니다. 보고 도구, 추출물, 사용자 SQL 등이 있습니다. DBA에서 수행 한 업데이트 및 수정 사항도 응용 프로그램이 날짜를 제공하지 않을 것입니다.

그러나 솔직히 제가 응용 프로그램에서하지 않는 #1 이유는 클라이언트 시스템의 날짜/시간을 제어 할 수 없기 때문입니다. 그들은 재판 라이센스에서 더 많은 며칠을 얻기 위해 그것을 롤백하거나 프로그램에 나쁜 일을하고 싶을 수도 있습니다.

데이터베이스가 필드에서 기본값을 지원하는 경우 트리거 없이이 작업을 수행 할 수 있습니다. 예를 들어, SQL Server 2005에는 다음과 같은 필드가있는 테이블이 있습니다.

create table dbo.Repository
   (
    ...
   last_updated     datetime default getdate(),
    ...
   )

그런 다음 삽입 코드는 해당 필드 삽입 필드 목록에서 해당 필드를 남깁니다.

첫 번째 삽입에만 효과가 있다는 것을 잊었습니다. 날짜 필드를 업데이트하고 내 히스토리 테이블에 업데이트 된 레코드의 사본을 넣기 위해 업데이트 트리거도 있습니다. 내 코드에서 ...

드디어:

create trigger dbo.Repository_Upd on dbo.Repository instead of update
as
--**************************************************************************
--   Trigger: Repository_Upd
--    Author: Ron Savage
--      Date: 09/28/2008
--
-- Description:
-- This trigger sets the last_updated and updated_by fields before the update
-- and puts a copy of the updated row into the Repository_History table.
--
-- Modification History:
-- Date        Init  Comment
-- 10/22/2008  RS    Blocked .prm files from updating the history as they
--                   get updated every time the cfg file is run.
-- 10/21/2008  RS    Updated the insert into the history table to use the
--                   d.last_updated field from the Repository table rather
--                   than getdate() to avoid micro second differences.
-- 09/28/2008  RS    Created.
--**************************************************************************
begin
   --***********************************************************************
   -- Update the record but fill in the updated_by, updated_system and
   -- last_updated date with current information.
   --***********************************************************************
   update cr set
      cr.filename           = i.filename,
      cr.created_by         = i.created_by,
      cr.created_system     = i.created_system,
      cr.create_date        = i.create_date,
      cr.updated_by         = user,
      cr.updated_system     = host_name(),
      cr.last_updated       = getdate(),
      cr.content            = i.content
   from
      Repository cr

      JOIN Inserted i
         on (i.config_id = cr.config_id);


   --***********************************************************************
   -- Put a copy in the history table
   --***********************************************************************
   declare @extention varchar(3);
   select @extention = lower(right(filename,3)) from Inserted;

   if (@extention <> 'prm')
      begin
      Insert into Repository_History
         select
            i.config_id,
            i.filename,
            i.created_by,
            i.created_system,
            i.create_date,
            user           as updated_by,
            host_name()    as updated_system,
            d.last_updated,
            d.content
         from
            Inserted i

            JOIN Repository d
               on (d.config_id = i.config_id);
      end
end

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top