복붙노트

[SQL] 두 번째 필드를 자동 증가로 두 필드의 SQL 서버 고유 복합 키

SQL

두 번째 필드를 자동 증가로 두 필드의 SQL 서버 고유 복합 키

나는 복합 기본 키 등이 갖고 싶어, 다음과 같은 문제가있다 :

PRIMARY KEY (`base`, `id`);

있는 나는 자동 증가 동일한 기본에 대해 이전 ID를 기반으로 아이디 기반을 삽입 할 때

예:

base   id
A      1
A      2
B      1
C      1

내가 말할 수있는 방법이 있나요 : INSERT INTO 테이블 (기본) VALUES ( 'A') 즉 'A'기본에 다음 ID이기 때문에 ID 3 새 레코드를 삽입하려면?

그 결과 표해야한다 :

base   id
A      1
A      2
B      1
C      1
A      3

가능 프로그래밍 할 경우는 경주 조건이 발생할 수 정확히 이후 DB에 그것을 할 것입니다.

편집하다

베이스는 현재 ID가 숫자 송장 대표, 회사를 나타냅니다. 각 회사에 대해 자동 증가 송장 번호가 있어야하지만 두 회사가 같은 번호로 송장이 경우가있을 수 있습니다. 사용자는 필터를 정렬하고 그 송장 번호로 검색 할 수 있어야 회사와 기록.

