【问题标题】:Fixing sql length error in progress 4gl 10.2B正在修复 sql 长度错误 4gl 10.2B
【发布时间】:2012-08-13 11:05:52
【问题描述】:

我正在尝试使用 opensge jdbc 连接器从现有进度数据库中提取数据,但我遇到了列宽问题。

这是阻碍我的错误。

[DataDirect][OpenEdge JDBC Driver][OpenEdge] PUB.Menu 表中的 TabDisplayName 列的值超过了其最大长度或精度。

我查看了很多帖子,每个帖子都提供了不同的建议,以下是我迄今为止尝试过的:

  1. 通过数据字典手动修改 SQL 宽度。
    • 我对 PUB.Menu.TabDisplayName 进行了快速检查,发现最大值为 44 个字符
    • 将宽度设置为 x(50) 无济于事,然后将 x(100) 设置为非理性愤怒,再次失败。
  2. 使用 SUBSTR() SQL 函数截断字段-不是最佳但总比没有好
    • 我得到了奇怪的结果。它在 sqlexp 中运行良好,但在 java 环境中,它就像从未选择过的列一样。
  3. 使用 dbtool 自动修复选项 #2 的宽度问题
    • 选择所有表和“区域”(不确定它们是什么...)并提交最终选项后,我将返回到 proenv cmdline,就好像什么都没发生过一样。
  4. 通过 4gl 以编程方式修改 sql 宽度
    • 这是我发现我尚未尝试的唯一选项。
    • 我有点不愿意尝试这个,只是因为手动修改失败。此外,这是一个实时开发环境(仅对我而言),尽管我会定期拍摄快照,但我试图把它搞得一团糟。

在 unix 机器上运行进度 10.2B。

我们将不胜感激。

-谢谢

【问题讨论】:

  • 如果您担心弄乱您的开发数据库,​​最好的办法是使用旧数据库的模式和一些数据创建一个测试数据库,“以防万一”制作备份副本,然后然后使用它的模式,看看有什么用。
  • “区域”是表和/或索引的集合。它有点像 oracle 的“表空间”。
  • @tombascom 很高兴知道以供将来参考。我不是一个很有经验的开发人员,也绝对不是数据库专家,所以请原谅我的无知。
  • @timkuehn 因为它在 vm 机器上运行会在关闭数据库后对机器进行快照,而不是以同样的方式保护我?
  • 仅当图像包含硬盘内容时。这比制作数据库的测试副本并用测试数据填充它需要更长的时间。

标签: jdbc progress-4gl openedge progress-db


【解决方案1】:

dbtool 选项是最好的。它就是为此而设计的。在 proenv 中,您应该会看到如下内容:

proenv> dbtool s2k

       DATABASE TOOLS MENU - 10.2B
       ---------------------------

  1. SQL Width & Date Scan w/Report Option
  2. SQL Width Scan w/Fix Option
  3. Record Validation
  4. Record Version Validation
  5. Read or Validate Database Block(s)
  6. Record Fixup
  7. Schema Validation
  9. Enable/Disable File Logging
          Q. Quit

  Choice: 2

