2014-02-21 28 views
0

我正在嘗試使用Pro * C從光標讀取數組。Pro * C - 獲取數組?

事情是這樣的:

struct array { 
    char key[10]]; 
    char name[32]; 
}; 

struct array rows[250]; 

// Open cursor... 

EXEC SQL FETCH my_cursor INTO :rows; 

這工作,但字段不被空值終止。我認爲這是因爲我通常會使用:

EXEC SQL VAR key IS STRING(11); 
EXEC SQL VAR name IS STRING(33); 

但是這似乎不適用於數組。

有誰知道如何解決這個問題?

謝謝!

+0

你的提取是正確的。你如何確認他們不是null結束? –

+0

如果鍵包含說,只有兩個字符,我期望第三個字符是一個空終止符。相反,它似乎將空間寫入關鍵主機變量。 – James

+0

很好,它們是空的終止..唯一的事情就像Alex說的那樣,他們都充滿了空間,就像典型的CHAR概念一樣。這就是爲什麼我們有pro * c的VARCHAR結構。 –

回答

2

由於無法確定長度,所以將這些值視爲(Oracle)CHAR。由於它的值爲fixed size,所以用空格填充值是正常的。

有了一個虛表:

create table t42 (key varchar2(10), name varchar2(32)); 
insert into t42 values ('abc','A B C'); 
insert into t42 values ('def','D E F'); 
commit; 

此代碼:

#include <string.h> 
#include <stdio.h> 

exec sql include sqlca.h; 

int main(int argc, char **argv) 
{ 
    VARCHAR v_userid[15]; 
    VARCHAR v_passwd[15]; 

    struct array { 
     char key[10]; 
     char name[32]; 
    }; 

    struct array rows[2]; 

    strcpy(v_userid.arr, "user"); 
    v_userid.len = 5; 
    strcpy(v_passwd.arr, "password"); 
    v_passwd.len = 8; 

    exec sql connect :v_userid identified by :v_passwd; 
    if (sqlca.sqlcode != 0) 
    { 
     printf("ORA%d: %s\n", sqlca.sqlcode, sqlca.sqlerrm); 
     return(1); 
    } 

    memset(rows, '\0', sizeof(rows)); 
    EXEC SQL DECLARE cur CURSOR FOR select * from t42; 
    EXEC SQL OPEN cur; 
    EXEC SQL FETCH cur INTO :rows; 
    printf("%d\n", sqlca.sqlcode); 
    printf("<%s><%s>\n", rows[0].key, rows[0].name); 
    printf("<%s><%s>\n", rows[1].key, rows[1].name); 
    EXEC SQL CLOSE cur; 
} 

...顯示你所描述的相同的行爲:

0 
<abc  ><A B C       > 
<def  ><D E F       > 

你基本上做一個隱cast(key as char(10))當數據被提取時,會引入填充,因爲它知道它將進入CHAR而不是VARCHAR變量。

改變陣列成員VARCHAR data types(包括指.arr成員):

#include <string.h> 
#include <stdio.h> 

exec sql include sqlca.h; 

int main(int argc, char **argv) 
{ 
    VARCHAR v_userid[15]; 
    VARCHAR v_passwd[15]; 

    struct array { 
     VARCHAR key[10]; 
     VARCHAR name[32]; 
    }; 

    struct array rows[2]; 

    strcpy(v_userid.arr, "user"); 
    v_userid.len = 5; 
    strcpy(v_passwd.arr, "password"); 
    v_passwd.len = 8; 

    exec sql connect :v_userid identified by :v_passwd; 
    if (sqlca.sqlcode != 0) 
    { 
     printf("ORA%d: %s\n", sqlca.sqlcode, sqlca.sqlerrm); 
     return(1); 
    } 

    memset(rows, '\0', sizeof(rows)); 
    EXEC SQL DECLARE cur CURSOR FOR select * from t42; 
    EXEC SQL OPEN cur; 
    EXEC SQL FETCH cur INTO :rows; 
    printf("%d\n", sqlca.sqlcode); 
    printf("<%s><%s>\n", rows[0].key.arr, rows[0].name.arr); 
    printf("<%s><%s>\n", rows[1].key.arr, rows[1].name.arr); 
    EXEC SQL CLOSE cur; 
} 

...讓你預料到它的工作:

0 
<abc><A B C> 
<def><D E F> 

有當然,那裏有一個錯誤(至少有一個!),我特意留下了這個錯誤。如果您的數據庫字段是我製作的10個和32個字符,那麼VARCHAR元素(或您的原始元素)的大小需要爲一個字節大以容納終止空值 - 這當然是基本的C元素,所以它是完全可能你的真正的專欄分別是9和31個字符(儘管你的EXEC SQL VAR例子暗示不)。隨着組合我,如果我:

insert into t42 values ('1234567890','123456789'); 

...然後在第三行顯示爲:

<1234567890 ><[email protected]> 

...因爲它的閱讀過去分配的空間。當然,如果我使用結構VARCHAR key[11]; VARCHAR name[33];,則按預期工作。