【问题标题】:Trying to use cursor on one database using select from another db尝试在一个数据库上使用从另一个数据库中选择的游标
【发布时间】:2017-08-09 22:53:38
【问题描述】:

所以我试图将我的头绕在光标周围。我的任务是将数据从一个数据库传输到另一个数据库,但它们的架构略有不同。假设我有 TableOne(Id、Name、Gold)和 TableTwo(Id、Name、Lvl)。我想从 TableTwo 中取出所有记录并将其插入 TableOne,但它可以是 Name 列上的重复数据。因此,如果 TableOne 中存在来自 TableTwo 的单个记录(在名称列比较中),我想跳过它,如果不存在 - 在 TableOne 中创建具有唯一 ID 的记录。

我正在考虑对 TableTwo 中的每条记录进行循环,并为每条记录检查它是否存在于 TableOne 中。那么,如何在不每次都调用另一个数据库的情况下进行此检查?我想首先从 TableOne 中选择所有记录,将其保存到变量中,然后在循环本身中检查这个变量。这在 SQL 中甚至可能吗?我对SQL不太熟悉,一些代码示例会很有帮助。

如果这很重要,我正在使用 Microsoft SQL Server Management Studio。当然,TableOne 和 TableTwo 存在于不同的数据库中。

【问题讨论】:

  • 我认为您的意思是“光标”。话虽如此,大多数操作通常不需要游标。绝对不适合这个操作。您只需要编写一个删除重复项的选择语句,然后将这些结果插入到目标表中。在一个 SQL 语句中,没有循环。此数据库是否在同一个 SQL Server 上?
  • 是的,但它并不是那么简单,因为我会丢失数据以及删除的记录。我展示了非常简化的表格,实际上它们看起来像 T1(Id,Name,Color,Level,Money,Customer,AnotherRealtedData)T2(Id,Name,Color,DataForTable3,DataForTable4)。我要执行的操作将针对几个表完成。
  • 根据您的解释,这很简单。您需要弄清楚比较字段是什么,然后使用select * from sourcedb..sourcetable where not exists (select * from targetdb..targettable where targettable.joinkey = sourcetable.joinkey)。然后它只会根据您的加入键选择不存在的记录

标签: sql sql-server tsql


【解决方案1】:

试试这个

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)

【讨论】:

    【解决方案2】:

    可能是的,但我不建议这样做。当基于集合的操作将执行时,循环(本质上是游标所做的)在 SQL 中通常是不可取的。

    在较高的级别上,您可能希望将两个表连接在一起(它们位于不同的数据库中这一事实不应该产生影响)。你提到一张桌子有重复。您可以通过多种方式消除它们,例如使用group byrow_number。这两种方法都需要您了解要“选择”哪些行以及要“忽略”哪些行。您还可以执行其他用户在评论中发布的操作,您可以使用相关子查询对目标表进行存在性检查。这实质上意味着,如果目标表中存在任何包含您尝试插入的重复项的行,则不会放入这些重复项。

    就游标而言,要执行这样的操作,您基本上会做同样的事情,除了在游标的每次传递中您将临时分配和使用变量而不是列。这种方法有时称为 RBAR(“Rob by Agonizing Row”)。在游标或循环的每一次通过时,它都必须重新打开表,找出它需要什么数据,然后对其进行操作。即使这是有效的并且它只是拉回一行,执行该查询仍然有很多开销。因此,虽然,是的,您可以强制 SQL 执行您所描述的操作,但数据库引擎已经对此(连接)进行了操作,它比您可以想象编写的任何循环都快得多

    【讨论】:

    • 我不认为连接是这里的解决方案。它不会只是创建另一个表,而不是将自定义值从一个表插入到另一个表吗?
    • 您谈到了在您的光标中设想的比较表之间的值,这几乎就是连接的目的。不过,我看到您已经得到了答案,使用子查询方法也同样有效。但是,如果您没有重复项,则连接也可以正常工作。
    猜你喜欢
    • 2020-03-09
    • 2019-12-02
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多