복붙노트

[SQL] 어떻게 마이크로 소프트 SQL 서버의 순서를 구현하는 것이?

SQL

어떻게 마이크로 소프트 SQL 서버의 순서를 구현하는 것이?

사람이 SQL 서버의 시퀀스처럼 뭔가를 구현하는 좋은 방법이 있습니까?

때때로 당신은 단지 그들이 지옥 같은 추악한 사실 외에, GUID를 사용하지 않습니다. 어쩌면 당신이 원하는 순서는 숫자 아닌가요? 게다가, DB를 묻는 다음 행을 삽입하는 것은 무엇 수가 것은 너무 hackish 보인다.

해결법

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

    1.SQL 서버 2012는 모든 테이블과 관련이없는 순차적 인 숫자 값을 생성 할 수 SEQUENCE 객체를 발표했다.

    SQL 서버 2012는 모든 테이블과 관련이없는 순차적 인 숫자 값을 생성 할 수 SEQUENCE 객체를 발표했다.

    을 만들기 쉽다 :

    CREATE SEQUENCE Schema.SequenceName
    AS int
    INCREMENT BY 1 ;
    

    삽입하기 전에를 사용하는 예 :

    DECLARE @NextID int ;
    SET @NextID = NEXT VALUE FOR Schema.SequenceName;
    -- Some work happens
    INSERT Schema.Orders (OrderID, Name, Qty)
      VALUES (@NextID, 'Rim', 2) ;
    

    시퀀스를 사용하는 방법에 대해 자세히 살펴 보도록 내 블로그를 참조하십시오 :

    http://sqljunkieshare.com/2011/12/11/sequences-in-sql-server-2012-implementingmanaging-performance/

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

    2.sqljunkieshare가 제대로 SQL 서버 2012에서 시작 말했듯이 내장 된 시퀀스 기능.

    sqljunkieshare가 제대로 SQL 서버 2012에서 시작 말했듯이 내장 된 시퀀스 기능.

    원래 질문은 명확하지 않지만, 나는 순서에 대한 요구 사항이 있다고 가정합니다 :

    나는 원래의 질문에 문을 언급하고 싶습니다 :

    글쎄, 우리는 여기에 대해 할 수있는 일은 거의 없다. DB를은 일련 번호의 공급자이고 DB는 사용자가 직접 처리 할 수없는 모든 동시성 문제를 처리합니다. 나는 순서의 다음 값에 대한 DB 요청에 대안을 볼 수 없습니다. 원자 작업이 있어야한다는 원자 작업을 제공 할 수있는 유일한 DB "나에게 시퀀스의 다음 값을 제공합니다." 어떤 클라이언트 코드는 그 순서에 유일하게 작동하고 있음을 보장 할 수 있습니다.

    우리는 2008을 사용하는, 그래서 다음과 결국이 주제에 대한 몇 가지 독서 후 SEQUENCE 기능이없는 - "당신이 순서를 구현하는 것이 방법"제목의 질문에 대답합니다.

    각 시퀀스를 들어 내가 한 IDENTITY 열이있는 별도의 도우미 테이블을 만들 필요가 (같은 방식으로 별도의 시퀀스 객체를 생성 할 2012 년으로).

    CREATE TABLE [dbo].[SequenceContractNumber]
    (
        [ContractNumber] [int] IDENTITY(1,1) NOT NULL,
    
        CONSTRAINT [PK_SequenceContractNumber] PRIMARY KEY CLUSTERED ([ContractNumber] ASC)
    )
    

    당신은 가치를 시작 지정하고 그것을 증가 할 수 있습니다. 그럼 난 시퀀스의 다음 값을 반환 저장 프로 시저를 만들 수 있습니다. 프로 시저, 트랜잭션을 시작 도우미 테이블에 행 삽입, 다시 트랜잭션을 생성 된 ID 값과 롤을 기억할 것입니다. 따라서 도우미 테이블은 항상 비어 있습니다.

    CREATE PROCEDURE [dbo].[GetNewContractNumber]
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
        SET XACT_ABORT ON;
    
        DECLARE @Result int = 0;
    
        IF @@TRANCOUNT > 0
        BEGIN
            -- Procedure is called when there is an active transaction.
            -- Create a named savepoint
            -- to be able to roll back only the work done in the procedure.
            SAVE TRANSACTION ProcedureGetNewContractNumber;
        END ELSE BEGIN
            -- Procedure must start its own transaction.
            BEGIN TRANSACTION ProcedureGetNewContractNumber;
        END;
    
        INSERT INTO dbo.SequenceContractNumber DEFAULT VALUES;
    
        SET @Result = SCOPE_IDENTITY();
    
        -- Rollback to a named savepoint or named transaction
        ROLLBACK TRANSACTION ProcedureGetNewContractNumber;
    
        RETURN @Result;
    END
    

    절차에 대한 몇 가지주의.

    첫째, 하나의 ID 열이있는 테이블에 행을 삽입하는 방법을 분명 아니었다. 대답은 기본값입니다.

    그 후, 나는 그것이 다른 트랜잭션 내에서 호출 된 경우 올바르게 동작에 절차를 원했다. 중첩 된 트랜잭션이있는 경우 간단한 ROLLBACK 롤 모든 것을 백업 할 수 있습니다. 내 경우에는 내가 SAVE 트랜잭션을 사용하므로 다시 만 도우미 테이블에 INSERT 롤에 필요합니다.

    I (예를 들어, 새로운 계약을 만들고, 다른 큰 절차 내에서) 절차를 사용하는 방법입니다 :

    DECLARE @VarContractNumber int;
    EXEC @VarContractNumber = dbo.GetNewContractNumber;
    

    당신은 한 번에 하나의 시퀀스 값을 생성해야하는 경우 모든 것이 잘 작동합니다. 이 방법이 완벽하게 작동하므로 계약의 경우 각 계약은 개별적으로 작성됩니다. 나는 모든 계약은 항상 독특한 계약 번호가 있는지 확신 할 수 있습니다.

    NB : 그냥 가능한 문제를 방지합니다. 이 계약 번호는 내 계약 테이블을 가지고 대리 신원 키에 추가됩니다. 서로 게이트 키를 참조 무결성에 사용되는 내부 키입니다. 생성 된 계약 번호는 계약에 인쇄되어 인간 친화적 인 숫자입니다. 게다가, 같은 계약의 표는 계약이 될 수 있습니다 또는 영원히 제안으로 남아있을 수 모두 최종 계약 및 제안서가 포함되어 있습니다. 둘 다 제안 및 계약은이 같은 테이블에 보관됩니다 이유가 매우 유사 데이터를 보유. 제안은 단순히 하나의 행에 플래그를 변경하여 계약이 될 수 있습니다. 제안 I 번째 테이블 SequenceProposalNumber 및 제 GetNewProposalNumber 절차가있는 숫자의 분리 시퀀스를 이용하여 넘버링되어있다.

    최근에, 그러나, 나는 문제를 건너 왔어요. 차라리 하나씩보다 일괄 시퀀스 값을 생성 할 필요가 있었다.

    나는 한 번에 주어진 분기 동안 접수 된 모든 지불을 처리 할 절차가 필요합니다. 이러한 처리의 결과는 내가 트랜잭션 테이블에 기록 할 것인지 만 거래 ~ 수 있습니다. 여기 유사한 디자인을 가지고있다. 트랜잭션 테이블은 최종 사용자가 볼 수 결코 내부 IDENTITY 열이 있고이 문에 인쇄 될 것입니다 인간 친화적 인 트랜잭션 수있다. 그래서 나는 배치에 고유 한 값의 특정 번호를 생성하는 방법이 필요합니다.

    기본적으로, 나는 동일한 방법을 사용하지만, 몇 가지 특색이있다.

    첫째, 하나의 IDENTITY 열이있는 테이블에 여러 행을 삽입하는 직접적인 방법이 없습니다. MERGE를 사용하여 (AB)에 의한 해결 방법이 있지만, 나는 결국 그것을 사용하지 않았다. 나는 더미 필러 열을 추가하는 것이 더 쉽습니다 것을 결정했다. 내 순서 표는 여분의 열이 정말 중요합니까, 그래서 항상 비워 것입니다.

    도우미 테이블은 다음과 같다 :

    CREATE TABLE [dbo].[SequenceS2TransactionNumber]
    (
        [S2TransactionNumber] [int] IDENTITY(1,1) NOT NULL,
        [Filler] [int] NULL,
        CONSTRAINT [PK_SequenceS2TransactionNumber] 
        PRIMARY KEY CLUSTERED ([S2TransactionNumber] ASC)
    )
    

    절차는 다음과 같습니다 :

    -- Description: Returns a list of new unique S2 Transaction numbers of the given size
    -- The caller should create a temp table #NewS2TransactionNumbers,
    -- which would hold the result
    CREATE PROCEDURE [dbo].[GetNewS2TransactionNumbers]
        @ParamCount int -- not NULL
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
        SET XACT_ABORT ON;
    
        IF @@TRANCOUNT > 0
        BEGIN
            -- Procedure is called when there is an active transaction.
            -- Create a named savepoint
            -- to be able to roll back only the work done in the procedure.
            SAVE TRANSACTION ProcedureGetNewS2TransactionNos;
        END ELSE BEGIN
            -- Procedure must start its own transaction.
            BEGIN TRANSACTION ProcedureGetNewS2TransactionNos;
        END;
    
        DECLARE @VarNumberCount int;
        SET @VarNumberCount = 
        (
            SELECT TOP(1) dbo.Numbers.Number
            FROM dbo.Numbers
            ORDER BY dbo.Numbers.Number DESC
        );
    
        -- table variable is not affected by the ROLLBACK, so use it for temporary storage
        DECLARE @TableTransactionNumbers table
        (
            ID int NOT NULL
        );
    
        IF @VarNumberCount >= @ParamCount
        BEGIN
            -- the Numbers table is large enough to provide the given number of rows
            INSERT INTO dbo.SequenceS2TransactionNumber
            (Filler)
            OUTPUT inserted.S2TransactionNumber AS ID INTO @TableTransactionNumbers(ID)
            -- save generated unique numbers into a table variable first
            SELECT TOP(@ParamCount) dbo.Numbers.Number
            FROM dbo.Numbers
            OPTION (MAXDOP 1);
    
        END ELSE BEGIN
            -- the Numbers table is not large enough to provide the given number of rows
            -- expand the Numbers table by cross joining it with itself
            INSERT INTO dbo.SequenceS2TransactionNumber
            (Filler)
            OUTPUT inserted.S2TransactionNumber AS ID INTO @TableTransactionNumbers(ID)
            -- save generated unique numbers into a table variable first
            SELECT TOP(@ParamCount) n1.Number
            FROM dbo.Numbers AS n1 CROSS JOIN dbo.Numbers AS n2
            OPTION (MAXDOP 1);
    
        END;
    
        /*
        -- this method can be used if the SequenceS2TransactionNumber
        -- had only one identity column
        MERGE INTO dbo.SequenceS2TransactionNumber
        USING
        (
            SELECT *
            FROM dbo.Numbers
            WHERE dbo.Numbers.Number <= @ParamCount
        ) AS T
        ON 1 = 0
        WHEN NOT MATCHED THEN
        INSERT DEFAULT VALUES
        OUTPUT inserted.S2TransactionNumber
        -- return generated unique numbers directly to the caller
        ;
        */
    
        -- Rollback to a named savepoint or named transaction
        ROLLBACK TRANSACTION ProcedureGetNewS2TransactionNos;
    
        IF object_id('tempdb..#NewS2TransactionNumbers') IS NOT NULL
        BEGIN
            INSERT INTO #NewS2TransactionNumbers (ID)
            SELECT TT.ID FROM @TableTransactionNumbers AS TT;
        END
    
    END
    

    그리고 이것은이 (계산 거래 몇 가지 큰 저장 프로 시저 내에서)를 사용하는 방법입니다 :

    -- Generate a batch of new unique transaction numbers
    -- and store them in #NewS2TransactionNumbers
    DECLARE @VarTransactionCount int;
    SET @VarTransactionCount = ...
    
    CREATE TABLE #NewS2TransactionNumbers(ID int NOT NULL);
    
    EXEC dbo.GetNewS2TransactionNumbers @ParamCount = @VarTransactionCount;
    
    -- use the generated numbers...
    SELECT ID FROM #NewS2TransactionNumbers AS TT;
    

    설명이 필요 여기에 몇 가지가있다.

    나는 SequenceS2TransactionNumber 테이블에 행 주어진 숫자를 삽입해야합니다. 나는 이것에 대한 도우미 번호 테이블을 사용합니다. 이 표는 단순히 1에서 10까지의 정수 번호를 보유하고 있습니다. 그것은뿐만 아니라 시스템의 다른 곳에서 사용된다. 나는 숫자 테이블에 충분한 행이 있는지 확인하고 필요한 경우 자체와 결합 크로스 100,000 * 100,000 확장합니다.

    나는 대량 삽입 어딘가의 결과를 저장해야하고 어떻게 든 호출자에게 전달합니다. 저장 프로 시저의 테이블 외부를 통과하는 한 가지 방법은 임시 테이블을 사용하는 것입니다. 이 읽기 전용 있기 때문에 불행히도 나는 여기에 테이블 반환 매개 변수를 사용할 수 없습니다. 또한, 나는 직접 임시 테이블 번호의 NewS2TransactionNumbers에 생성 된 시퀀스 값을 삽입 할 수 없습니다. ROLLBACK이 그것을 청소하기 때문에 나는 OUTPUT 절에서 # NewS2TransactionNumbers을 사용할 수 없습니다. 다행히, 테이블 변수는 ROLLBACK에 의해 영향을받지 않습니다.

    그래서, OUTPUT 절의 대상으로 테이블 변수 @TableTransactionNumbers를 사용합니다. 그럼 난 순서 테이블을 정리 트랜잭션을 롤백. 임시 테이블 # 1 NewS2TransactionNumbers 저장 프로 시저의 호출을 볼 수 있기 때문에 그리고, 임시 테이블 # 1 NewS2TransactionNumbers 표 변수 @TableTransactionNumbers로부터 생성 된 시퀀스 값을 복사한다. 테이블 변수 @TableTransactionNumbers 저장 프로 시저의 호출자에게 보이지 않는다.

    또한, (당신이 주석 변형이 사용하는 병합에서 볼 수 있듯이) 호출에 직접 생성 순서를 보낼 OUTPUT 절을 사용하는 것이 가능하다. 그것은 그 자체로 벌금을 작동하지만 나는 호출 저장 프로 시저에 추가 처리를 위해 일부 테이블에서 생성 된 값을 필요로했다. 때 나는 이런 식으로 뭔가를 시도했다 :

    INSERT INTO @TableTransactions (ID)
    EXEC dbo.GetNewS2TransactionNumbers @ParamCount = @VarTransactionCount;
    

    나는 오류가 발생했다

    그러나, 나는 너무 많은 임시 테이블을 가지고 결국 그 이유는의 EXEC 내부 ROLLBACK이 필요합니다.

    이 모든 후, 얼마나 좋은 그것은 적절한 순서로 개체가 SQL 서버의 최신 버전으로 전환하는 것입니다.

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

    3.ID 열은 서열과 대략 유사하다.

    ID 열은 서열과 대략 유사하다.

  4. ==============================

    4.당신은 그냥 평범한 오래된 테이블을 사용하고 시퀀스로 사용할 수 있습니다. 그게 당신의 삽입은 항상 것을 의미합니다 :

    당신은 그냥 평범한 오래된 테이블을 사용하고 시퀀스로 사용할 수 있습니다. 그게 당신의 삽입은 항상 것을 의미합니다 :

    BEGIN TRANSACTION  
    SELECT number from plain old table..  
    UPDATE plain old table, set the number to be the next number  
    INSERT your row  
    COMMIT  
    

    그러나이 작업을 수행하지 않습니다. 잠금 나쁜 것 ...

    내가 SQL Server에서 나에게 시작, 오라클 "순서"방식은 해킹처럼 보였다. 난 당신이 해킹처럼 다른 방향에서 오는 당신하고, SCOPE_IDENTITY () 외모되는 것 같아요.

    그것을 극복. 로마, 로마인처럼 수행 할 때.

  5. ==============================

    5.내가이 문제를 해결하는 데 사용하는 방법은 테이블 '시퀀스를'였습니다 매장 내 모든 시퀀스와 'NEXTVAL'저장 프로 시저가.

    내가이 문제를 해결하는 데 사용하는 방법은 테이블 '시퀀스를'였습니다 매장 내 모든 시퀀스와 'NEXTVAL'저장 프로 시저가.

    는 SQL 테이블 :

    CREATE TABLE Sequences (  
        name VARCHAR(30) NOT NULL,  
        value BIGINT DEFAULT 0 NOT NULL,  
        CONSTRAINT PK_Sequences PRIMARY KEY (name)  
    );
    

    PK_Sequences는 같은 이름의 시퀀스가 ​​없을 것 있는지 확인하기 위해 단지 사용된다.

    저장 프로 시저를 SQL :

    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'nextVal') AND type in (N'P', N'PC')) DROP PROCEDURE nextVal;  
    GO  
    CREATE PROCEDURE nextval  
        @name VARCHAR(30)  
    AS  
        BEGIN  
            DECLARE @value BIGINT  
            BEGIN TRANSACTION  
                UPDATE Sequences  
                SET @value=value=value + 1  
                WHERE name = @name;  
                -- SELECT @value=value FROM Sequences WHERE name=@name  
            COMMIT TRANSACTION  
            SELECT @value AS nextval  
        END;  
    

    일부 시퀀스를 삽입합니다 :

    INSERT INTO Sequences(name, value) VALUES ('SEQ_Workshop', 0);
    INSERT INTO Sequences(name, value) VALUES ('SEQ_Participant', 0);
    INSERT INTO Sequences(name, value) VALUES ('SEQ_Invoice', 0);  
    

    마지막 시퀀스의 다음 값을 얻을,

    execute nextval 'SEQ_Participant';
    

    일부 C # 코드는 시퀀스 테이블에서 다음 값을 얻을 수

    public long getNextVal()
    {
        long nextval = -1;
        SqlConnection connection = new SqlConnection("your connection string");
        try
        {
            //Connect and execute the select sql command.
            connection.Open();
    
            SqlCommand command = new SqlCommand("nextval", connection);
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add("@name", SqlDbType.NVarChar).Value = "SEQ_Participant";
            nextval = Int64.Parse(command.ExecuteScalar().ToString());
    
            command.Dispose();
        }
        catch (Exception) { }
        finally
        {
            connection.Dispose();
        }
        return nextval;
    }
    
  6. ==============================

    6.SQL 서버 2012 년, 당신은 간단하게 사용할 수 있습니다

    SQL 서버 2012 년, 당신은 간단하게 사용할 수 있습니다

    CREATE SEQUENCE
    

    2005 년과 2008 년, 당신은 공통 테이블 표현식을 사용하여 일련 번호의 임의의 목록을 얻을 수 있습니다.

    여기에 예제합니다 (MAXRECURSION 옵션이 중요하다는 것을 주)입니다 :

    DECLARE @MinValue INT = 1;
    DECLARE @MaxValue INT = 1000;
    
    WITH IndexMaker (IndexNumber) AS
    (
        SELECT 
            @MinValue AS IndexNumber
        UNION ALL SELECT 
            IndexNumber + 1
        FROM
            IndexMaker
        WHERE IndexNumber < @MaxValue
    )
    SELECT
        IndexNumber
    FROM
        IndexMaker
    ORDER BY
        IndexNumber
    OPTION 
        (MAXRECURSION 0)
    
  7. ==============================

    7.오라클에 의해 구현 시퀀스는 삽입하기 전에 데이터베이스에 대한 호출을 필요로한다. 같은 SQL 서버에 의해 구현 정체성은 삽입 후 데이터베이스에 대한 호출을 필요로한다.

    오라클에 의해 구현 시퀀스는 삽입하기 전에 데이터베이스에 대한 호출을 필요로한다. 같은 SQL 서버에 의해 구현 정체성은 삽입 후 데이터베이스에 대한 호출을 필요로한다.

    하나는 다른 것보다 더 hackish 없습니다. 순 효과는 동일 - 데이터 저장소에 의존 / 의존성 (대부분의 경우) 저장소에 두 통화를 고유의 인공 키 값을 제공 할 수 있습니다.

    나는 당신의 관계형 모델이 인공 키를 기반으로 있으리라 믿고있어,이 맥락에서, 나는 다음과 같은 관측을 제공합니다 :

    우리는 의미와 인공 키를 스며들게을 추구해서는 안됩니다; 그들의 유일한 목적은 관련 기록을 연결해야합니다.

    데이터를 주문에 관한 당신의 필요는 무엇인가? 그것은보기 (프리젠 테이션)으로 처리하거나이 지속되어야 데이터의 진정한 속성입니다 수 있는가?

  8. ==============================

    8.거기에 식별자와 함께 무대 테이블을 만듭니다.

    거기에 식별자와 함께 무대 테이블을 만듭니다.

    무대 테이블, 잘라 내기로드 1에서 시작하는 식별자를 다시 시드 전에.

    테이블을로드합니다. 각 행은 현재 1 N.에 고유 한 값을 갖는다

    일련 번호를 유지하는 테이블을 만듭니다. 이것은 여러 행, 각 시퀀스 하나가 될 수 있습니다.

    사용자가 만든 시퀀스 테이블에서 일련 번호를 조회. 서열 번호 스테이지 테이블의 행의 개수를 추가하여 시퀀스 번호를 업데이트.

    당신이 그것까지 보였다 seqence 번호를 추가하여 무대 테이블 식별자를 업데이트합니다. 이것은 쉬운 단계로 진행됩니다. 또는 당신의 목표 테이블을로드하면 ETL에서로드로 식별자에 일련 번호를 추가합니다. 이 벌크 로더를 활용하고 다른 변환을 허용 할 수 있습니다.

  9. ==============================

    9.다음 코드를 생각해 보자.

    다음 코드를 생각해 보자.

    CREATE TABLE [SEQUENCE](
        [NAME] [varchar](100) NOT NULL,
        [NEXT_AVAILABLE_ID] [int] NOT NULL,
     CONSTRAINT [PK_SEQUENCES] PRIMARY KEY CLUSTERED 
    (
        [NAME] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    
    CREATE PROCEDURE CLAIM_IDS (@sequenceName varchar(100), @howMany int)
    AS
    BEGIN
        DECLARE @result int
        update SEQUENCE
            set
                @result = NEXT_AVAILABLE_ID,
                NEXT_AVAILABLE_ID = NEXT_AVAILABLE_ID + @howMany
            where Name = @sequenceName
        Select @result as AVAILABLE_ID
    END
    GO
    
  10. ==============================

    10.sqljunkiesshare 상태로, 순서는 여기에 GUI에서 그것을 할 방법은 SQL 서버 2012에 추가되었습니다. 이것은의 equivolent입니다 :

    sqljunkiesshare 상태로, 순서는 여기에 GUI에서 그것을 할 방법은 SQL 서버 2012에 추가되었습니다. 이것은의 equivolent입니다 :

    CREATE SEQUENCE Schema.SequenceName
    AS int
    INCREMENT BY 1 ;
    

    노트:

  11. ==============================

    11.난 완전히 동의하고 프로젝트에 작년에했다.

    난 완전히 동의하고 프로젝트에 작년에했다.

    I는 단지 시퀀스의 이름, 현재 값, 증분 량 테이블을 생성.

    그럼 추가 및 삭제하기 위해이 발동을 만들었습니다. 그리고이 개 기능은 다음 얻을, 현재 얻을 수 있습니다.

  12. ==============================

    12.당신은 순차적 인 키를 사용하여 데이터를 삽입 할,하지만 당신은 방금 삽입 한 키를 얻기 위해 다시 데이터베이스를 조회하고 싶지 않는 경우에, 나는 당신의 유일한 두 가지 선택이 생각 :

    당신은 순차적 인 키를 사용하여 데이터를 삽입 할,하지만 당신은 방금 삽입 한 키를 얻기 위해 다시 데이터베이스를 조회하고 싶지 않는 경우에, 나는 당신의 유일한 두 가지 선택이 생각 :

    내가 클라이언트 측 키 생성을하고 있어요, 내가 GUID를 사랑 해요. 나는 그들이 도대체 아름다운 것 같아요.

    row["ID"] = Guid.NewGuid();
    

    그 라인은 스포츠카 곳의 후드에 누워해야합니다.

  13. ==============================

    13.SQL Server 2005를 사용하는 경우는 ROW_NUMBER를 사용할 수있는 옵션이

    SQL Server 2005를 사용하는 경우는 ROW_NUMBER를 사용할 수있는 옵션이

  14. ==============================

    14.신원 열이있는 또 다른 문제는 일련 번호가 고유해야 할 필요가 둘 이상의 테이블이있는 경우, ID 열이 작업을하지 않습니다. 코리 Trager 언급처럼 그리고, 시퀀스 구현의 롤 - 네 - 자신의 유형은 일부 잠금 문제가 야기 될 수 있습니다.

    신원 열이있는 또 다른 문제는 일련 번호가 고유해야 할 필요가 둘 이상의 테이블이있는 경우, ID 열이 작업을하지 않습니다. 코리 Trager 언급처럼 그리고, 시퀀스 구현의 롤 - 네 - 자신의 유형은 일부 잠금 문제가 야기 될 수 있습니다.

    가장 노골적 해당 솔루션은 "순서"개체의 분리형의 발생하는 정체성에 대해 하나의 열이있는 SQL Server 테이블을 만들 것으로 보인다. 예를 들어, 당신은 그런 개 같은 하나의 시퀀스에서 두 개의 테이블을 가질 것이다 오라클의 경우 <- 시퀀스 객체 -> 고양이가 다음 SQL Server에 당신이 개 같은 세 개의 데이터베이스 오브젝트, 모든 테이블을 만들 것 <- ID 열을 가진 애완 동물 -> 고양이. 당신은 당신이 일반적으로 한 번 당신이 사용자로부터 애완 동물의 실제 유형을 얻을 것입니다 당신이 일반적으로 NEXTVAL을 사용하고 개 또는 고양이 테이블에 삽입 할 시퀀스 번호를 얻기 위해 애완 동물 테이블에 행을 삽입합니다. 추가되는 일반적인 열은 1) 것 시퀀스 번호를 가져올 때 채워하기, 2) 어떤 열 수없는 각 시퀀스 번호에 대한 하나 개의 행이있을 것 몇 가지 결과로, 애완 동물 슈퍼 테이블에 개 / 고양이 테이블에서 이동 될 수 있습니다 필요 그것은이 모든 열을 얻기 위해 가입 필요) 기본 값 3이 있습니다.

  15. ==============================

    15.SQL함으로써 당신은이 전략을 사용할 수 있습니다;

    SQL함으로써 당신은이 전략을 사용할 수 있습니다;

    CREATE SEQUENCE [dbo].[SequenceFile]
    AS int
    START WITH 1
    INCREMENT BY 1 ;
    

    이 SQL에 고유 한 다음 값을 읽어

    SELECT NEXT VALUE FOR [dbo].[SequenceFile]
    
  16. ==============================

    16.TRANSACTION SAFE! SQLServer에 대한 버전의 2012 전에 ... (감사 매트 G.) 이 토론에서 누락 한 것은 거래의 안전이다. 당신은 일련의 숫자를 얻을 경우, 그 번호는 고유해야하며 다른 응용 프로그램 또는 코드는 그 번호를 얻을 수 없습니다. 내 경우에는, 우리는 종종 시퀀스에서 고유 번호를 당겨, 그러나 우리는 우리가 트랜잭션을 커밋하기 전에 다른 사람이 같은 번호를 받고 싶지 않아 그래서 실제 거래는 상당한 시간에 걸쳐 수 있습니다. 우리는이 당겨졌다 때 번호가 예약 된 오라클 시퀀스의 동작을 모방 할 필요가 있었다. 내 솔루션은 우리가 즉시 트랜잭션이 완료되기도 전에, 전체 데이터베이스, 순서를 갱신 할 수 있도록하는 것이 데이터베이스에 별도의 세션 / 트랜잭션을 얻기 위해 xp_cmdshell을 사용하는 것입니다.

    TRANSACTION SAFE! SQLServer에 대한 버전의 2012 전에 ... (감사 매트 G.) 이 토론에서 누락 한 것은 거래의 안전이다. 당신은 일련의 숫자를 얻을 경우, 그 번호는 고유해야하며 다른 응용 프로그램 또는 코드는 그 번호를 얻을 수 없습니다. 내 경우에는, 우리는 종종 시퀀스에서 고유 번호를 당겨, 그러나 우리는 우리가 트랜잭션을 커밋하기 전에 다른 사람이 같은 번호를 받고 싶지 않아 그래서 실제 거래는 상당한 시간에 걸쳐 수 있습니다. 우리는이 당겨졌다 때 번호가 예약 된 오라클 시퀀스의 동작을 모방 할 필요가 있었다. 내 솔루션은 우리가 즉시 트랜잭션이 완료되기도 전에, 전체 데이터베이스, 순서를 갱신 할 수 있도록하는 것이 데이터베이스에 별도의 세션 / 트랜잭션을 얻기 위해 xp_cmdshell을 사용하는 것입니다.

    --it is used like this:
    -- use the sequence in either insert or select:
    Insert into MyTable Values (NextVal('MySequence'), 'Foo');
    
    SELECT NextVal('MySequence');
    
    --you can make as many sequences as you want, by name:
    SELECT NextVal('Mikes Other Sequence');
    
    --or a blank sequence identifier
    SELECT NextVal('');
    

    이 솔루션은 사용 순서 값을 유지하는 하나의 테이블이 필요하며, 두 번째 자율 트랜잭션을 생성하는 절차는 동시 세션이 휩쓸 리게되지 않는 보험에 가입 할 수 있습니다. 당신은 그들이 이름으로 참조되어, 원하는대로 당신은 많은 독특한 시퀀스로 할 수 있습니다. 하기 실시 예는 생략 부호가 (감사를 위해) 시퀀스 이력 테이블에 사용자 및 날짜 스탬프를 요청하도록 수정하지만 덜 복잡한 생각 좋은 예; - 대였다.

      CREATE TABLE SequenceHolder(SeqName varchar(40), LastVal int);
    
    GO
    CREATE function NextVAL(@SEQname varchar(40))
    returns int
    as
    begin
        declare @lastval int
        declare @barcode int;
    
        set @lastval = (SELECT max(LastVal) 
                          FROM SequenceHolder
                         WHERE SeqName = @SEQname);
    
        if @lastval is null set @lastval = 0
    
        set @barcode = @lastval + 1;
    
        --=========== USE xp_cmdshell TO INSERT AND COMMINT NOW, IN A SEPERATE TRANSACTION =============================
        DECLARE @sql varchar(4000)
        DECLARE @cmd varchar(4000)
        DECLARE @recorded int;
    
        SET @sql = 'INSERT INTO SequenceHolder(SeqName, LastVal) VALUES (''' + @SEQname + ''', ' + CAST(@barcode AS nvarchar(50)) + ') '
        SET @cmd = 'SQLCMD -S ' + @@servername +
                  ' -d ' + db_name() + ' -Q "' + @sql + '"'
        EXEC master..xp_cmdshell @cmd, 'no_output'
    
        --===============================================================================================================
    
        -- once submitted, make sure our value actually stuck in the table
        set @recorded = (SELECT COUNT(*) 
                           FROM SequenceHolder
                          WHERE SeqName = @SEQname
                            AND LastVal = @barcode);
    
        --TRIGGER AN ERROR 
        IF (@recorded != 1)
            return cast('Barcode was not recorded in SequenceHolder, xp_cmdshell FAILED!! [' + @cmd +']' as int);
    
        return (@barcode)
    
    end
    
    GO
    
    COMMIT;
    

    이제 작업에 해당 절차를 얻으려면, 당신은 xp_cmdshell을 활성화 할 필요가 있기 위하여려고하고있다, 그 작업을 수행하는 방법의 좋은 설명을 많이가, 여기에 내가 작업에 물건을 얻으려고 할 때 만든 것을 내 개인 노트입니다. 기본 아이디어는 SQLServer에 표면에서의 구성을인가되어 xp_cmdshell을 필요하고 xp_cmdshell을 명령 시퀀스 번호를 삽입하고이를 저지하기 위해 데이터베이스에 액세스하는 것, 아래에서 실행하는 계정으로 사용자 계정을 설정해야한다는 것입니다.

    --- LOOSEN SECURITY SO THAT xp_cmdshell will run 
    ---- To allow advanced options to be changed.
    EXEC sp_configure 'show advanced options', 1
    GO
    ---- To update the currently configured value for advanced options.
    RECONFIGURE
    GO
    ---- To enable the feature.
    EXEC sp_configure 'xp_cmdshell', 1
    GO
    ---- To update the currently configured value for this feature.
    RECONFIGURE
    GO
    
    —-Run SQLServer Management Studio as Administrator,
    —- Login as domain user, not sqlserver user.
    
    --MAKE A DATABASE USER THAT HAS LOCAL or domain LOGIN! (not SQL server login)
    --insure the account HAS PERMISSION TO ACCESS THE DATABASE IN QUESTION.  (UserMapping tab in User Properties in SQLServer)
    
    —grant the following
    GRANT EXECUTE on xp_cmdshell TO [domain\user] 
    
    —- run the following:
    EXEC sp_xp_cmdshell_proxy_account 'domain\user', 'pwd'
    
    --alternative to the exec cmd above: 
    create credential ##xp_cmdshell_proxy_account## with identity = 'domain\user', secret = 'pwd'
    
    
    -—IF YOU NEED TO REMOVE THE CREDENTIAL USE THIS
    EXEC sp_xp_cmdshell_proxy_account NULL;
    
    
    -—ways to figure out which user is actually running the xp_cmdshell command.
    exec xp_cmdshell 'whoami.exe'  
    EXEC xp_cmdshell 'osql -E -Q"select suser_sname()"'
    EXEC xp_cmdshell 'osql -E -Q"select * from sys.login_token"'
    
  17. from https://stackoverflow.com/questions/282943/how-would-you-implement-sequences-in-microsoft-sql-server by cc-by-sa and MIT license