Fixing sql length error in progress 4gl 10.2B

心已入冬 提交于 2019-12-11 02:51:38

问题


I'm trying to use the openedge jdbc connector to pull data from an existing progress db but im running into column width issues.

Here is the error that is holding me up.

[DataDirect][OpenEdge JDBC Driver][OpenEdge] Column TabDisplayName in table PUB.Menu has value exceeding its max length or precision.

I've looked at many posts, each offering different advice, and here's what I've given a go this far:

  1. Manually modify the SQL width via the data dictionary.
    • I ran a quick check on PUB.Menu.TabDisplayName to find a max value of 44 Characters
    • Set the width to x(50) to no avail and then x(100) out of a fix of irrational rage, again with no luck.
  2. Use the SUBSTR() SQL Function to truncate the field -not optimum but better than nothing
    • I get weird results with this. It works fine in sqlexp but in a java environment its like the column is never selected.
  3. Use the dbtool to automatically fix width problems with option #2
    • After selecting all tables and "areas" (not sure what those are...) and submitting the final option I am returned to the proenv cmdline as if nothing ever happened.
  4. Modify the sql width programmatically via 4gl
    • This is the only option I found that I have yet to try.
    • I am a little reluctant to try this only because a manual modification failed. Also this is a live development environment(for me only) and Im trying to mess it up too terribly, although i am taking snaps regularly.

Running progress 10.2B on a unix machine.

Any comments and suggestions would be appreciated.

-Thanks


回答1:


The dbtool option is the best. It is designed for this. From proenv you should see something like this:

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=single-user 1=self-service >1=#threads)? 1

Padding % above current max: 100

: (Table number or all)? all

: (Area number or all)? all

: (verbose level 0-3)? 0

Total records read: 31357

SQLWidth errors found: 0, Date errors found: 0

SQLWidth errors fixed: 0

If your db has a server up & running choose "1" at the connect: prompt. If not, choose "0".

Pick 100 for padding to double the width of fields.

Try it on a copy of the "sports" database if you are unsure. Use a higher level of verboseness if you want some insight into what it is doing.

It does not take very long to run on a small development database. (It is basically instantaneous on "sports".)




回答2:


It is possible to create views with substring (field.name,1,maxlength) option and use PUB2.viewname instead 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;

use sqlexp for automatic creation: sqlexp account -H localhost -S ' + db-port + ' -user sysprogress -password sysprogress -infile recreateSQLviews.sql -outfile recreateSQLviews.log

here is code:

    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.


来源:https://stackoverflow.com/questions/11998342/fixing-sql-length-error-in-progress-4gl-10-2b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!