救人啊!!!我用500分解决这样一个关于通过MSSQL APIs读varChar类型数据的问题!!!(300分)

  • 主题发起人 主题发起人 aimingoo
  • 开始时间 开始时间
A

aimingoo

Unregistered / Unconfirmed
GUEST, unregistred user!
我急用,手边的程序就要交货了,却发现这个问题!!!各位请救命!!!
请尽可能快回复,谢谢。

如果需要,你可以先下载这套APIs的声明接口:
ftp://delphi-jedi.org/api/mssqlsrv.zip

在MSSQL Client中,使用DBBIND()只能在varChar中获取256字节的数据,因为它将varChar
当成CHAR处理。
有没有什么方法能够一次取出全部的数据呢???
下面这个软件就是调用MS Client APIs得到的,我想一定有办法!!!(软件在国外受限站点,
你可能无法下载,请用代理。)
http://www.geocities.com/laplassoft/data/sqlexecms.zip
 
另200分在http://www.delphibbs.com/delphibbs/DispQ.asp?LID=456664,问题是一样的。
 
还是说说具体状况吧,否则怎么知道一定是dbbind的原因呢?

比如:你的参数是否都正确,(vartype=VARYCHARBIND等等)
目标变量是否有足够空间?以及存取的时候有没有问题?(比如使用了短string)
实在不行,就用dbdata,正好可以看看dbdatlen到底等于多少,
如果正确,用StrLCopy自己复制出来也就行了?
 
RETCODE dbbind (
PDBPROCESS dbproc,
INT column,
INT vartype,
DBINT varlen,
LPBYTE varaddr );
请设置varlen=0试试。或者足够大的值。(例如超过您数据的最大值)
还有问题请讨论。
 
