SQL Server:如果记录发现更新,则插入,合并查询错误更正

时间:2013-05-09 14:09:06

标签: mysql sql sql-server merge insert-update

如果找到了其他插入

,我已经提出了SQL Server的以下查询来更新行
merge tblpermissions  as t
using (select cid, uid from tblpermissions) as s
on (t.cid = s.cid and t.uid=s.uid)
when not matched
THEN INSERT (cid, uid, [read], [write], [readonly], [modify], [admin]) VALUES ('1',   '1', 1, 1, 0, 1, 1) 
when matched 
THEN UPDATE SET [read]=1, write=1, readonly=0, modify=1, admin=1 ;

虽然没有任何错误,但它没有达到我的预期。表中没有记录,也没有插入新记录。

有任何更正吗?

编辑:考虑到您的建议我已经进一步修改了它,如下所示,但没有任何预期的结果 -

MERGE INTO tblpermissions  as t
using (SELECT '1' AS cid, '1' AS uid FROM tblpermissions) as s
on (t.cid = s.cid and t.uid=s.uid)
WHEN NOT MATCHED 
THEN INSERT (cid, uid, [read], [write], [readonly], [modify], [admin])
VALUES  ('1', '1', 1, 1, 0, 1, 1) 
WHEN MATCHED
THEN UPDATE SET [read]=1, write=1, readonly=0, modify=1, admin=1 ;

编辑:请检查底部的评论,下面是对您的建议的改进查询,更不用说它不会按预期工作,因为它会再次使用相同的表格。

MERGE INTO tblpermissions  as t
using tblpermissions as s
on (t.cid = s.cid and t.uid=s.uid)
WHEN NOT MATCHED 
THEN INSERT (cid, uid, [read], [write], [readonly], [modify], [admin])
VALUES  ('1', '1', 1, 1, 0, 0, 1) 
WHEN MATCHED
THEN UPDATE SET [read]=1, write=1, readonly=0, modify=1, admin=1 ;

编辑:select-if found update-else在下面插入替代 -

$query = "SELECT * FROM ".SQL_PREFIX."permissions\n"
              ."WHERE cid='".$cid."' AND uid='".$uid."'";
    $sth = $this->dbh->query($query);
    $res = $sth->fetch();
    //print_r($res);var_dump($res);
    if(!$res || $res==null)
    {
        $query = "INSERT INTO ".SQL_PREFIX."permissions (cid, uid, [read], [write], [readonly], [modify], [admin])\n"
            ."VALUES ('$cid', '$uid', ".implode(", ", $values).")";
        if(!($sth = $this->dbh->query($query)))
            $this->db_error(__('Error inserting user permissions.'),
                $query);
    }else{
        $query = "UPDATE ".SQL_PREFIX."permissions SET ".implode(", ", $sets).";";
        if(!($sth = $this->dbh->query($query)))
            $this->db_error(__('Error updating user permissions.'),
                $query);
    } 

编辑:以下是针对这种情况的mysql解决方案 -

  

INSERT into tblpermissions(cid,uid,[read],[write],[readonly],   [修改],[admin])VALUES('1','1',1,1,0,0,1)ON DUPLICATE KEY   UPDATE [read] = 1,write = 1,readonly = 0,modify = 1,admin = 1

只使用关键字DUPLICATE KEY。还想再次强调一下,cid& amp; uid组合。所以mysql的作用是,首先它只是寻找cid和amp;的组合。我们试图插入uid,如果发现更新,则会插入新记录。

1 个答案:

答案 0 :(得分:2)

因为源表和目标表是相同的,所以永远不会出现行不匹配的情况。 tblpermissions上的所有行都在更新。

为了插入,源表(使用使用定义)必须与目标表不同,例如以下示例:

merge tblpermissions  as t
using (select cid, uid from otherTable) as s
on (t.cid = s.cid and t.uid = s.uid)

merge tblpermissions  as t
using (select cid, uid from tblpermissions) as s
on (t.cid = s.cid + 1 and t.uid = s.uid + 1)

编辑:由于您使用的是常量值而不是任何表格中的选择结果,因此可能会出现以下情况:

merge tblpermissions as t
using (select '1' cid, '1' uid, 1 [read], 1 [write], 0 [readonly], 0 [modify], 1 [admin]) s
on (t.cid = s.cid and t.uid = s.uid)
when matched 
    then update set [read] = s.[read], write = s.[write], readonly = s.[readonly], modify = s.[modify], admin = s.[admin]
when not matched
    then insert (cid, uid, [read], [write], [readonly], [modify], [admin]) values (s.cid, s.uid, s.[read], s.[write], s.[readonly], s.[modify], s.[admin]);

虽然我认为只插入一行合并是过度杀戮,但更容易做到以下几点:

if exists (select 1 from tblpermissions where cid = '1' and uid = '1')
update tblpermissions set [read] = 1, write = 1, readonly = 0, modify = 1, admin = 1 where cid = '1' and uid = '1'
else
    insert tblpermissions (cid, uid, [read], [write], [readonly], [modify], [admin]) VALUES ('1', '1', 1, 1, 0, 1, 1)

我认为SQL Server没有更短或更优雅的方式来执行此操作,而不像MySQL的on duplicate