OPENROWSET BCP批量导入OUTPUT子句适用于开发系统SQL Server 2016,但在生产

时间:2017-04-30 04:23:01

标签: sql-server tsql merge sql-server-2014 sql-server-2016

我认为我的问题只是SQL Server版本,但我仍需要解决方法或修复。我正在做的很简单。

我使用OPENROWSET进行批量导入,填充临时表(临时表),并通过执行以下操作设置此临时表:

select top 0 * 
into ##Person 
from tbl_Person

针对现有物理表获取其列结构。这很好。这会引入主键字段(名为ID),而不是索引字段。

然后,我通过对具有BCP格式文件(XML)的##Person文件执行OPENROWSET查询来填充.csv。这也有效。下一步是MERGE将新获取的数据(在临时表中)移动到原始物理表中。

然后我使用MERGE语句中的OUTPUT子句将tbl_Person物理表中的新ID值作为外键值插入到另一个物理表中。这是问题发生的地方。在我的运行VS 2017和SQL Server 2016开发人员版的开发系统上,整个过程非常有效。但是,在生产服务器(SQL Server 2014 Express)上,我得到了(您可能已经猜到了):

enter image description here

我想让它在SQL Server 2014上工作,而不必重写整个事情。也许如果我改变OUTPUT子句,或者在正确的位置设置INSERT OFF。我试图从##Person临时表中删除ID主键(不是索引),但无济于事。

这是截断的代码:

USE [thedb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_BulkMergeDynamic] 
     @OrganisationID int, @DF nvarchar(1024), @FF nvarchar(1024)
AS
BEGIN
    SET NOCOUNT ON;

    IF OBJECT_ID('tempdb..##Person') IS NOT NULL
    DROP TABLE ##Person

    --SET IDENTITY_INSERT ##Person OFF - Requires table creation then alter table, which might be the solution
    select top 0 * into ##Person from tbl_Person 
    --GO 
    ALTER TABLE ##Person NOCHECK CONSTRAINT all 
    ALTER TABLE ##Person ALTER COLUMN DateCreated DateTime NULL 

    DECLARE @SQL NVARCHAR(MAX) = ''
    SET @SQL = 'INSERT INTO ##Person (tpp.RecordTitle, tpp.SecurityCode, ... truncated
SELECT CONCAT(tpp.FirstName, '' '', tpp.LastName), tpp.SecurityCode, ...truncated
FROM OPENROWSET(BULK''' + @DF + ''', FORMATFILE=''' + @FF + ''' ) tpp'

ALTER TABLE ##Person CHECK CONSTRAINT all

     EXEC sp_executesql @SQL

    -- SET IDENTITY_INSERT tbl_Person ON
    --ALTER TABLE tbl_Person ALTER COLUMN DateCreated DateTime NULL
    SET IDENTITY_INSERT tbl_Person OFF
    SET IDENTITY_INSERT tbl_OC OFF
    alter table ##Person drop column ID
    MERGE INTO tbl_Person AS tgt USING ##Person AS src
       ON tgt.EmailAddress1=src.EmailAddress1

    WHEN NOT MATCHED then 
    insert values(src.RecordTitle, src.SecurityCode, GETDATE(), src.FK_User_CreatedBy, ... truncated)
    --SET IDENTITY_INSERT tbl_Person OFF
           --VVVVVVVVV The problem seems to be here in SQL Server 2104 only. SQL Server 2016 developer executes with the right results in output tables.
    OUTPUT inserted.ID, inserted.EmailAddress1, @OrID, 1 INTO tbl_OC(FK_Person, RecordTitle, FK_Or, IsrID);-- output inserted.*; --@PersonTempID;

    drop table ##Person
END

GO

0 个答案:

没有答案