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等等?