0

我有一个大表,我想从该表中获取数据,并将其插入其他(较小的)表中。但是在执行此操作时,我想将大表(“已处理”)中的列标记为 true,以便下次运行查询时,它不会最终创建重复项。除了事后创建小查询以将所有内容设置为 0 到 1 之外,还有更简单的方法吗?或者这是最有效的方法?

DECLARE @largeTable TABLE(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    productName varchar(100),
    productId int,
    quantity int,
    someVar int,
    Processed bit)

INSERT INTO @largeTable (productName, productId, quantity, someVar, Processed)
VALUES ('Apple', 1, 50, 34, 0),
        ('Orange', 2, 50, 53, 0),
        ('Banana', 3, 50, 165, 0),
        ('Pineapple', 4, 74, 34, 0),
    ('Mango', 5, 50, 388, 0),
        ('Kiwi', 6, 50, 2, 0),
        ('Strawberry', 7, 50, 16, 0)

SELECT * FROM @largeTable

DECLARE @smallTable TABLE(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    productName varchar(100),
    productId int)

INSERT INTO @smallTable (productName, productId)
SELECT productName, productId
FROM @largeTable
WHERE Processed = 0

UPDATE @largeTable
Set Processed = 1
WHERE Processed = 0

SELECT * FROM @largeTable
SELECT * FROM @smallTable
4

2 回答 2

2

您可以使用合并语句,这里根据产品ID,您可以发现如果任何行已经存在,如果存在则更新它或者插入:

MERGE smalltable AS target
USING (SELECT productName, productId from largetable) AS source (productName, productId)
ON (target.productId = source.productId)
WHEN MATCHED THEN 
    UPDATE SET productName = source.productName
WHEN NOT MATCHED THEN   
    INSERT (productId, productName)
    VALUES (source.productId, source.productName)

此外,要获取插入的 ProductsId 以便您可以更新 Processed 列,您可以执行以下操作:

  Update largetable
  set Processed=1
  from largetable join Inserted on largetable.Productid=Inserted.ProductId

这里,Inserted 是插入/更新操作后由 SQL 创建的逻辑表

于 2013-09-05T20:21:05.430 回答
1

这个想法是获取未处理的记录(Delta)并将它们的主键值插入表变量中,然后使用此信息来管理从大表到小表的数据传输并更新大表传输的记录(更新标志)。

BEGIN TRY
BEGIN TRANSACTION 

DECLARE @ProccessTable TABLE (IsProcessed SMALLINT)

DECLARE @LargeTable TABLE ( 
                   field1 INT IDENTITY(1,1) NOT NULL, 
                   field2 NVARCHAR(50) NULL, 
                   field3 NVARCHAR(50) NULL, 
                   field4 NVARCHAR(50) NULL, 
                   IsProcessed SMALLINT NOT NULL  
                   )

INSERT INTO @LargeTable 
VALUES ('ABC', 'DEF', 'GHI',0), ('JKL','MNO','PQR',0), ('STU','VXY','ZAB',0)

SELECT * FROM @LargeTable WHERE IsProcessed = 0

DECLARE @SmallTable TABLE ( 
                   field1 INT NOT NULL, 
                   field2 NVARCHAR(50) NULL, 
                   field3 NVARCHAR(50) NULL
                   )

INSERT INTO @ProccessTable
SELECT field1 FROM  @LargeTable WHERE IsProcessed = 0 

INSERT INTO @SmallTable
SELECT field1, field2, field3 FROM @LargeTable WHERE field1 IN (SELECT 
field1 FROM @ProccessTable)

UPDATE @LargeTable SET IsProcessed = 1 WHERE field1 IN (SELECT field1 FROM @ProccessTable)

SELECT * FROM @LargeTable WHERE IsProcessed = 0
SELECT * FROM @SmallTable

COMMIT TRANSACTION 

END TRY
BEGIN CATCH 
ROLLBACK 
END CATCH 
于 2018-03-22T18:08:52.297 回答