首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在没有参数的查询上获取SQLFetch返回代码1004 (右截断)

在没有参数的查询上获取SQLFetch返回代码1004 (右截断)
EN

Stack Overflow用户
提问于 2013-11-18 21:40:13
回答 2查看 2.9K关注 0票数 0

我客户公司的某人正在通过ODBC访问我的2012

他们的代码在COBOL中,我无法访问。但是,他说,如果他运行以下查询,SQLFetch将返回前几条记录,然后在我的数据库中得到一个正确的截断错误:

代码语言:javascript
复制
SELECT        labCodes.labCode, labCodes.description, labCodes.price, labCodes_localPrices.localPrice
FROM            labCodes LEFT OUTER JOIN
                     labCodes_localPrices ON labCodes.labCode = labCodes_localPrices.labCode

labCodes.description字段是唯一的字符串字段(它是varchar(80)),所以我让他尝试LEFT(labCodes.description,10),运行得很好,他实验并发现,如果他将它设置为左(labCodes.description,62),程序将运行良好,但在63岁时它仍然会死。有相当多的记录,是接近完整的80个字符,所以这是非最佳的。

由于没有where子句,我完全不明白他是如何得到截断错误的。

谢谢

编辑以添加cobol guy re的代码:@bohica的注释缓冲区为80个字符。

代码语言:javascript
复制
01 Sql-Data.
        03 q-Col                       PIC X(80) OCCURS 50.

我与SQL绑定。

代码语言:javascript
复制
PERFORM VARYING Perf-Count FROM 1 BY 1
             UNTIL Perf-Count > Num-Cols
             CALL ODBCAPI "SQLBindCol"
             USING BY VALUE hstmt
                   BY VALUE Perf-Count
                   BY VALUE SQL-C-CHAR SIZE 2
                   BY REFERENCE q-col(Perf-Count),
                   BY VALUE cbValueMax,
                   BY REFERENCE pcbValue
         IF Return-Code <> SQL-Success
           DISPLAY "SQLBindCol: " Return-Code
           PERFORM Get-Sql-Error
           MOVE Num-Cols TO Perf-Count
 END-IF
END-PERFORM

*第二版:

I尝试将varchar(80)更改为char(80),但没有任何效果。

我终于从他的COBOL应用程序中得到了实际的错误消息,下面是:

代码语言:javascript
复制
 * Accepted - CONFIRM
 SQLFetch: +0001
 SQLerror: +0000
 SQL-STATE is: 01004
 Message : [Microsoft][ODBC SQL Server Driver]String data, right truncation
 SQLExecDirect: -0001
 SQLerror: +0000
 SQL-STATE is: 24000
 Message : [Microsoft][ODBC Driver Manager] Invalid cursor state

第3版,也是最后一版

我得到了COBOL代码的副本,并注意到在执行过程中,cbVALUEMax的值被设置为63。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-19 11:51:06

如果您显示的是准确的错误文本,可能会有所帮助。假设客户端使用ODBC并发出了SQLFetch,则Server驱动程序返回的错误将被截断,这意味着客户端代码传递的缓冲区太小,无法检索该列值。例如,它调用SQLBindCol作为第2列,表示缓冲区长度为62,而不是80,或者他绑定的不是SQL_C_CHAR。

票数 2
EN

Stack Overflow用户

发布于 2013-11-20 00:44:34

注意:我从COBOL方面回答这个问题,并且是IBM大型机COBOL。如果这不起作用,关键是找出正在使用的COBOL编译器,并从数据库中了解COBOL的特定方言是如何表示VARCHAR的。

COBOL没有可变长度的字符串。COBOL没有以空结尾的字符串。没有位模式,COBOL不能处理,尽管先前的建议.

您需要做的是找到数据库/SQL如何显示VARCHAR。IBM大型机上的DB2是这样做的:

代码语言:javascript
复制
01  data-name.
    05  data-name-length  BINARY  PIC 9(4).
    05  data-name-max-data        PIC X(80).

我会大刀阔斧地说你的名字是一样的。如果您找到编译器的名称并搜索一些文档,您可能会确认或否认这一点。

定义上述内容的更好方法如下:

代码语言:javascript
复制
01  data-name.
    05  data-name-length  BINARY  PIC 9(4).
    05  data-name-data.
        10  FILLER OCCURS 1 TO 80 TIMES
            DEPENDING ON data-name-length.
            15  FILLER            PIC X.

但是您正在使用的COBOL已经在表中包含了数据。该表将需要包含两个字节的二进制长度以及数据的最大长度。

将长度从表移到上面的长度,将数据从表移动到上面的数据名称数据。

使用数据-名称-数据将给您提供全部的数据,没有更多,也没有更少。

只是二进制的笔记。对于80个字符的VARCHAR,它没有什么区别,但是对于大于9,999字节的VARCHAR,您需要确保字段使用了“本机二进制”定义。用于大型机上的企业COBOL,即COMP-5。OpenCOBOL/OpenCOBOL也是如此。对于其他方言,它可能是不同的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20058512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档