【问题标题】:INSERT INTO from SELECT: The select list for the INSERT statement contains more items than the insert listINSERT INTO from SELECT:INSERT 语句的选择列表包含的项目多于插入列表
【发布时间】:2014-07-22 14:10:10
【问题描述】:

我仍然收到一个奇怪的错误:

INSERT 语句的选择列表包含比插入列表更多的项目。 SELECT 值的数量必须与 INSERT 列的数量相匹配。

代码:

    INSERT INTO @tab (Phone)
    select t2.Phone 
    from 
    (
      SELECT DISTINCT top 999 t3.Phone, MIN(t3.Ord) 
      FROM 
      (
        select Phone1 as Phone, Ord from @tabTemp
        union all
        select Phone2 as Phone, Ord from @tabTemp
      ) t3 
      GROUP BY t3.Phone 
      ORDER BY MIN(t3.Ord) asc, t3.Phone
    ) t2

这个想法是从@tabTemp 中选择所有电话号码及其行顺序。然后我想区分它们并将不同的数字插入表@tab。 Top 999 仅用于 order by 目的,因为我将它用于 function (UDF)。

结构如下:

    declare @tabTemp TABLE 
    (
    Phone1 varchar(128) NULL,
    Phone2 varchar(128) NULL,
    Ord int
    );

    declate @tab TABLE 
    (
    Phone varchar(max) NULL
    );

已编辑:

完整代码

    CREATE FUNCTION dbo.myFnc(@PID int, @VID int, @JID int, @ColumnNo int)
      RETURNS @tab TABLE 
      (
          Phone varchar(max) NULL
      )
      AS 
      BEGIN
        if @PID is null and @VID is null and @JID is null 
          return;

        if @ColumnNo is null or (@ColumnNo<>2 and @ColumnNo<>3 and @ColumnNo<>6)
          return;

        declare @catH int;
        set @catH = dbo.fncGetCategoryID('H','tt');   -- just returning int value       
        declare @kvalP int;
        set @kvalP = dbo.fncGetCategoryID('P','te');          
        declare @kvalR int;
        set @kvalR = dbo.fncGetCategoryID('R','te');

        declare @tabTemp TABLE 
        (
          Phone1 varchar(128) NULL,
          Phone2 varchar(128) NULL,
          Ord int
        );

        -- finding parent subject + current one
        WITH subj AS(
                SELECT  *
                FROM    Subjekt
                WHERE   
                  (ID = @PID and @PID is not null)
                  or
                  (ID = @VID and @VID is not null)
                  or
                  (ID = @JID and @JID is not null)            
                UNION ALL
                SELECT  t.*
                FROM    Subjekt t 
                      INNER JOIN subj r ON r.ID = t.ID
        )

        INSERT INTO @tabTemp (Phone1,Phone2)
          (select 
              (case when o.TYP1=@catH then o.TEL1 else null end) Phone1
              ,(case when o.TYP2=@catH then o.TEL2 else null end) Phone2
              ,so.POR_C
          from 
              subj s
              ,SubjektPerson so
              ,Persons o
              ,recSetup idS              
              ,recSetup idSO
              ,recSetup idO            
          where 1=1
              and idO.isValid=1
              and idSO.isValid=1
              and idS.isValid=1
              and idSO.ID0=so.ID
              and idS.ID0=s.ID
              and idO.ID0=o.ID

              and so.ID_PERSON=o.ID
              and so.ID_SUBJECT=s.ID

              and (o.TYP=@kvalP or o.TYP=@kvalR)

          ) 

          INSERT INTO @tab (Phone)
              select t2.Phone 
              from 
              (
                SELECT DISTINCT top 999 t3.Phone, MIN(t3.Ord) 
                FROM 
                (
                  select Phone1 as Phone, Ord from @tabTemp
                  union all
                  select Phone2 as Phone, Ord from @tabTemp
                ) t3 
                GROUP BY t3.Phone 
                ORDER BY MIN(t3.Ord) asc, t3.Phone
              ) t2

        RETURN
      END

【问题讨论】:

  • 你的桌子上有触发器吗?
  • @podiluska 这些是表变量,因此任何触发器都不在这些变量上。
  • @SeanLange 或者这可能只是一个例子,而不是真正的表格......
  • 它们只是表变量。所以没有触发器。

标签: sql sql-server sql-insert insert-into


【解决方案1】:

不知道为什么您在同一个查询中具有不同的 AND 分组依据。你可以大大简化这个。

INSERT INTO @tab (Phone)
SELECT top 999 t3.Phone
FROM 
(
    select Phone1 as Phone, Ord from @tabTemp
    union all
    select Phone2 as Phone, Ord from @tabTemp
) t3 
GROUP BY t3.Phone 
ORDER BY MIN(t3.Ord) asc, t3.Phone

现在对于您收到的错误消息,它似乎不是来自此代码块,因为语法很好并且列数正确匹配。我怀疑该错误在您的代码中较早的地方。

此外,您可能需要考虑使用临时表而不是表变量,因为这些表中似乎有很多行。

【讨论】:

    【解决方案2】:

    您专注于错误的插入。这是不匹配的:

        INSERT INTO @tabTemp (Phone1,Phone2)
          (select 
              (case when o.TYP1=@catH then o.TEL1 else null end) Phone1
              ,(case when o.TYP2=@catH then o.TEL2 else null end) Phone2
              ,so.POR_C
          from 
              ...
    

    插入列表中的两列,子选择中的三列。我无法仅从命名中判断 POR_C 是否打算在 Ord 列中结束。

    【讨论】:

      【解决方案3】:

      从表面上看,您可能正在触发查询计划程序错误或其他问题。有很多 iffy 事情正在发生:

      • 同一张表的联合到自身
      • 同时使用 group bydistinct

      我不知道你的意思是什么

      Top 999 仅用于按目的排序,因为我将其用于函数 (UDF)。

      您的意思是整个查询都在 UDF 中执行吗?如果是这样,是否有其他查询可能会给出该错误?

      【讨论】:

      • Union all 在这里是因为将两个不同的列(Phone1 和 Phone1)选择到单独的行中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多