Sql server 如何将一组键(uniqueid)添加到临时表中,以便以后插入到生产表中

Sql server 如何将一组键(uniqueid)添加到临时表中,以便以后插入到生产表中,sql-server,oracle,sql-update,temp-tables,Sql Server,Oracle,Sql Update,Temp Tables,我已经准备好将数据插入到生产表中,但是ID列为NULL,需要在插入之前预先填充ID。我在另一个临时表中有这些ID。。。我只想简单地将这些ID应用于我的临时表中的记录 例如。。。假设我有10条记录都需要ID。我在另一个临时表中正好有10个ID。。。它们只需应用于“准备插入”临时表中的10条记录 我在甲骨文公司工作了大约9年,我可以通过使用FORALL循环在我的“收藏”上循环来完成这项工作。。。基本上,我只需循环我的“准备插入”临时表,并为每一行应用来自另一个“集合”的ID。。。在SQL Serve

我已经准备好将数据插入到生产表中,但是ID列为NULL,需要在插入之前预先填充ID。我在另一个临时表中有这些ID。。。我只想简单地将这些ID应用于我的临时表中的记录

例如。。。假设我有10条记录都需要ID。我在另一个临时表中正好有10个ID。。。它们只需应用于“准备插入”临时表中的10条记录

我在甲骨文公司工作了大约9年,我可以通过使用FORALL循环在我的“收藏”上循环来完成这项工作。。。基本上,我只需循环我的“准备插入”临时表,并为每一行应用来自另一个“集合”的ID。。。在SQL Server中,我使用的是临时表,而不是集合,以及。。。除了WHILE之外,SQL Server中没有FORALL循环或任何奇特的循环

我的目标是了解在SQL Server中实现这一点的适当方法。我了解到,在SQL Server世界中,许多DML操作都是基于集合的,而当我在oracle工作时,我们通过数组/集合处理数据,并使用游标或循环,我们只需对数据进行迭代。我见过在SQL Server世界中,使用游标和/或逐个记录地迭代数据是不受欢迎的

帮我把脑袋从我呆了这么长时间的“Oracle”空间中解放出来,进入我需要进入的“SQL Server”空间。这是一场小小的斗争

下面的代码是我目前如何实现这一点的,但是它看起来很复杂

    SET NOCOUNT ON;

    DECLARE @KeyValueNewMAX INT,
            @KeyValueINuse  INT,
            @ClientID       INT,
            @Count          INT;

    DROP TABLE IF EXISTS #InterOtherSourceData;
    DROP TABLE IF EXISTS #InterOtherActual;
    DROP TABLE IF EXISTS #InterOtherIDs;

    CREATE TABLE #InterOtherSourceData      -- Data stored here for DML until data is ready for INSERT 
    (
        UniqueID            INT IDENTITY( 1, 1 ),
        NewIntOtherID       INT,
        ClientID            INT
    );

    CREATE TABLE #InterOtherActual          -- Prod Table where the data will be INSERTED Into
    (
        IntOtherID          INT,
        ClientID            INT
    );

    CREATE TABLE #InterOtherIDs             -- Store IDs needing to be applied to Data
    (
        UniqueID            INT IDENTITY( 1, 1 ),
        NewIntOtherID       INT
    );

    BEGIN

        /* TEST Create Fake Data and store it in temp table */
            WITH fakeIntOtherRecs AS
            (
                SELECT 1001 AS ClientID, 'Jake'  AS fName, 'Jilly'   AS lName UNION ALL
                SELECT 2002 AS ClientID, 'Jason' AS fName, 'Bateman' AS lName UNION ALL
                SELECT 3003 AS ClientID, 'Brain' AS fName, 'Man'     AS lName 
            )

            INSERT INTO #InterOtherSourceData (ClientID)
            SELECT fc.ClientID--, fc.fName, fc.lName
            FROM fakeIntOtherRecs fc
            ;
        /* END TEST Prep Fake Data */


        /* Obtain count so we know how many IDs we need to create */
        SELECT @Count = COUNT(*) FROM #InterOtherSourceData;

        PRINT 'Count: ' + CAST(@Count AS VARCHAR);

        /* For testing set value OF KeyValuePre to the max key currently in use by Table */
        SELECT @KeyValueINuse = 13;

        /* Using the @Count let's obtain the new MAX ID... basically Existing_Key + SourceRecordCount = New_MaxKey */
        SELECT @KeyValueNewMAX = @KeyValueINuse + @Count /* STORE new MAX ID in variable */

        /* Print both keys for testing purposes to review */
        PRINT 'KeyValue Current: ' + CAST(@KeyValueINuse AS VARCHAR) + ' KeyValue Max: ' + CAST(@KeyValueNewMAX AS VARCHAR);

        /* Using recursive CTE generate a fake table containing all of the IDs we want to INSERT into Prod Table */
        WITH CTE AS
        (
            SELECT (@KeyValueNewMAX - @Count) + 1 AS STARTMINID, @KeyValueNewMAX AS ENDMAXID  UNION ALL

            /* SELECT FROM CTE to create Recursion */
            SELECT STARTMINID + 1  AS STARTMINID, ENDMAXID FROM CTE 
            WHERE (STARTMINID + 1) < (@KeyValueNewMAX + 1)
        )




        INSERT INTO #InterOtherIDs (NewIntOtherID)
        SELECT c.STARTMINID AS NewIntOtherID
        FROM CTE c
        ;



        /* Apply New IDs : Using the IDENTITY fields on both Temp Tables I can JOIN the tables by the IDENTITY columns
            | Is there a BETTER Way to do this?... like LOOP over each record rather than having to build up common IDs in both tables using IDENTITY columns?
        */
        UPDATE #InterOtherSourceData SET NewIntOtherID = oi.NewIntOtherID
        FROM #InterOtherIDs oi
            JOIN #InterOtherSourceData o ON o.UniqueID = oi.UniqueID
        ;

        /* View data that is ready for insert */
        --SELECT *
        --FROM #InterOtherSourceData
        --;

        /* INSERT DATA INTO PRODUCTION TABLE */
        INSERT INTO #InterOtherActual (IntOtherID, ClientId)
        SELECT NewIntOtherID, ClientID
        FROM #InterOtherSourceData
        ;

        SELECT * FROM #InterOtherActual;
    END

要在SQL Server中预生成键值,请使用列而不是标识列

乙二醇

drop table if exists t
drop table if exists #t_stg 

drop sequence t_seq

go
create sequence t_seq start with 1 increment by 1

create table t(id int primary key default (next value for t_seq),a int, b int)

create table #t_stg(id int, a int, b int)

insert into #t_stg(a,b) values (1,2),(3,3),(4,5)

update #t_stg set id = next value for t_seq

--select * from #t_stg

insert into t(id,a,b) 
select * from #t_stg