1

我有一對數據庫(一個mssql和一個oracle),由不同的團隊運行。現在有些數據正在通過mssql表中的存儲過程定期進行同步。此存儲過程調用一個非常大的MSSQL數據類型轉換

MERGE [mssqltable].[Mytable] as s 
USING THEORACLETABLE.BLA as t 
ON t.[R_ID] = s.[R_ID] 
WHEN MATCHED THEN UPDATE SET [Field1] = s.[Field1], ..., [Brokenfield] = s.[BrokenField] 
WHEN NOT MATCHED BY TARGET THEN 
... another big statement 

Brokenfield是一個數字一個直到今天,並且可以採取值N ULL, 0, 1, .., 24

現在,甲骨文隊今天推出了重大更改,出於某種原因,改變了列的類型爲字符串,現在在列中具有值NULL, "", "ALFA", "BRAVO" ...。當然,同步被破壞了。

在這裏修復同步最簡單的方法是什麼?我(Mysql團隊負責人,前端專家,但在數據庫中並非如此)通常會應用我們的數據庫專家人員之一,但他們現在都生病了,並且修補程序必須今天上線......

我認爲的存儲過程,如CONVERT_BROKENFIELD_INT_TO_STRING左右,基於某些switch-case,可以在該合併語句中調用,但不知道該怎麼做。

編輯/澄清:
我需要的是一種方法,使的SQL代碼(存儲過程)的組塊,以「ALFA」的輸入,並返回1,「BRAVO」 - ,> 2等並且可以重複使用,以避免在多個地方寫入巨大的ifs。

+0

你將需要更改列的數據類型的SQL Server數據庫。它需要是一個(n)varchar(SomeSize)。它取決於Oracle端的列的大小,以確保它可以容納所有數據。 –

+0

如果可能,我很樂意避免這種情況。它需要大量重構mssql上的軟件。我今天需要在線修復,並且在一家大公司使用的100000 LOC軟件中進行這樣的更改只能在固定發佈日期進行,並至少進行3個月的測試。 –

+0

那麼你不能像ALFA那樣插入字符串到數字列中。你可以用一個case表達式來包裝這個列,並且當它不是一個有效的數字時就插入NULL。但是你正在做的是從一個曾經是數字的來源獲取數據,而不再是一個數字,並將該數值插入到數字列中。這些值必須是數字,否則將失敗。 –

回答

2

如果您無法簡化@RichardHansell所描述的正確值的邏輯,您可以創建一個BrokenField的人行橫道表以獲得正確的值。然後,您可以使用公用表格表達式或帶有left join的子查詢來在該人行橫道上使用merge

create table dbo.BrokenField_Crosswalk (
    BrokenField varchar(32) not null primary key 
    , CorrectedValue int 
); 

insert into dbo.BrokenField_Crosswalk (BrokenField,CorrectedValue) values 
    ('ALFA', 1) 
, ('ALPHA', 1) 
, ('BRAVO', 2) 
... 
go 

和你的merge代碼將是這個樣子:

;with cte as (
    select o.R_ID 
    , o.Field1 
    , BrokenField = cast(isnull(c.CorrectedValue,o.BrokenField) as int) 
    .... 
    from oracle_table.bla as o 
    left join dbo.BrokenField_Crosswalk as c 
) 

merge into [mssqltable].[Mytable] t 
    using cte as s 
    on t.[R_ID] = s.[R_ID] 
    when matched 
    then update set 
     [Field1] = s.[Field1] 
     , ... 
     , [Brokenfield] = s.[BrokenField] 
    when not matched by target 
    then 
+0

看起來像一個好主意,我會嘗試! –

+0

僅供參考 - 工作很好 –

+0

@PetrOsipov樂意幫忙!感謝您回報! – SqlZim

0

如果他們使用的名稱與在該進去的順序開始了一封信:

A = 1 
B = 2 
C = 3 
etc. 

然後,你可以做這樣的事情:

MERGE [mssqltable].[Mytable] as s 
USING THEORACLETABLE.BLA as t 
ON t.[R_ID], 1)) - ASCII('A') + 1 = s.[R_ID] 
WHEN MATCHED THEN UPDATE SET [Field1] = s.[Field1], ..., [Brokenfield] = s.[BrokenField] 
WHEN NOT MATCHED BY TARGET THEN 
... another big statement 

編輯:但實際上我重新閱讀你的問題,你正在談論[Brokenfield]是問題專欄,所以我的解決方案將無法正常工作。

我現在不太明白,因爲MERGE語句似乎是用數字更新oracle表,所以您肯定需要映射以另一種方式工作,即1 - > ALFA,2 - > BETA等等?