所以我试图绕过游标。我有将数据从一个数据库传输到另一个数据库的任务,但它们的模式略有不同。假设我有TableOne(Id,Name,Gold)和TableTwo(Id,Name,Lvl)。我想从TableTwo获取所有记录并将其插入到TableOne中,但它可以是Name列上的重复数据。因此,如果TableOne中存在来自TableTwo的单个记录(在Name列比较中),我想跳过它,如果不存在 - 在TableOne中创建具有唯一ID的记录。
我正在考虑在TableTwo中对每条记录进行循环,并在每个记录中检查它是否存在于TableOne中。那么,如何在不每次调用其他数据库的情况下进行此检查?我想首先从TableOne中选择所有记录,将其保存到变量中并在循环中自行检查此变量。这在SQL中是否可行?我对SQL不太熟悉,一些代码示例会有很多帮助。
如果重要的话,我正在使用Microsoft SQL Server Management Studio。当然,TableOne和TableTwo存在于不同的数据库中。
答案 0 :(得分:2)
试试这个
Insert into table1(id,name,gold)
Select id,name,lvl from table2
Where table2.name not in(select t1.name from table1 t1)
如果您想为每一行添加newId,可以尝试
Insert into table1(id,name,gold)
Select (select max(m.id) from table1 m) + row_number() over (order by t2.id) ,name,lvl from table2 t2
Where t2.name not in(select t1.name from table1 t1)
答案 1 :(得分:0)
可能是的,但我不推荐它。当基于集合的操作执行时,循环(基本上是游标所做的)通常不建议在SQL中使用。
在较高的层面上,您可能希望将两个表连接在一起(事实上,它们在不同的数据库中应该没有区别)。你提到一个表有重复。您可以通过多种方式消除这些问题,例如使用group by
或row_number
。这两种方法都需要您了解要“选择”哪些行以及要“忽略”哪些行。您还可以使用相关子查询执行另一个用户在评论中发布的内容,其中您使用相关子查询对目标表进行存在检查。这基本上意味着如果目标表中存在任何您想要插入重复项的行,那么这些重复项都不会被放入。
就游标而言,要做这样的事情,你将基本上做同样的事情,除了光标的每次传递,你将临时分配和使用变量而不是列。这种方法有时称为RBAR(针对“通过Agonizing Row的Rob”)。在光标或循环的每次传递中,它必须重新打开表,找出它需要的数据,然后对其进行操作。即使这是有效的并且它只撤回一行,执行该查询仍然有很多开销。所以,虽然,是的,你可以强迫SQL做你所描述的,数据库引擎已经有了这个(连接)的操作,这比你可以想象的任何循环快得多