私は独学で Pro*C を学んでおり、(おそらく) カーソルを使用してデータベース内のレコードを処理し、コンパイルして実行するプログラムを持っています。問題は、変数が印刷されたときにメモリにあったジャンクを取得していることです(カーソルを使用して読み込まれたもの)。
SQL execステートメントをいくつかの異なる方法で分割しようとしましたが、これは役に立ちませんでした。また、さまざまな場所でSQLを開いたり閉じたりしようとしましたが、これも役に立ちませんでした。私は本当に長いデバッグ プロセスの最後にいます。この時点で、私は非常に初心者の間違いを犯していると確信しています。ここにいる Oracle プログラマーの中で少し時間を割いても構わないという人がいれば、ここで軌道に戻る方法について少しフィードバックをいただければ幸いです。
印刷するはずです:
Enter a Guest_ID(type 0 to terminate)>>
1
Charge Summary for: Firstname Lastname Guest-ID: 1
Sales_Item: 1 – Room (Taxable)
Hotel-Id Hotel-Name Trans-Date Quantity Unit-Price Extended-Price
Hotel-Id Hotel-Name Trans-Date Quantity Unit-Price Extended-Price
Hotel-Id Hotel-Name Trans-Date Quantity Unit-Price Extended-Price
Sales Item Total Quantity Extended-Price
それは実際に印刷します:
Enter a Guest_ID(type 0 to terminate)>>
3
Charge Summary for: l▒ Guest_ID: 3
カーソルを完全に台無しにしているように感じますが、Pro*C での変数の宣言方法と使用方法にまだ慣れていないため、問題がどこにあるかを正確に特定することはできません。また、C プログラムは通常デバッグされますが、これはリモート サーバー上で実行され、デバッグは非常に制限されており、dbx コマンドさえありません。
コード:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
exec sql include sqlca;
// OK - Here we GO
void main()
{
// First, create all the variables that we will need to communicate between
// the "C" program and the database
exec sql begin declare section;
//VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sCheckInDate[12], sRoom[11];
VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sTransDate[11];
//int nDays, nGuest_ID, nCount;
int nGuest_ID, nQuantity, nUnitPrice, nCount, nHotelID, nItemID;
//VARCHAR sInCity[11];
VARCHAR sItemName[31], sTaxable[11];
VARCHAR sUserID[21], sPassword[21];
exec sql end declare section;
// Now define the cursor we will use to get all of the charges that the guest incurred at all hotels
exec sql declare dbGuest cursor for
Select G.Guest_ID, G.Last_Name, G.First_Name, C.Item_ID, C.Item_Name, C.Quantity, C.Unit_Price, C.Trans_Date, H.Hotel_Name, H.Hotel_ID, SI.Taxable
From Hotel H, Charge C, Stay S, Guest G, Sales_Item SI Where
C.Stay_ID=S.Stay_ID And H.Hotel_ID=S.Hotel_ID And G.Guest_ID=S.Guest_ID
And SI.Item_ID=C.Item_ID
Group By S.Guest_ID;
// Set up the user-id and password to access my database
// Because we are using the local database on this server
// we don't need to use any database location or SID
strcpy(sUserID.arr,"myuserid");
strcpy(sPassword.arr,"mypassword");
sUserID.len=strlen(sUserID.arr);
sPassword.len=strlen(sPassword.arr);
exec sql connect :sUserID identified by :sPassword;
// sqlca.sqlcode is a variable that is set based on the last command sent in to the database
// a value anything other than zero for what we just did (connect to the database) indicates
// a error.
if(sqlca.sqlcode !=0)
{
//printf("Sorry, cannot connect to server, pgm aborted %s\n",sqlca.sqlcode); //correction 2/5/14
printf("Sorry, cannot connect to server, pgm aborted %d\n",sqlca.sqlcode); //change to %d
exit(1);
}
//we made it here, so we were able to open the database correctly
exec sql SELECT COUNT(*) INTO :nCount FROM Guest;
printf ("There are %d Guests.\n",nCount);
for(;;){
// Read in through stdio the Guest we want to query, then set it up do we can use it
printf("Enter a Guest_ID(type 0 to terminate)>>\n");
scanf("%d",&nGuest_ID);
//Guest_ID.len= strlen(Guest_ID.arr);
if(nGuest_ID==0)
{
printf("BYE\n");
exit(0);
}
printf("%s %s %s %s %d\n","Charge Summary for:", sFirstName.arr, sLastName.arr, " Guest_ID:", nGuest_ID);
//printf("I do not work yet (type exit to terminate)>>\n");
// Open our cursor and begin reading records
exec sql open dbGuest;
for(;;)
{
//exec sql fetch dbGuest into :nGuest_ID, :sLastName, :sFirstName, :sHotelName, :sCheckInDate, :nDays, :sRoom;
exec sql fetch dbGuest into :sLastName, :sFirstName, :nItemID, :sItemName, :nQuantity, :nUnitPrice, :sTransDate, :sHotelName, :nHotelID;
if(sqlca.sqlcode !=0) // If anything went wrong or we read past eof, stop the loop
{
break;
}
printf("%s %s %s %s %d\n","Charge Summary for:", sFirstName.arr, sLastName.arr, " Guest_ID:", nGuest_ID);
// Do the crazy stuff to end the C-Strings
sLastName.arr[sLastName.len] = 0;
sFirstName.arr[sFirstName.len] = 0;
sItemName.arr[sItemName.len] = 0;
sTransDate.arr[sTransDate.len] = 0;
sHotelName.arr[sHotelName.len] = 0;
// Print out the information for this guest
printf("%s %d %s %s \n", "Sales_Item: ", nItemID, " - ", sItemName.arr);
printf("%d %s %s %d %d \n", nHotelID, " ", sHotelName.arr, " ",sTransDate.arr, " ", nQuantity, " ", nUnitPrice);
}
// close the cursor and end the program
exec sql close dbGuest ;
}
exit(0);
}
通常、C プログラムはデバッガーで実行されますが、これは Pro C であり、Oracle Pro C のデバッグ全体に戸惑っています (リモート データベースで実行されているため)。
これらを試しましたが、役に立ちませんでした:
Oracle ProC INSERT INTO VALUES ( (select ...) )
Oracle Pro*C でカーソルを使用してテーブルを更新できませんでした
VARCHAR 変数は別の方法で宣言する必要があると言われましたが、他の方法ではエラーがスローされるようです。