|
藍森林 http://www.lslnet.com 2006年6月6日 10:18
在pro*c中出問題了!
我在程序中調用insert語句,出現了下面錯誤的語句:
ORA-1480: trailling null missing from STR bind value
這是什麼原因??怎麼會發生這樣的錯誤呢?
謝謝!! |
在pro*c中出問題了!
你使用的是pro*c還是途徑
另外使用的是varchar類型的還是char類型的 |
在pro*c中出問題了!
我使用的是pro*C
我的表中的類型有NUMBER, VARCHAR2
定義的插入的變量全都是char數組 類型。
書上說NUMBER和char是可以互換的。這樣會有問題嗎? |
在pro*c中出問題了!
你檢查一下數據類型的長度,這個問題應該是數據類型的長度超過了數據庫中的定義! |
在pro*c中出問題了!
我的NUMBER和VARCHAR2中最大的定義為20個字符,請問是不是這個地方出問題了。
我的列也定義得很長,最大的有10個字符那麼大,這樣有問題嗎?? |
在pro*c中出問題了!
不好說,出現這個錯誤報告應該是數據類型的長度不匹配,你仔細的查查,如果可以的話是否可以把那段錯誤程序貼一下. |
在pro*c中出問題了!
錯誤信息就是說你插入的數據沒有以NULL結束. |
在pro*c中出問題了!
不好意思,我的程序不在手上。
我插入的數據是從客戶端接受的,我是不是要在每個字符串後都加上'\0'才對呢? |
在pro*c中出問題了!
能否將你插入數據庫的那條語句,發出來看一下,我覺得應該是你語句寫的有問題吧?我以前用Pro*C沒有遇到過這種問題呀 |
在pro*c中出問題了!
[code]
#include <unistd.h>;
#include <stdlib.h>;
#include <fcntl.h>;
#include <sys/types.h>;
#include <sys/wait.h>;
#include <signal.h>;
#include <errno.h>;
#include <stdio.h>;
#include <string.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#include <netinet/in.h>;
#include <arpa/inet.h>;
#include <sys/time.h>;
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE ORACA;
EXEC SQL BEGIN DECLARE SECTION;
char uid[]="test/test";
struct tab_main_data{
char c_account_id[20];
char dep_open_id[8];
char dep_cur_id[8];
char c_name[20];
char c_passwd[6];
char c_open_day[10];
char c_status_flag[2];
char c_saved[11];
char c_cancel_flag[2];
char op_id[20];
char c_saved_day[10];
}TMD;
EXEC SQL END DECLARE SECTION;
/* There is the declaration section*/
void account_open(char *, int);
void SetAccountInfoToTMD(char *, struct tab_main_data *);
void select_error(int);
/*
* account_open() is used to open an count for a customer
* and write the info of customer into the table "tab_main_data"
*/
void account_open(char *buf, int sockfd)
{
SetAccountInfoToTMD(buf, &TMD);
EXEC SQL WHENEVER SQLWARNING CONTINUE;
EXEC SQL WHENEVER SQLERROR DO select_error(sockfd);
EXEC SQL INSERT INTO tab_main_data(c_account_id, dep_open_id, \
dep_cur_id, c_name, c_passwd, c_open_day, c_status_flag, \
c_saved, c_cancel_flag, op_id, c_saved_day) \
VALUES(:TMD.c_account_id, :TMD.dep_open_id, :TMD.dep_cur_id, \
:TMD.c_name, :TMD.c_passwd, :TMD.c_open_day, \
:TMD.c_status_flag, :TMD.c_saved, :TMD.c_cancel_flag, \
:TMD.op_id, :TMD.c_saved_day);
printf("account_open(): add an account success!\n");
}
void SetAccountInfoToTMD(char *buf, struct tab_main_data *pInfo)
{
buf+=1;
strncpy(pInfo->;c_account_id, buf, 20);
printf("%-8s\n",pInfo->;c_account_id);
buf+=20;
strncpy(pInfo->;dep_open_id, buf, 8);
printf("%s\n",pInfo->;dep_open_id);
// strncpy(pInfo->;dep_cur_id, buf, 8);
strncpy(pInfo->;dep_cur_id, pInfo->;dep_open_id, 8);
printf("%s\n",pInfo->;dep_cur_id);
buf+=8;
strncpy(pInfo->;c_name, buf, 20);
printf("%-8s\n",pInfo->;c_name);
buf+=20;
strncpy(pInfo->;c_passwd, buf, 6);
printf("%-8s\n",pInfo->;c_passwd);
buf+=6;
strncpy(pInfo->;c_open_day, buf, 10);
printf("%-8s\n",pInfo->;c_open_day);
buf+=10;
strncpy(pInfo->;c_status_flag, buf, 2);
printf("%-8s\n",pInfo->;c_status_flag);
// bcopy(buf, pInfo->;c_status_flag, sizeof(char));
buf+=2;
strncpy(pInfo->;c_saved, buf, 11);
printf("%-8s\n",pInfo->;c_saved);
buf+=11;
strncpy(pInfo->;c_cancel_flag, buf, 2);
printf("%-8s\n",pInfo->;c_cancel_flag);
// bcopy(buf, pInfo->;c_status_flag, sizeof(char));
buf+=2;
strncpy(pInfo->;op_id, buf, 20);
printf("%-8s\n",pInfo->;op_id);
buf+=20;
strncpy(pInfo->;c_saved_day, buf, 10);
printf("%-8s\n",pInfo->;c_saved_day);
}
void select_error(int sockfd)
{
char err_buf[100];
sprintf(err_buf, "%.*s", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
if(write(sockfd, err_buf, sizeof(err_buf))==-1)
{
printf("select_error(): write error");
}
printf("%s", err_buf);
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK WORK RELEASE;
exit(-1);
}
[/code]
以上就是三個函數就是出問題的地方,請各位幫幫忙!
void SetAccountInfoToTMD(char *buf, struct tab_main_data *pInfo)
這個函數是用來把收到的數據包寫進TMD這個結構,裡面的的printf語句用於測試收到到的結果是否正確,經過測試客戶端(用kylix/delphi寫的)發來的數據都能正確顯示。
請問我的問題出在哪了?? |
在pro*c中出問題了!
程序重用strncpy(pInfo->;c_cancel_flag, buf, 2);
應該沒什麼問題的,我覺得你有必要察看一下數據庫中字段定義信息。 |
在pro*c中出問題了!
我同意樓上大哥的建議,仔細查看你每一個數據庫中字段的定義,然後再對應查看你給其賦的值的類型是否與字段類型匹配 |
在pro*c中出問題了!
希望高手門能看明白以下我說什麼,我的表達能力實在很差勁!見諒!
我的問題解決了,不是數據庫中字段的定義有問題。
問題出在我接收字符串的函數void SetAccountInfoToTMD(char *, struct tab_main_data *);
客戶端是把數據放進一個string的變量發過來的,而我在void SetAccountInfoToTMD(char *, struct tab_main_data *);
這個函數里卻沒有用'\0'截取每個字符串,而是想當然的以為strncpy把我想要的N個字符拷貝到struct結構裡的成員,struct結構裡的變量就有了我預期的值。
我的理解是這樣的,我定義的struct tab_main_data裡的成員全都是字符串類型,結構裡的變量是用一塊連續的空間存放的,由於沒有用'\0'標誌每個字符串變量的結束,所以結構裡的的第一個變量存放的就是整個讀出來的數據,而不是預期的其中一個數據,所以就出問題了。不知道我這樣理解對不對?
我還有一點不明白,我要改了以下兩個地方才能把所有數據完整的取出來,否則每個成員變量就會少取最後一個字符,即比原來的想取的字符串少了一個字符。
照理說,如:
char c_account_id[20];就可以存放21個字符了,但是為什麼我要寫成
char c_account_id[21];才能把20個字符全部放進去了呢?
[code]
EXEC SQL BEGIN DECLARE SECTION;
char uid[]="test/test";
struct tab_main_data{
char c_account_id[21];
char dep_open_id[9];
char dep_cur_id[9];
char c_name[21];
char c_passwd[7];
char c_open_day[11];
char c_status_flag[3];
char c_saved[12];
char c_cancel_flag[3];
char op_id[21];
char c_saved_day[11];
}TMD;
EXEC SQL END DECLARE SECTION;
.........
..........
.........
void SetAccountInfoToTMD(char *buf, struct tab_main_data *pInfo)
{
buf+=1;
strncpy(pInfo->;c_account_id, buf, 20);
pInfo->;c_account_id[21]='\0'; 《====這裡要是寫成pInfo->;c_account_id[20]='\0'; 就會只截取19個字符,而不是我想要的20個字符,怎麼會這樣呢??以下各個變量也是這樣。。。
buf+=20;
strncpy(pInfo->;dep_open_id, buf, 8);
pInfo->;dep_open_id[9]='\0';
strncpy(pInfo->;dep_cur_id, pInfo->;dep_open_id, 8);
buf+=8;
strncpy(pInfo->;c_name, buf, 20);
pInfo->;c_name[21]='\0';
buf+=20;
strncpy(pInfo->;c_passwd, buf, 6);
pInfo->;c_passwd[7]='\0';
buf+=6;
strncpy(pInfo->;c_open_day, buf, 10);
pInfo->;c_open_day[11]='\0';
buf+=10;
strncpy(pInfo->;c_status_flag, buf, 2);
pInfo->;c_status_flag[3]='\0';
buf+=2;
strncpy(pInfo->;c_saved, buf, 11);
pInfo->;c_saved[12]='\0';
buf+=11;
strncpy(pInfo->;c_cancel_flag, buf, 2);
pInfo->;c_cancel_flag[3]='\0';
buf+=2;
strncpy(pInfo->;op_id, buf, 20);
pInfo->;op_id[21]='\0';
buf+=20;
strncpy(pInfo->;c_saved_day, buf, 10);
pInfo->;op_id[11]='\0';
}
[/code] |
在pro*c中出問題了!
因為還有\0要佔一個字符
另外strncpy
如果源比目的串找
那麼不會在最後自動加\0
我原來分析時也沒有認真看 |
在pro*c中出問題了!
是的,Strncpy函數是不會自動帶拷貝的字符串後面加"\0"的.另外如果你定義的字符串長度應該比數據庫中的定義多一位,因為在C語言裡面字符串是要用"\0"字符來表示結束的. |
在pro*c中出問題了!
謝謝 無雙 robinliu76 !! |
| |