: (0=单用户 1=自助服务 >1=#threads)? 1

高于当前最大值的填充百分比:100

:(表号还是全部)?全部

:(区号还是全部)?全部

:(详细级别 0-3)? 0

读取的总记录数:31357

发现 SQLWidth 错误:0,发现日期错误:0

已修复 SQLWidth 错误:0

如果您的数据库已启动并运行服务器,请在 connect: 提示符处选择“1”。如果不是,请选择“0”。

选择 100 进行填充以使字段宽度加倍。

如果您不确定,请在“体育”数据库的副本上尝试。如果您想深入了解它在做什么,请使用更高级别的详细信息。

在小型开发数据库上运行不需要很长时间。 (在“运动”上基本上是瞬时的。)

【讨论】:

  • 谢谢!我以前使用过 dbtool,但使用不正确。我从未将密码更改为我的数据库所在的位置。
【解决方案2】:

可以使用 substring (field.name,1,maxlength) 选项创建视图并使用 PUB2.viewname 代替 pub.tablename

    DROP VIEW PUB2."accounts";
    CREATE VIEW PUB2."accounts" ( 
    "ACC-TYPE",
    "ACCOUNT-NAME",
    ANALITIC,
    ARCH,
    COUNT1,
    CURRENCY,
    PLAN,
    QUANTITY,
    "RID-ANOBJECT",
    "RID-APP",
    TRANSIT ) 
    AS select "acc-type",
    SUBSTRING("account-name", 1, 130),
    "analitic",
    "arch",
    "count1",
    "currency",
    "plan",
    "quantity",
    "rid-anobject",
    "rid-app",
    "transit"
    FROM PUB."accounts";
    COMMIT;

使用 sqlexp 进行自动创建: sqlexp account -H localhost -S ' + db-port + ' -user sysprogress -password sysprogress -infile recreateSQLviews.sql -outfile recreateSQLviews.log

代码如下:

    def var num-port as integer.
    for first _Servers where _Servers._Server-Type = "Login" no-lock:
        num-port = _Servers._Server-PortNum.
    end.
    if num-port < 0 then num-port = num-port + 65536.
    if num-port = 0 then do:
       message "Define -S parameter for Database" view-as alert-box.
       RETURN.
    end.
    message num-port.

    /* ttSQLWidth table: SQL WIDTH for all tables */

    def var execstr as char.
    def var rez-str as char.
    def var db-port as char. /* -S port */
    db-port = STRING(num-port).

    DEFINE TEMP-TABLE ttSQLWidth NO-UNDO
        FIELD tableName   AS CHARACTER
        FIELD tableNum    AS INTEGER
        FIELD fieldName   AS CHARACTER
        FIELD sqlWidth    AS INTEGER
        FIELD requireFix  AS LOGICAL INIT FALSE
        FIELD actualWidth AS INTEGER
        FIELD newWidth    AS INTEGER
    INDEX tableNum  tableNum
    INDEX tableName tableName.

    FOR EACH _File NO-LOCK WHERE _Tbl-Type = "T":
        FOR EACH _Field OF _File WHERE _Field._Data-type = "character":
            if _field._extent > 0 then next.
            CREATE ttSQLWidth.
            ASSIGN tableName = _File._File-name
                tableNum = _File._File-num
        fieldName = _Field._Field-name
        sqlWidth = _Field._Width.
        RELEASE ttSQLWidth.
        END. /* FOR EACH _Field */
    END. /* FOR EACH _File */

    DEFINE VARIABLE bTab        AS HANDLE      NO-UNDO.
    DEFINE VARIABLE hQuery      AS HANDLE      NO-UNDO.
    DEFINE VARIABLE queryString AS CHARACTER   NO-UNDO.

    FOR EACH ttSQLWidth:
        CREATE BUFFER bTab FOR TABLE tableName.
        CREATE QUERY hQuery.
        hQuery:ADD-BUFFER(bTab).

        message tablename.
        queryString = "FOR EACH " + tableName + " WHERE LENGTH(" + fieldName + ") >= " + STRING(sqlWidth) + " BY LENGTH(" + fieldName + ") DESC".
        hQuery:QUERY-PREPARE(queryString).
        hQuery:QUERY-OPEN().

        IF hQuery:GET-NEXT() THEN DO:
            ASSIGN actualWidth = LENGTH(bTab:BUFFER-FIELD(fieldName):BUFFER-VALUE)
                   requireFix = TRUE.
        END. /* IF .. THEN DO */

        hQuery:QUERY-CLOSE.
        DELETE OBJECT hQuery.

        bTab:BUFFER-RELEASE().
        DELETE OBJECT bTab.

    END. /* FOR EACH ttSQLWidth */

    def var add-pr   as integer initial 10.  /* % from max */
    def var maxWidth as integer initial 249. /* maxwidth */

    FOR EACH ttSQLWidth WHERE ttSQLWidth.requireFix = TRUE:

        ttSQLWidth.newWidth = TRUNCATE ( (ttSQLWidth.actualWidth + add-pr) / add-pr, 0 ) * add-pr.
        ttSQLWidth.newWidth = INTEGER( ttSQLWidth.newWidth).
        if ttSQLWidth.newWidth > maxWidth then ttSQLWidth.newWidth = maxWidth.

    END.

    /* sql script generation */ 

    OUTPUT TO value("recreateSQLviews.sql").
    def var lst-field as char.
    FOR EACH ttSQLWidth WHERE BREAK BY ttSQLWidth.tableName:
       IF FIRST-OF(ttSQLWidth.tableName) 
          THEN run MakeSQLViews(ttSQLWidth.tableName).

    END.
    OUTPUT CLOSE. 

    /* sql script execution */

    execstr = 'sqlexp account -H localhost -S ' + db-port + ' -user sysprogress -password sysprogress -infile recreateSQLviews.sql -outfile recreateSQLviews.log'.

    input through value(execstr).
    repeat:
      IMPORT UNFORMAT rez-str.
      message rez-str.
    end.
    INPUT CLOSE.

    RETURN.

    PROCEDURE MakeSQLViews:
    define input parameter tableName as character.

    def var str_tmp as char.
    def var str_tmp1 as char.
    def var str as char initial "count,sum,double,row,date,level,area,number,primary".

    def var fieldName  as char.
    def var fieldName1 as char.

    FOR EACH _file WHERE _file._file-name = tableName AND 
                         _file._file-num GT 0 AND _file._file-num LT 32000 NO-LOCK:   
       fieldName = "".    
       FOR EACH _Field OF _File NO-LOCK:            

              str_tmp = '"' + _Field._Field-name + '"'.
              FOR FIRST ttSQLWidth where ttSQLWidth.tableName = _file._file-name   and 
                                         ttSQLWidth.fieldName = _Field._Field-name and 
                                         ttSQLWidth.requireFix = TRUE:
                  str_tmp = 'SUBSTRING("' + _Field._Field-name + '", 1, ' + STRING(ttSQLWidth.newWidth) + ')'. 
              END.
              fieldName  = fieldName + (IF(fieldName = "") THEN ("") ELSE ("," + chr(10) + chr(9))) + str_tmp.    
              str_tmp1   = ( IF ( INDEX ( _Field._Field-name, "-" ) = 0 ) 
                                THEN ( _Field._Field-name ) 
                                ELSE ( '"' + _Field._Field-name + '"' )).

              if LOOKUP ( _Field._Field-name, str, "," ) > 0 then str_tmp1 = '"' + _Field._Field-name + '"'.

              fieldName1 = fieldName1 + (IF(fieldName1 = "") THEN ("") ELSE ("," + chr(10) + chr(9))) + UPPER(str_tmp1). 

       END. /* FOR EACH _Field */    

       PUT UNFORMATTED 'DROP VIEW PUB2."' + _file._file-name + '";' SKIP.     
       PUT UNFORMATTED 'CREATE VIEW PUB2."' + _file._file-name + '" ( ' + chr(10) chr(9) + fieldName1 +  ' ) ' + chr(10) + 
           'AS select ' + fieldName + chr(10) + 
           'FROM PUB."' + _file._file-name + '";' SKIP.     
       PUT UNFORMATTED 'COMMIT;' SKIP(1). 
    END.

    END.

【讨论】:

    猜你喜欢
    • 2014-03-31
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多