天啊!!!MSDN上说明了,DBBIND只能用256字节。
其二,将varChar处理成char也是MSDN上声明的。
其三,char的BIND的BUFFER只有256字节是结构声明中表明的。:(

很惨!:(
 
那把数据库的varchar改成text行吗?
 
faint!!
你说的那个软件明明是用ADO的,你怎么说是用 SQL API呢??
 
不会吧!!!你不会多读一下下说明么?是SQL Client API的呀。
NTWDBLIB.DLL中的接口声明和实现代码。

(* Accessing SQL-Server without ODBC and BDE. You need only the DLL *)
(* NTWDBLIB.DLL from client package of SQL-Server. *)
 
下面的代码段来自SQL 2K的帮助。我看不太明白,说实在的,我不太会C。:(
大家参考一下下。还有,我不明白如何得到一个正在查询的视图(??)的名字,也就是正在
用dbresults()返回SQL查询结果的那个临时表的名字。:(((有办法么?

如何从程序变量大容量复制数据 (ODBC)
(直接对程序变量使用大容量复制函数 )

1. 分配环境句柄和连接句柄。
2. 设置 SQL_COPT_SS_BCP 和 SQL_BCP_ON 以启用大容量复制操作。
3. 连接到 Microsoft® SQL Server™。
4. 调用 bcp_init 以设置下列信息:
要大容量复制到(或从中复制)的表或视图的名称。
将数据文件的名称指定为 NULL。
接收任何大容量复制错误信息的数据文件的名称(如果不想要消息文件,则指定 NULL)。
复制的方向为:从应用程序到视图或表为 DB_IN,从表或视图到应用程序为 DB_OUT。
5. 对大容量复制中的每列调用 bcp_bind 以将每列与一个程序变量绑定在一起。
6. 用数据填充程序变量,然后调用 bcp_sendrow 以发送数据行。
7. 发送出几行后,调用 bcp_batch 对已发送出的行执行检查点操作。较好的方法是每 1000 行至少调用一次 bcp_batch。
8. 发送出所有数据行后,调用 bcp_done 以完成此操作。

可以在大容量复制操作期间,通过调用 bcp_colptr 和 bcp_collen 改变程序变量的位置和长度。
使用 bcp_control 设置多种大容量复制选项。使用 bcp_moretext 将 text、ntext 和 image 数据分段发送到服务器。

示例
下例说明如何使用大容量复制函数 bcp_bind 和 bcp_sendrow 将数据从程序变量大容量复制到 SQL Server。为简化本示例,查错代码已删除。
// Sample showing ODBC bulk copy from program variables
// bound with bcp_bind; data sent with bcp_sendrow.
//
// Assumes server has:
//
// CREATE TABLE BCPSource (cola int PRIMARY KEY,
// colb CHAR(10) NULL)
// CREATE TABLE BCPTarget (cola int PRIMARY KEY,
// colb CHAR(10) NULL)
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>

SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC;
SQLHSTMT hstmt2 = SQL_NULL_HSTMT;

int main() {
RETCODE retcode;

// BCP variables.
char *terminator = "/0";
// bcp_done takes a different format return code
// because it returns number of rows bulk copied
// after the last bcp_batch call.
DBINT cRowsDone;
// Set up separate return code for bcp_sendrow so
// it is not using the same retcode as SQLFetch.
RETCODE SendRet;

// Column variables.
// cbCola and cbColb must be defined right before
// Cola and szColb because they are used as
// bulk copy indicator variables.
struct ColaData{
SQLINTEGER cbCola;
SQLINTEGER Cola;
} ColaInst;
struct ColbData{
SQLINTEGER cbColb;
SQLCHAR szColb[11];
} ColbInst;

// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &amp;henv);
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);

// Allocate ODBC connection handle, set bulk copy mode, and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &amp;hdbc1);
retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP,
(void *)SQL_BCP_ON, SQL_IS_INTEGER);
retcode = SQLConnect(hdbc1, "MyDSN", SQL_NTS,
"sa", SQL_NTS, "MyPassWord", SQL_NTS);

// Initialize the bulk copy.
retcode = bcp_init(hdbc1, "pubs..BCPTarget", NULL,
NULL, DB_IN);
// Bind the program variables for the bulk copy.
retcode = bcp_bind(hdbc1, (BYTE *)&amp;ColaInst.cbCola, 4,
SQL_VARLEN_DATA, NULL, (INT)NULL,
SQLINT4, 1);
// Could normally use strlen to calculate the bcp_bind
// cbTerm parameter, but this terminator is a null byte
// (/0), which gives strlen a value of 0. Explicitly give
// cbTerm a value of 1.
retcode = bcp_bind(hdbc1, (BYTE *)&amp;ColbInst.cbColb, 4, 11,
terminator, 1, SQLCHARACTER, 2);

// Allocate second ODBC connection handle so that bulk copy
// and cursor operations do not conflict.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &amp;hdbc2);
retcode = SQLConnect(hdbc2, "MyDSN", SQL_NTS,
"sa", SQL_NTS, "MyPassWord", SQL_NTS);
// Allocate ODBC statement handle.
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc2, &amp;hstmt2);

// Bind the SELECT statement to the same program variables
// bound to the bulk copy operation.
retcode = SQLBindCol(hstmt2, 1, SQL_C_SLONG, &amp;ColaInst.Cola, 0,
&amp;ColaInst.cbCola);
retcode = SQLBindCol(hstmt2, 2, SQL_C_CHAR, &amp;ColbInst.szColb, 11,
&amp;ColbInst.cbColb);
// Execute a SELECT statement to build a cursor containing
// the data to be bulk copied to the new table.
retcode = SQLExecDirect(hstmt2,
"SELECT * FROM BCPSource",
SQL_NTS);
// Go into a loop fetching rows from the cursor until
// each row is fetched. Because the bcp_bind calls
// and SQLBindCol calls each reference the same
// variables, each fetch fills the variables used by
// bcp_sendrow, so all you have to do to send the data
// to SQL Server is to call bcp_sendrow.

while ( (retcode = SQLFetch(hstmt2) ) != SQL_NO_DATA) {
if ( (retcode != SQL_SUCCESS) &amp;&amp;
(retcode != SQL_SUCCESS_WITH_INFO) ) {
// Process error.
return(9);
}
if ( (SendRet = bcp_sendrow(hdbc1) ) != SUCCEED ) {
// Process error.
return(9);
}
}
// Signal the end of the bulk copy operation.
cRowsDone = bcp_done(hdbc1);
printf("Number of rows bulk copied after last bcp_batch
call = %d./n", cRowsDone);
/* Clean up. */
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return(0);
}
 
往上提提。

不会没人理我了吧!!!我到现在还没有搞定它!:(((
dcp_init()调用就不成功了。:((((
 
我说的是这个:
http://www.geocities.com/laplassoft/data/sqlexecms.zip

这个软件就是用ADO而已,那里有什么MS Client APIs
你说的MSSQL API(NTWDBLIB)俺早用过多年了,真是从来没用它具体搞过项目 :-(
没注意varchar的问题,以后再说吧。
 
大虾也搞不定,我更没办法了。帮你提提前。
 
我自己已经搞定了!
哈哈。

真他妈的难!
实际上,这个必须用MEMO来处理。DB-Libray从6.5版本以来就一直没有改过,而ODBC为了适应SQL 7/2000中出现的新的数据类型和对原数据类型的扩展,都是通过“内置转换”来处理的。

用BDE引擎打开一个带Varchar(260)及更长的变长字串字段来看,就明白了:这已经被转换成了memo类型。你必须将它作为一个text来处理。

我改写了mssql client接口,通过二次处理,将varchar转换成text类型返回,从而解决了varchar超长字符串的问题。就目前来看,可能只有这样一种方法了。ODBC内部也是这样处理的。
另外,bcp函数集只能处理“服务器表-->本地文件”的绑定,而不能处理“服务器表-->本地程序变量”的绑定。所以不能用来解决问题。

问题的解决方案已经给出来了。分呢,大家都没得。哈哈哈。
有什么方法还给我呢???
 
唉!不要太在意分数嘛!
这个问题不要太早结束,让更多人可以看到岂不更好?

你要是心疼分,你给我300,我给你300...
如此这般,循环往复,万世不竭...则天下英雄,唯明戈与刀耳!
 
多人接受答案了。
 
后退
顶部