해결법

  1. ==============================

    1.누군가가 비슷한 질문을 게시 한 이후, 나는 이것을 숙고했습니다. 첫 번째 문제는 데시벨은 "파티션"시퀀스를 (다른 키에 따라 기억 그 / 다시 시작 것) 제공하지 않는다는 것입니다. 두 번째는 제공되는 SEQUENCE 개체가 빠른 액세스 주위를 대상으로하고 있으며, (즉, 당신이 격차를 얻을 것이다) 다시 롤백 할 수 없다는 것입니다. 사용하여이 본질적으로이 규칙 내장 유틸리티 ... 우리는 우리 자신의 롤해야 의미합니다.

    누군가가 비슷한 질문을 게시 한 이후, 나는 이것을 숙고했습니다. 첫 번째 문제는 데시벨은 "파티션"시퀀스를 (다른 키에 따라 기억 그 / 다시 시작 것) 제공하지 않는다는 것입니다. 두 번째는 제공되는 SEQUENCE 개체가 빠른 액세스 주위를 대상으로하고 있으며, (즉, 당신이 격차를 얻을 것이다) 다시 롤백 할 수 없다는 것입니다. 사용하여이 본질적으로이 규칙 내장 유틸리티 ... 우리는 우리 자신의 롤해야 의미합니다.

    우리가 필요 해요 첫 번째 것은 우리의 일련 번호를 저장하는 테이블입니다. 이것은 매우 간단 할 수있다 :

    CREATE TABLE Invoice_Sequence (base CHAR(1) PRIMARY KEY CLUSTERED,
                                   invoiceNumber INTEGER);
    

    실제로 기본 열이 어떤 테이블 / 아이디 정의하는 비즈니스 (들)에 대한 외래 키 참조해야한다 / 단체 당신은 인보이스를 발행하고 있습니다. 이 표에서, 당신은 항목이 발행 엔티티마다 고유해야합니다.

    다음으로, 당신은 키 (기본)를 연속 촬영할 (INVOICENUMBER)의 다음 수를 뱉어 proc 디렉토리에 저장을합니다. 다음과 같이 필요한 키의 세트 (즉, 일부 송장 번호는 년 또는 그 문제의 전체 날짜 있어야합니다)에 따라 다르지만,이 상황의 기본 형식은 다음과 같습니다

    CREATE PROCEDURE Next_Invoice_Number @baseKey CHAR(1), 
                                         @invoiceNumber INTEGER OUTPUT 
    AS MERGE INTO Invoice_Sequence Stored
                  USING (VALUES (@baseKey)) Incoming(base)
                     ON Incoming.base = Stored.base
       WHEN MATCHED THEN UPDATE SET Stored.invoiceNumber = Stored.invoiceNumber + 1
       WHEN NOT MATCHED BY TARGET THEN INSERT (base) VALUES(@baseKey)
       OUTPUT INSERTED.invoiceNumber ;;
    

    그 참고 :

    맞아요, 당신은 여전히 ​​송장 번호를 발행 할 때마다 비즈니스 차단 얻을 것이다. 송장 번호는 순차적이어야합니다 당신은 빈틈이없는,이 문제를 피할 수 - 행이 실제로 커밋 될 때까지, 그것은 송장 번호가 발급되지 않았을 것을 의미 롤백 할 수 있습니다.

    지금, 당신은 항목에 대한 프로 시저를 호출 트리거에서 그것을 마무리하는 것을 기억하고 싶지 않기 때문에 :

    CREATE TRIGGER Populate_Invoice_Number ON Invoice INSTEAD OF INSERT
    AS 
      DECLARE @invoiceNumber INTEGER
      BEGIN
        EXEC Next_Invoice_Number Inserted.base, @invoiceNumber OUTPUT
        INSERT INTO Invoice (base, invoiceNumber) 
                    VALUES (Inserted.base, @invoiceNumber)
      END
    

    (- 당신이 그들을 채우기 위해 필요합니다 분명히, 당신은 자동으로 입력해야 다른 사람을 포함, 더 많은 열이) ... 어떤을 당신은 단순히 말해서 사용할 수 있습니다 :

    INSERT INTO Invoice (base) VALUES('A');
    

    그래서 우리는 무엇을 한거야? 대부분,이 모든 작업은 트랜잭션에 의해 잠긴 행의 수를 축소에 대해이었다. 이 INSERT이 커밋 될 때까지, 두 행이 잠겨있다 :

    특정 기준에 대한 다른 모든 행이 무료입니다 - 그들은 업데이트 또는 의지에서 조회 할 수 있습니다 (이러한 종류의 시스템에서 정보를 삭제 회계사 긴장하게하는 경향이있다). 당신은 아마 쿼리가 정상적으로 보류 송장을 포함 할 때 발생해야하는지 결정해야합니다 ...

  2. ==============================

    2.당신은 삽입 전에 트리거를 사용하여 "A"는이 경우에 "기본"필터를 최대 (ID)를 고려하여 다음 값을 할당 할 수 있습니다. 즉 2로와 최대 (ID)에 의해 증가를 한 것보다 당신에게 최대 (ID) 값을 제공합니다. 이제 "ID"필드에 새 값을 누릅니다. 전에 삽입. 내가 당신을 도울 수있다 생각

    당신은 삽입 전에 트리거를 사용하여 "A"는이 경우에 "기본"필터를 최대 (ID)를 고려하여 다음 값을 할당 할 수 있습니다. 즉 2로와 최대 (ID)에 의해 증가를 한 것보다 당신에게 최대 (ID) 값을 제공합니다. 이제 "ID"필드에 새 값을 누릅니다. 전에 삽입. 내가 당신을 도울 수있다 생각

    MSSQL 트리거 : http://msdn.microsoft.com/en-in/library/ms189799.aspx

  3. ==============================

    3.

    CREATE TABLE MyTable
       ( base CHAR(1),
         id   INT
       )
    GO
    
    CREATE TRIGGER dbo.tr_Populate_ID
    ON dbo.MyTable 
    INSTEAD OF INSERT
    AS
    BEGIN
      SET NOCOUNT ON;
    
    INSERT INTO MyTable (base,id)
    SELECT i.base, ISNULL(MAX(mt.id),0) +1 AS NextValue
      FROM inserted i left join MyTable mt
      on i.base = mt.base
      GROUP BY i.base
    
    END
    

    다음 문을 여러 번 실행하고 해당 그룹에서 사용할 수있는 다음 값이 ID에 할당됩니다 볼 수 있습니다.

    INSERT INTO MyTable VALUES
    ('A'),
    ('B'),
    ('C')
    GO
    
    SELECT * FROM MyTable
    GO
    
  4. from https://stackoverflow.com/questions/24184749/sql-server-unique-composite-key-of-two-field-with-second-field-auto-increment by cc-by-sa and MIT license