【问题标题】:Using db2 on iSeries, issue with SQL insert into from () where () not in ()在 iSeries 上使用 db2,SQL insert into from () where () not in () 出现问题
【发布时间】:2017-08-23 17:57:29
【问题描述】:

我需要跨多个库/表构建键索引。已经为单字段索引做了很多次,但是在尝试使用多个字段创建基本相同的东西时遇到了困难。

在下面的所有示例中,我都进行了缩写以显示所有方面,但元素列表要少得多,以便更容易理解。如果我犯了任何重命名错误,我们深表歉意。

这是一个在计划作业中每晚运行的有效查询示例:

    INSERT INTO LIBMAST.TABL_X1
    (SELECT DISTINCT T1.FIELD1 FROM 
        (SELECT DISTINCT T1.FIELD1 FROM LIB1NAME.TABL T1 
         UNION ALL
         SELECT DISTINCT T1.FIELD1 FROM LIB2NAME.TABL T1 ) T1 
     WHERE T1.FIELD1 NOT IN (SELECT T1.FIELD1 FROM LIBMAST.TABL_X1) ) ;

这是我的插入查询的测试版本,作为选择语句来显示应该导入哪些记录。这很好用,显示了它应该做什么。

    SELECT T2.* FROM 
    (SELECT DISTINCT  'PA' AS FIELD1, T1.NAME2 AS FIELD2, T1.NAME3 AS FIELD3, T1.NAME4 AS FIELD4, T1.NAME5L AS FIELD5 FROM 
        (SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB1NAME.TABL T1 
         UNION ALL
         SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB2NAME.TABL T1  ) T1
    ) T2
       WHERE (T2.FIELD1, T2.FIELD2, T2.FIELD3, T2.FIELD4, T2.FIELD5) NOT IN 
      (SELECT T3.FIELD1, T3.FIELD2, T3.FIELD3, T3.FIELD4, T3.FIELD5 FROM LIBMAST.TABLKEYS T3) ;

这是无效的插入语句。只有第一行代码发生了变化。

    INSERT INTO LIBMAST.TABLKEYS  
    (SELECT DISTINCT  'PA' AS FIELD1, T1.NAME2 AS FIELD2, T1.NAME3 AS FIELD3, T1.NAME4 AS FIELD4, T1.NAME5L AS FIELD5 FROM 
        (SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB1NAME.TABL T1 
         UNION ALL
         SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB2NAME.TABL T1  ) T1
    ) T2
       WHERE (T2.FIELD1, T2.FIELD2, T2.FIELD3, T2.FIELD4, T2.FIELD5) NOT IN 
      (SELECT T3.FIELD1, T3.FIELD2, T3.FIELD3, T3.FIELD4, T3.FIELD5 FROM LIBMAST.TABLKEYS T3) ;

这是我收到的错误消息的第一部分:

SQL 状态:42601 供应商代码:-104 消息:[SQL0104] 令牌 T2 无效。有效令牌:用于使用 SKIP WAIT WITH FETCH LIMIT ORDER UNION EXCEPT OFFSET。原因 。 . . . . : 在令牌 T2 处检测到语法错误。令牌 T2 不是有效令牌。有效令牌的部分列表是 FOR USE SKIP WAIT WITH FETCH LIMIT ORDER UNION EXCEPT OFFSET。此列表假定该语句在令牌之前是正确的

我看不出语法有什么不同,但显然我遗漏了一些东西。

【问题讨论】:

    标签: sql db2 db2-400


    【解决方案1】:

    您删除了SELECT 并将其替换为INSERT....您需要离开SELECT

    INSERT INTO LIBMAST.TABLKEYS
    SELECT T2.* FROM 
        (SELECT DISTINCT  'PA' AS FIELD1, T1.NAME2 AS FIELD2, T1.NAME3 AS FIELD3, T1.NAME4 AS FIELD4, T1.NAME5L AS FIELD5 FROM 
            (SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB1NAME.TABL T1 
             UNION ALL
             SELECT DISTINCT T1.NAME2, T1.NAME3, T1.NAME4, T1.NAME5 FROM LIB2NAME.TABL T1  ) T1
        ) T2
           WHERE (T2.FIELD1, T2.FIELD2, T2.FIELD3, T2.FIELD4, T2.FIELD5) NOT IN 
          (SELECT T3.FIELD1, T3.FIELD2, T3.FIELD3, T3.FIELD4, T3.FIELD5 FROM LIBMAST.TABLKEYS T3) ;
    

    编辑
    关于第一个查询的“我不需要额外的选择包装器”。

    语句的语法总是INSERT INTO table1 SELECT FROM <...>

    您的第一个简化语句是:

    INSERT INTO LIBMAST.TABL_X1
        SELECT DISTINCT T1.FIELD1 FROM <...> T1
    

    您的第二个选择简化为:

    SELECT T2.* FROM <...> T2
    

    这就是您打算插入另一个表的结果集。因此:

    INSERT INTO LIBMAST.TABLKEYS
      SELECT T2.* FROM <...> T2
    

    如果选择只返回 5 列而 TABLKEYS 有 10 列,则需要指定 5 列的值,如下所示:

    INSERT INTO LIBMAST.TABLKEYS (field1, field2, field3, field4, field5)
      SELECT T2.* FROM <...> T2
    

    【讨论】:

    • 感谢您的回复。我可以尝试,但也请查看当前正在运行的第一个示例。我不需要该查询中的额外选择包装器。
    • 添加额外的 [select t2.* from ] 给了我一个不同的错误。 “语句包含错误数量的值。”
    • 除非在插入表中包含显式列表,否则 select 语句必须为要插入的表中的每一列返回一个值。
    • 因为这是现有记录中的键列表,在键表中不存在,所以每个要插入的字段中总会有值。
    • 看起来您的选择返回 5 个字段...LIBMAST.TABLKEYS 中有多少个字段?
    猜你喜欢
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多