从SELECT INSERT INTO:INSERT语句的选择列表包含的项目多于插入列表

时间:2014-07-22 14:10:11

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

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

  

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 目的,因为我将其用于函数(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

3 个答案:

答案 0 :(得分: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

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

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

答案 1 :(得分:0)

从表面上看,您可能会触发查询计划程序错误或其他内容。有许多 iffy 正在进行中:

  • 同一个表的联合所有给自己
  • 同时使用分组分明

我不确定你的意思

  

Top 999仅供参考,因为我将它用于函数(UDF)。

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

答案 2 :(得分:0)

你专注于错误的插入。这是不匹配的那个:

    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 
          ...

插入列表中的两列,子选择中的3列。我不能仅仅通过命名来说明POR_C是否意味着最终会出现在Ord列中。