OPENROWSET BCP Bulk Import OUTPUT clause works on dev system SQL Server 2016 but fails on SQL Server 2014 in production

374 Views Asked by At

I think my problem here is just SQL Server versions, but I still need a work around or a fix. What I am doing is pretty simple.

I have a bulk import using OPENROWSET that populates a temp table (staging table) and this temp table is set up by doing a:

select top 0 * 
into ##Person 
from tbl_Person

against an existing physical table to get its column structure. That works fine. This brings in the primary key field (named ID) which is NOT an index field.

I then populate ##Person by doing an OPENROWSET query against a .csv file with a BCP format file (XML). This works also. The next step does a MERGE to move the newly acquired data (in the staging table) into the original physical table.

Then I use the OUTPUT clause from the MERGE statement to insert the new ID values in the tbl_Person physical table into another physical table as foreign key values. Here is where the problem occurs. On my dev system running VS 2017 and SQL Server 2016 developer edition, the whole thing works nicely. However, on the production server (SQL Server 2014 Express) I get (you probably guessed):

enter image description here

I would like to get it to work on SQL Server 2014 without having to rewrite the whole thing. Perhaps if I alter the OUTPUT clause, or set INSERT OFF at the right point. I have tried actually deleting the ID primary key (NOT an index) from the ##Person temp table, but to no avail.

Here is the truncated code:

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

There are 0 best solutions below