【问题标题】:SQLRPGLE. Is there something wrong with my SQL Query?SQLRPGLE。我的 SQL 查询有问题吗?
【发布时间】:2021-06-02 10:30:48
【问题描述】:

这是我试图在我的程序中运行的 SQL 查询。但是我什至无法编译它,我收到一个错误,只是告诉我查询中有问题。

我得到的错误是“SQL0117 语句包含错误数量的值”。

/Free                                                        
   exec sql                                                  
   INSERT INTO NOEDTSR                                       
        SELECT * FROM NOEDEH AS deh                          
        WHERE EXISTS (SELECT act.AC2ACT FROM ACTEST AS act   
                              WHERE  act.AC2ACT = deh.N1ACTE 
                              AND    act.AC2CRB IN('C0','C2')
                              AND    act.AC2TYT = 'DEN')     
        AND   NOT EXISTS (SELECT sin.SISTE FROM SINREG AS sin
                              WHERE  sin.SISTE  = deh.N1STE  
                              AND    sin.SIGRP  = deh.N1GRP
                              AND    sin.SIIND  = deh.N1IND   
                              AND    sin.SIRANG = deh.N1RANG  
                              AND    sin.SIACTE = deh.N1ACTE  
                              AND    sin.SIREEL = deh.N1MERG  
                              AND    sin.SISECU = deh.N1EBAS) 
         AND N1DBSS = 20                                       
         AND N1DBSA = 21                                       
         AND N1TIER = '000000000000000';                       
 /end-free                                                       

我不是故意在此处指定 column_names,因为我想将所有列从 NOEDEH 复制到 NOEDTSR
这两个表的结构相同,用于编译两者的DDS(Data Description Structure)完全相同。

有什么想法吗?

【问题讨论】:

  • 您声称查询返回与目标表相同的列是错误的。这就是错误所说的。明确列出列。
  • 可能这两个表没有相同的列。明确列名以避免此类问题始终是一种好习惯。
  • 您需要明确指定所有插入的列,因为可以以任何方式重新组织表(添加新列,或者可以使用新列顺序重新创建,或者可以被另一个对象替换)并且没有人可以保证你的列顺序。
  • 感谢您的回答,我知道指定列很重要,但是在这种情况下,表有 107 个列,我试图找到解决方法。我尝试使用带有 qsys2.syscolumns2 的另一个程序列出列,但我不能在我的 INSERT 语句中使用 RPG 变量...
  • 以下查询的结果是什么? SELECT TABLE_SCHEMA, TABLE_NAME, COUNT(1) CNT , LISTAGG (COLUMN_NAME, ', ') AS COLS FROM QSYS2.SYSCOLUMNS WHERE TABLE_SCHEMA = 'YOUR_SCHEMA' AND TABLE_NAME IN ('NOEDEH', 'NOEDTSR') GROUP BY TABLE_SCHEMA, TABLE_NAME。相应地设置您的架构名称。您可以注释掉最后一列,在该列中您会得到一个以逗号分隔的所有表列的列表,并可用于构造您的 INSERT SELECT 查询。

标签: sql db2 rpgle


【解决方案1】:

您已经弄清楚了您的问题。 Mark 提供了一个简单的 SQL 来轻松生成包含列列表的字符串。

这是我随身携带的一条 SQL 语句。它将允许您生成以下内容之一:

  • 短列名的字符串
  • 长列名称的字符串
  • 使用短名称的 rpg 数据结构
  • 使用长名称的 rpg 数据结构

只需取消注释语句底部相应的 select * 行即可。

with selected (system_table_name, system_table_schema) 
     --  enter file & library name here
  as (values ('MYTABLE','MYLIB') )
, tbl as (
select 
        case
           when data_type = 'DECIMAL' then 'packed'
           when data_type = 'NUMERIC' then 'zoned'
           when data_type = 'TIMESTMP' then 'timestamp'
           when data_type = 'INTEGER' then 'int'
           else lower(data_type)  
         end
        concat case
                 when data_type = 'INTEGER' and length >= 8 then '(20'
                 when data_type = 'INTEGER' and length >= 4 then '(10'
                 when data_type = 'INTEGER' and length >= 2 then '(5'
                 when data_type in ('TIMESTMP','DATE','TIME') then '' 
                 else '(' concat length
               end
        concat case 
                 when numeric_scale is null then ''
                 when data_type = 'INTEGER' then ''
                 else ':' concat numeric_scale
               end
        concat case
                 when data_type in ('TIMESTMP','DATE','TIME') then ';'   
                 else ');' 
               end 
        as rpg_type 
,system_column_name, length, numeric_scale,
column_text, column_name, ordinal_position
from qsys2.syscolumns syscolumns
 join selected using(system_table_name,system_table_schema)
)
-- build RPG DS
, rpg_ds as (
 select lower(system_column_name) concat ' ' concat rpg_type as rpg_ds_subfield
   from tbl
 order by ordinal_position
)
-- build rpg long name ds
, rpg_ds_long_name as (
 select lower(column_name) concat ' ' concat rpg_type as rpg_ds_subfield
   from tbl
 order by ordinal_position
)
---- build a string of all columns in the table using short names
, list_short_names as (
select listagg(lower(trim(system_column_name)),', ') 
    within group (order by ordinal_position)
from tbl
)
---- build a string of all columns in the table using short names
, list_long_names as (
select listagg(lower(trim(column_name)),', ') 
    within group (order by ordinal_position)
from tbl
)
-- use one of these depending on what you're looking for
--select * from rpg_ds_long_name;
--select * from rpg_ds;
--select * from list_long_names;
select * from list_short_names;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多