【问题标题】:insert table1 select from table2,table3 where插入表 1 从表 2、表 3 中选择
【发布时间】:2015-03-27 15:14:34
【问题描述】:

我在 Windows 7 上使用 SQL Server 2008 R2,我正在尝试填充表中缺失的行。对于背景,我有

  • 一组“参数”,它们都有一个(字符串)值。这些参数大约有200个

  • 我需要为每个参数设置一个值的一组“上下文”。有很多这样的上下文。

我在数据库中使用三个这样的表对此进行建模:

[Parameter] (
    [ID] int not null,
    [DefaultValue] varchar(100) not null
)

[Context] (
    [ID] int not null
)

[ParameterValues] (
    [ID] int IDENTITY(1,1) not null,
    [ParameterID] int not null,
    [ContextID] int not null,
    [Value] varchar(100) not null
)

因此,对于上下文和参数的每个组合,参数值表中都应该有一行。因此,对于 200 个参数和 10 个上下文,我应该期望 ParameterValues 表中有 200x10 = 2000 行。

由于历史原因,我们在某些上下文中缺少一些参数值,我想在 ParameterValues 表中填写所有缺少的值。

我正在尝试使用以下查询:

insert [ParameterValues]
  select [Parameter].[ID], [Context].[ID], [Parameter].[DefaultValue]
    from [Parameter],[Context]
     where not exists 
      (select 1 from [ParameterValues]
                where [ParameterValues].[ContextID] = [Context].[ID] 
                  and [ParameterValues].[ParameterID] = [Parameter.[ID])

我不断收到以下错误:

子查询返回超过 1 个值。这是不允许的,当 子查询遵循 =、!=、、>= 或当子查询用作 一个表达式。

我想我只是不理解插入...选择语法等的限制。任何关于正确处理的建议将不胜感激。

更新:

如果我只是运行“select ... from ... where not exists...”,那么我会显示正确的行数(我知道每个上下文中缺少多少行)。我检查了这些行,它们似乎具有正确的值并且没有重复。

如果我在临时表中进行选择,它可以正常工作,并且我会在该临时表中获得预期的内容。但我不能这样做:

insert [ParameterValues] select * from #temptable

因为这给了我同样的错误。因此,我的参数值表中的结构或 FK 中必须有一些东西破坏了这一点。

使用 SSMS,我可以将这些行直接复制并粘贴到目标表中并且不会出现错误,因此这些行中的值看起来很好,并且不会破坏任何 FK 等。我刚刚再次检查,没有触发器或此数据库中的 SP,FK 关系看起来还不错。

在过去的几个小时里,我已经绕着房子转了几个小时,这让我发疯了。在短期内,我有我需要使用的数据,但我将不得不在数据库的其他副本上重复这个过程,并且希望通过脚本等以标准的可重复方式来完成它,而不是手动破解。 ..

【问题讨论】:

  • 你不应该使用隐式连接,你遇到麻烦的一个原因是因为你没有正确加入这里,所以你有一个意外的交叉连接。使用隐式连接非常糟糕。在 21 世纪的代码中使用它们是不负责任的,因为它们在上个世纪被替换了。
  • 请解释一下。与其只是批评,不如尝试给出一个可能有帮助的好解决方案。

标签: sql sql-server sql-server-2008 insert-select


【解决方案1】:

你可以这样做:

insert into ParameterValues (ParameterID, ContextID, Value)
select P.ID, C.ID, P.DefaultValue
from Parameter as P, Context as C
where not exists 
      (select top 1 * from ParameterValues as PV
       where PV.ContextID = C.ID and PV.ParameterID = P.ID)

更新

坦率地说,您的原始查询也应该可以工作(尽管从我的角度来看,使用表别名的查询看起来更优雅,并且明确指定要插入的列名总是更好)。经过一番思考,我找不到您的查询引发此类异常的原因。

您确定您已经提供了您遇到问题的实际查询吗?

【讨论】:

  • 最初我以为是因为他没有在插入时指定列,但在运行他的查询后,它也对我有用。
  • 感谢您的意见。查询简化的,表结构也是如此。完整的表每个都有另外 5-10 列,查询有点混乱。刚刚在一个虚拟数据库中再次尝试了同样的方法,如果我不定义外键等它就可以工作。所以我可能有一些线索......
  • 使用隐式连接是一种 SQL 反模式。
猜你喜欢
  • 2020-10-01
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 2014-03-12
  • 2012-11-03
  • 2016-05-06
相关资源
最近更新 更多