我客户公司的某个人正在通过ODBC访问我的SQL-Server Express 2012
他们的代码在COBOL中,我无法访问。但是他说如果他运行以下查询,SQLFetch会返回前几条记录,然后在我的数据库上出现正确的截断错误:
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)并且运行正常,他进行了实验并发现如果他将其设置为LEFT (labCodes.description,62)程序运行正常,但在63的镜头它仍然死亡。有很多记录接近完整的80个字符,因此这不是最佳的。
由于没有where子句我根本不明白他是如何得到截断错误的。
由于
编辑以添加来自cobol guy的代码:@bohica的评论 缓冲区有80个字符。
01 Sql-Data.
03 q-Col PIC X(80) OCCURS 50.
我与SQL-C-Char绑定。
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
* 2nd Edit:
我尝试将varchar(80)更改为char(80),但没有效果。
我终于得到了他从COBOL应用程序获得的实际错误消息,所以这就是:
* 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。
答案 0 :(得分:2)
如果你展示了确切的错误文本,它可能会有所帮助。假设客户端使用ODBC API并发出了SQLFetch,那么SQL Server驱动程序返回的错误是数据截断,这意味着客户端代码传递的缓冲区太小而无法检索该列值。例如,它为第2列调用SQLBindCol,说缓冲区长度为62而不是80,或者他的绑定不是SQL_C_CHAR。
答案 1 :(得分:1)
注意:我从COBOL方面回答这个问题,那就是IBM Mainframe COBOL。如果这不起作用,那么关键是找出正在使用的COBOL编译器,并找出COBOL的特定方言如何表示数据库中的VARCHAR。
COBOL没有可变长度的字符串。 COBOL没有以null结尾的字符串。尽管有早先的建议,但COBOL无法处理任何位模式。
您需要做的是找到数据库/ SQL如何呈现VARCHAR。 IBM Mainframe上的DB2就像这样:
01 data-name.
05 data-name-length BINARY PIC 9(4).
05 data-name-max-data PIC X(80).
我会采取疯狂的刺,并说你未命名的COBOL是相同的。如果您找到编译器的名称并搜索某些文档,您可能会确认或否认这一点。
定义上述内容的更好方法是:
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已经在表格中包含数据。该表将需要包括双字节二进制长度,以及数据的最大长度。
将表中的长度移动到上面的长度,将表中的数据移动到上面的数据名称数据。
使用数据名称数据将为您提供全部数据,仅此而已。
关于BINARY的一个注释。对于80个字符的VARCHAR,它没有区别,但对于大于9,999字节的VARCHAR,您需要确保为该字段使用“本机二进制”定义。对于COMP-5主机上的Enterprise COBOL。 GNU-COBOL / OpenCOBOL也是如此。对于其他方言,它可能会有所不同。