2016-02-27 62 views
1

我把从SQL Server存储过程到MySQL,我发现,我已经难倒查询:从SQL Server到MySQL转换 - 合并

IF EXISTS (SELECT * FROM dbo.T_ExampleTable WHERE Col1 = @Col1 AND Col2 = @Col2 AND Col3 = @Col3) 
    SET @return_value = -10 
ELSE IF EXISTS (SELECT * FROM dbo.T_ExampleTable WHERE Col1 = @Col1 OR Col2 = @Col2 OR Col3 = @Col3) 
    SET @return_value = -20; 

IF @return_value = 0 
BEGIN 
    MERGE ExampleDB.dbo.T_ExampleTable AS T 
    USING (VALUES (@Col1, @Col2, @Col3)) AS S (Col1, Col2, Col3) 
    ON T.Col1 = S.Col1 
    WHEN NOT MATCHED THEN 
    INSERT VALUES (S.Col1, S.Col2, S.Col3); 
END 

为了安全起见,我已经改变了名称的变量,但语法是相同的。

我想我已经掌握了MERGE在这里发生了什么(但请纠正我,如果我错了)。我假设我们将3个变量(@Col1,@Col2@Col3)放到我们称为“S”的结果集中。然后,我们正在检查T_ExampleTable中的每一行,以获得匹配的Col1值。最后,我们要说的是,如果它不匹配任何行,INSERT这些值。

现在,我对MERGE语法不太熟悉,所以我可能会忽略上述假设。然而,假设我是正确的,这与仅执行SELECT FROM T_ExampleTable WHERE Col1 = @Col1,然后检查@@ROWCOUNT(或FOUND_ROWS()在MySQL中)并且如果它不等于0相同,则执行INSERT

此外,我更难以通过MERGE以上的逻辑困惑。如果我对MERGE工作原理的理解是正确的(并且可能会关闭),那么整个陈述就毫无意义。因为基本上,如果在T_ExampleTable内存在@Col1,则@return_value将等于-10或-20。因此,它不能等于0,我们不会击中MERGE。如果@Col1不存在于T_ExampleTable内,则@return_value将等于0,但MERGE不会返回任何结果集,因为T.Col1 = S.Col1永远不会成立。

这就是为什么我相信我必须误解MERGE的工作原理。无论是那个,还是我正在移植的SQL Server代码都写得很差(我想这也是可能的)。

因此,最终,我在这里寻找两个答案。一个有助于澄清MERGE声明的逻辑是什么,以及我对上述代码的理解是否正确,另一个说明将此转换为MySQL的可能解决方案。

谢谢!

回答

1

出于实用的目的,我认为这是相当于这个(在两个数据库):

INSERT INTO T(Col1, Col2, Col3) 
    SELECT col1, col2, col3 
    FROM (SELECT @Col1 as col1, @Col2 as col2, @Col3 as col3) s 
    WHERE NOT EXISTS (SELECT 1 
         FROM ExampleDB.dbo.T_ExampleTable t 
         WHERE t.col1 = s.col1 
        ); 

可能会有一些边缘情况下,他们是不完全一样的 - 比如说,在并发呼叫条款到存储过程或col1NULL。但是,无论如何,你已经在两个数据库之间锁定了差异。

(而且,虽然你没有问,我希望Postgres的是一个更自然的数据库从SQL Server切换到Postgres的原因和SQL Server在功能较大的重叠。)

+0

感谢您超快速回复!从我所知道的情况来看,这似乎至少在返回0/1行的基础上是否存在匹配的Col1。但是,它会跳过插入部分。尽管我并不完全无能,所以我可以自己弄清楚,我想知道你是否可以评论MERGE上面的代码?我的理解是错误的,整个程序是毫无意义的? –