2016-03-22 18 views
0

Yardım edin arkadaşlar, varolan tablonun yüklenen dosyalardan güncelleştirilmesini istiyorum, ancak güncelleştirmenin başladığı bölümde sorun yaşıyorum, referans numarasıyla eşleşmek istiyorum Tablodan güncellemek için doğru satırı seçecektir.MSSQL: yüklenen dosyadan satırları eşleştirmeyi güncelle

USE [RMT] 
GO 
/****** Object: StoredProcedure [dbo].[gen048update] Script Date: 03/29/2016 08:35:52 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  
-- Create date: 
-- Description: Upload data 
-- ============================================= 
ALTER PROCEDURE [dbo].[gen048update] 
(
     @fileDate VARCHAR(20) 
) 


AS BEGIN 
SET NOCOUNT ON 

declare @sql NVARCHAR(MAX), 

@dynamic varchar(8000), 
@tablesuffix varchar(8), 
@refd varchar(30), 
@refcnt varchar(30) 



select @refd=(SELECT REPLACE(CONVERT(VARCHAR(10), GETDATE(), 102), '.', '') AS [MMDDYYYY]) 
select @tablesuffix=(SELECT REPLACE(UPPER(RIGHT(CONVERT(VARCHAR(11), GETDATE(), 106), 8)), '', '') AS [Mon-YYYY]) 
--print @tablesuffix 
--convert(varchar,day(convert(datetime, @fileDate)))+upper(substring(datename(m,convert(datetime,@fileDate)),1,3))+convert(varchar,year(convert(datetime,@fileDate))) 


--**COMPOSE FIGURE COLUMNS 
declare @currmonth varchar(10) 
select @dynamic='' 

create table #logs(
i int identity(1,1), 
tableName varchar(50), 

status varchar(30) 
) 

--SELECT getdate() 

    SET NOCOUNT ON; 
    CREATE TABLE #temp (WHOLEROW VARCHAR(8000)) 

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

    CREATE TABLE #temp1 (WHOLEROW VARCHAR(8000)) 

    --BEGIN TRY 

     BEGIN TRANSACTION 

     DECLARE @SQL2 NVARCHAR(MAX) 
     SET @SQL2 = 'BULK INSERT #temp1 
     FROM ''Y:\FTP\RMT\RMT\gen048\delivery\' + @fileDate + '.txt' + ''' 
     WITH (DATAFILETYPE = ''char'', KEEPNULLS, FIRSTROW=1, MAXERRORS=0, ROWTERMINATOR = ''' + CHAR(0x0A) + ''')' 

;WITH Splitted(AsXml) AS 
(
    SELECT CAST('<x>' + REPLACE(t1.WHOLEROW,'|','</x><x>') + '</x>' AS XML) 
    FROM #records AS t1 
) 
SELECT AsXml.value('x[1]','varchar(max)') AS ID 
     ,ID_Splitted.* 
     ,AsXml.value('x[2]','varchar(max)') AS FSI_Field 
     ,AsXml.value('x[3]','varchar(max)') AS CAPTION 
     ,AsXml.value('x[4]','varchar(max)') AS STATUS 
     ,AsXml.value('x[5]','varchar(max)') AS NUMBER 
     ,AsXml.value('x[6]','varchar(max)') AS Fld1 
     ,AsXml.value('x[7]','varchar(max)') AS Fld2 
     ,AsXml.value('x[8]','varchar(max)') AS Fld3 
     ,AsXml.value('x[9]','varchar(max)') AS Fld4 
     ,AsXml.value('x[10]','varchar(max)') AS TARGET 
     ,AsXml.value('x[11]','varchar(max)') AS TARGET_TYPE 
     ,AsXml.value('x[12]','varchar(max)') AS TARGET_NUMBER 
INTO #temp2 
FROM Splitted 
CROSS APPLY(SELECT LEFT(AsXml.value('x[1]','varchar(max)'),1) AS FirstLetter 
        ,CAST(SUBSTRING(AsXml.value('x[1]','varchar(max)'),2,8) AS DATE) AS IncludedDate 
        ,CAST(SUBSTRING(AsXml.value('x[1]','varchar(max)'),11,100) AS INT) AS IncludedNumber) AS ID_Splitted; 

     EXEC sys.sp_executesql @SQL2 

declare @sourceTable varchar(500) 
declare @year varchar(22) 
declare @month varchar(3) 
declare @test varchar(11) 
declare @result varchar(8) 
declare @index int 

declare @string varchar(15) 
set @string = (SELECT DISTINCT TOP 1 REPLACE(dbo.fn_Parsename(WHOLEROW, '|', 0), CHAR(9), '') FROM #temp1) 
set @test = (select UPPER(convert(datetime,substring(@string,2,charindex('-',@string,1)-2)))) 
--select @test 

set @month =(left(@test,3)) 

set @year = (right(@test,4)) 
--select @year 

set @result = @month + @year 
-- select @result 

set @sourceTable = 'gen_048_'[email protected] 
select @sourceTable 

declare @ref varchar(255) 
SET @ref = 'select convert(varchar(55),refdate)+''-''+convert(varchar(55),refcount)' 
select @ref 

declare @string2 varchar(255) 
SET @string2 = 'select convert(varchar(55),refdate)+''-''+convert(varchar(55),refcount) FROM ' 
       + Quotename(@sourceTable) 
print @string2 
EXEC (@string2) 

set @index = 1 




SELECT * FROM #temp2; 

DROP TABLE #temp2; 
DROP TABLE #temp1; 


declare @refnum varchar(100) 
declare @stat varchar(100) 
declare @statdate varchar(100) 


WHILE (@index <= (SELECT MAX([index]) FROM #records)) 


     BEGIN 

     set @stat = (select stat from #records where [index] = @index) 
     select @stat 

     set @statdate = (select statdate from #records where [index] = @index) 
     select @statdate 

     set @refnum = (select refnum from #records where [index] = @index) 
     set @refnum = replace(@refnum, 'F', '') 

     select @refnum 
     -- = '[email protected]+'(courier, stat, statdate, stat2, statdate2, stat3, statdate3, recvby, rel, pupdate) 
     select * from #records 

         --(select UPPER(convert(datetime,substring(@string,2,charindex('-',@string,1)-2)))) 
     set @sql = ' 
      MERGE gen_048_MAR2016 target 
      USING #records source 
       ON target.refdate'+'-'+'select convert(varchar(20), target.refcount) = (select substring(source.refnum, 2, 13)) 
      WHEN MATCHED THEN 
       UPDATE 
        SET 
        target.stat = source.stat 

      WHEN NOT MATCHED BY TARGET THEN 
       INSERT (stat, statdate) 
       VALUES (source.stat, source.statdate)     
       ;' 
       select @refnum, @stat, @statdate 
       print @sql 
       exec (@sql) 

      SELECT 'File has been successfully uploaded', @fileDate,'success' as msg 

      set @index = @index + 1 

     END 

     COMMIT TRANSACTION 

END 
+0

Etiketin MySql ve SQL Server ile sonuçlanır. Lütfen gerçek RDBMS'yi etiketleyin (SQL Server'ı varsayalım ...) Kodunuzdan yüklediğinizi görebilirsiniz. "WHOLEROW" tablonuzun sütununda # temp? Bu tabloyu nasıl doldurursun? Lütfen verilerin neye benzediğini gösterin. Ve hedef tablonuzun yapısını göster. Eminim, bu çok daha kolay yapılabilirdi ... – Shnugo

+0

Üzgünüz, tüm önerilen etiketlere tıkladım. MySQL'i fark etmedim, "WHOLEROW", 0 veya 1 satırını yüklediğim verilerden Bu yükleme dosyasından referans kodu Ex. F20160316-1000 ve ben değişken '@ string2' –

+0

Merhaba Vince tablodan benim şimdiki veriye uyan ediyorum. Senin yanında oturmuyorum ... Lütfen verileri (bazı satırlar) ve hedef tablonun yapısını göster. Bu masa boş mu? Tüm satırlar yeni veriler mi yoksa tüm satırlar var olan veriler mi yoksa her ikisi de mi olabilir? "MERGE" hakkında bilgi edinin Lütfen bu dosyayı nasıl yüklediğinizi söyle. – Shnugo

cevap

1

Bu, boruyla sınırlandırılmış verilerinize girmek için çok daha kolay bir yaklaşımdır. Tablo benzeri verilerinizi # temp2 içinde bulabilirsiniz. Buradan, UPDATE, INSERT veya MERGE verilerinizi hedefinize kolayca getirmeniz gerekir.

Dikkat: sütun adları çöp olabilir bu yüzden ... senin sütunların anlamını tahmin sadece olabilir

CREATE TABLE #temp1(WHOLEROW VARCHAR(8000)); 
INSERT INTO #temp1 VALUES 
('F20160323-1000|FSI|BISCOCHO|DELIVERED|42317|||||GINA T|TENANT|42311') 
,('F20160323-1001|FSI|MARTINNE|DELIVERED|42314|||||MERLIE STRADA|IN LAW|42311') 
,('F20160323-1002|FSI|MANALO|DELIVERED|42313|||||GINA A|TENANT|42311') 
,('F20160323-1004|FSI|HAMOY CAJAYON|DELIVERED|42311|||||MERLIE QTRADA|IN LAW|42311') 
,('F20160323-1003|FSI|FRANCISCA|DELIVERED|42312|||||GINA B|TENANT|42311') 
,('F20160323-1005|FSI|NINA|DELIVERED|42318|||||MERLIE STRADA|IN LAW|42311'); 

;WITH Splitted(AsXml) AS 
(
    SELECT CAST('<x>' + REPLACE(t1.WHOLEROW,'|','</x><x>') + '</x>' AS XML) 
    FROM #temp1 AS t1 
) 
SELECT AsXml.value('x[1]','varchar(max)') AS ID 
     ,ID_Splitted.* 
     ,AsXml.value('x[2]','varchar(max)') AS FSI_Field 
     ,AsXml.value('x[3]','varchar(max)') AS CAPTION 
     ,AsXml.value('x[4]','varchar(max)') AS STATUS 
     ,AsXml.value('x[5]','varchar(max)') AS NUMBER 
     ,AsXml.value('x[6]','varchar(max)') AS Fld1 
     ,AsXml.value('x[7]','varchar(max)') AS Fld2 
     ,AsXml.value('x[8]','varchar(max)') AS Fld3 
     ,AsXml.value('x[9]','varchar(max)') AS Fld4 
     ,AsXml.value('x[10]','varchar(max)') AS TARGET 
     ,AsXml.value('x[11]','varchar(max)') AS TARGET_TYPE 
     ,AsXml.value('x[12]','varchar(max)') AS TARGET_NUMBER 
INTO #temp2 
FROM Splitted 
CROSS APPLY(SELECT LEFT(AsXml.value('x[1]','varchar(max)'),1) AS FirstLetter 
        ,CAST(SUBSTRING(AsXml.value('x[1]','varchar(max)'),2,8) AS DATE) AS IncludedDate 
        ,CAST(SUBSTRING(AsXml.value('x[1]','varchar(max)'),11,100) AS INT) AS IncludedNumber) AS ID_Splitted; 

SELECT * FROM #temp2; 

DROP TABLE #temp2; 
DROP TABLE #temp1; 

ID   FirstLetter IncludedDate InclNmbr FSI CAPTION  STATUS  NUMBER TARGET   TYPE NUMBER 
F20160323-1000 F  2016-03-23  1000  FSI BISCOCHO  DELIVERED 42317 GINA T   TENANT 42311 
F20160323-1001 F  2016-03-23  1001  FSI MARTINNE  DELIVERED 42314 MERLIE STRADA IN LAW 42311 
F20160323-1002 F  2016-03-23  1002  FSI MANALO  DELIVERED 42313 GINA A   TENANT 42311 
F20160323-1004 F  2016-03-23  1004  FSI HAMOY CAJAYONDELIVERED 42311 MERLIE QTRADA IN LAW 42311 
F20160323-1003 F  2016-03-23  1003  FSI FRANCISCA DELIVERED 42312 GINA B   TENANT 42311 
F20160323-1005 F  2016-03-23  1005  FSI NINA   DELIVERED 42318 MERLIE STRADA IN LAW 42311 
+0

Kullanmakta olduğum 'VALUES', kendi kodunuzda yüklenen dosyadan –

+0

@ VinceOsana olacaktır. Eğer # temp1' 'içine dosyadan' DÖKME INSERT' yapmak Kodum bazı test verilerini ekler, bu yüzden sadece 'başlamak;. iLE ...' çağrı sonra '# temp2' tüm verilerinizi bulacaksınız Sorununuz nerede? Sonunda DROP TABLE ifadelerini yorumlayabilirsiniz ... – Shnugo

+0

Şu anda bu kodlarla gerçekten kayıyorum çünkü tüm bunları farklı boyutlardan aldım ve şimdi anlayamıyorum. Tüm kodları şimdi sorgumdan yapıştırdım –