VCとは直接関係ない質問かもしれませんが、ご容赦願います。m(__)m
Win2000,VC6,MFC,SDIの環境です。
データーベースは ODBC MS SQL7 を使っています。
CDaoDatabase::Execute()を使って SQLの CREATE TABLE を実行すると
この操作は実行できません というメッセージボックスが出てしまいます。
どうすればテーブルを作成できるでしょうか?
もしくわエンタープライズマネージャーでテーブルを作成する方法を
教えてください。
(単にテーブルを作成しただけでは、 SELECT 文に対して、テーブルまたはクエリーが
見つからないというエラーになってしまいます)
よろしくお願いいたします。m(__)m
データベースのオープンはできているのですか?
または、connect はきちんと成功しているんですよね?
>エンタープライズマネージャーでテーブルを作成する方法
具体的に何がわからないのでしょうか
セキュリティのログインは定義しているんですよね
ODBCと言うことは「コントロールパネル」や「管理ツール」にある
データソースの設定しているんですよね
woodさん レスありがとうございます。
>データベースのオープンはできているのですか?
はい、できています。
>または、connect はきちんと成功しているんですよね?
localですし、データソースのテストは成功していますので
問題ないと思います。
>セキュリティのログインは定義しているんですよね
こちらは意味がわかりません。
>ODBCと言うことは「コントロールパネル」や「管理ツール」にある
>データソースの設定しているんですよね
はい、しています。
すこし進歩しました。データソースの設定で
「規定のデーターベースを以下のものに変更する」にチェックが入っていなかったので
チェックを入れたら新規に作成したテーブルへのレコードセットのOpenに成功しました。
ここのチェックをはずすと新規作成したテーブルへのオープンに失敗します。
そういうものなのでしょうか?
チェックを入れて、新規テーブルのOpenに成功はしたのですが、今度は
「データーベースまたはオブジェクトは読み取り専用であるため、更新できません。」
というメッセージが出てしまいます。
読み書き可能にするオマジナイがどこかにあるのでしょうか?
アドバイスを頂けたら、幸いです。
以下に簡略化したソースをのせてみます。
// m_pDB : DBへのポインタ(オープンには成功), pRS : CDaoRecordsetへのポインタ
CString sQuery = select * from [hoge];
CString sInsert;
CString s1 = 2003/02/20 18:25, s2 = 012, s3 = 123;
sInsert.Format(insert into [hoge] VALUES('%s', '%s', '%s'), s1, s2, s3);
try
{
// dbAppendOnly : レコードの追加のみ可能
pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
pRS->AddNew();
m_pDB->Execute(sInsert);
pRS->Update();
delete pRS;
}
catch(CDBException *pEx)
{
// 省略
}
よろしくお願いいたします。m(__)m
CDaoDatabase::Open などでデータベース接続確立していると思いますが
接続文字列の「ユーザーID」はSQL Server上の
DBまたはテーブルに対する権限設定はどうなってますか?
テーブル毎の設定の場合「SELECT」・「INSERT」・「DELETE」・「DIR」
などチェックする場所があったはずですけど
SQLでのGRANTのことですけど
woodさん レスありがとうございます。
>CDaoDatabase::Open などでデータベース接続確立していると思いますが
>接続文字列の「ユーザーID」はSQL Server上の
>DBまたはテーブルに対する権限設定はどうなってますか?
SQL7のエンタープライズマネージャーでabcというデータベースを作成し
a というテーブルをつくりました。
ODBCの設定でユーザーIDは sa , パスワードは入力していません。
下記のコードでは CDaoRecordset::CanUpdate()がゼロを返してくるので
レコードの追加ができません。
CDaoDatabase *pDB = new CDaoDatabase;
CString strConnect;
strConnect.Format(_T(ODBC;DSN=abc;UID=sa;PWD=;));
pDB->Open(_T("), FALSE, FALSE, strConnect);
CDaoRecordset *pRS = new CDaoRecordset(pDB);
CString sQuery = select * from a;
CString sInsert;
CString s1 = 001, s2 = 012, s3 = 012;
sInsert.Format(insert into a VALUES('%s', '%s', '%s'), s1, s2, s3);
pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
BOOL bRet = pRS->CanUpdate(); //ここで0が返ってきてしまいます
pRS->AddNew();
pDB->Execute(sInsert);
pRS->Update();
最初の質問とは、内容が変わってしまいました。m(__)m
現在は CDaoRecordset::AddNew()に失敗します。
その理由が知りたいです。
よろしくお願いいたします。m(__)m
>pDB->Execute(sInsert);
これに対して何で「AddNew()」いるのでしょうか
レコードセットとしては何も操作していないと思うのですけど
>pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
>BOOL bRet = pRS->CanUpdate(); //ここで0が返ってきてしまいます
「dbAppendOnly」の説明では「新しいレコードの追加だけが可能です 」
となっていますので「CanAppend」を使うのが正しくありませんか
woodさん レスありがとうございます。
>>pDB->Execute(sInsert);
>これに対して何で「AddNew()」いるのでしょうか
>レコードセットとしては何も操作していないと思うのですけど
SQLの INSERT INTO ステートメントは「レコードの追加」だと思っているのですが
違うのでしょうか?
>>pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
>>BOOL bRet = pRS->CanUpdate(); //ここで0が返ってきてしまいます
>「dbAppendOnly」の説明では「新しいレコードの追加だけが可能です 」
>となっていますので「CanAppend」を使うのが正しくありませんか
はい、CanAppendだとゼロ以外が返ってきました。
今回データベースを初めて扱うので、ご迷惑をおかけします。
よろしくお願いします。m(__)m
データのバインドをしないといけなかったようです。
(よくわかっていませんけど)
結論は CRecordset ではなく その派生クラスを使って解決できました。
http://www.aa.wakwak.com/~dragoon/mdb.htm
こちらを参考にさせていただきました。EIJIさん 直リンク ごめんなさい。
woodさん お付き合いくださり、ありがとうございました。
解決したようですが、誤解されてる部分が
あるようなのでレスします。
1.CDaoRecordsetを使ったレコードの追加
pRS->AddNew();
pRS->SetFieldValue( 0, s1 );
pRS->SetFieldValue( 1, s2 );
pRS->SetFieldValue( 2, s3 );
pRS->Update();
2.CDaoDatabaseを使ったレコードの追加
pDB->Execute(sInsert);
1と2のやってることは結果的に同じ(になるはず)です。
派生クラスを使うこととは関係ありません。
EIJIさん レスありがとうございます。
>1と2のやってることは結果的に同じ(になるはず)です。
>派生クラスを使うこととは関係ありません。
そういうことでしたか、納得です。
わざわざありがとうございました。m(__)m
ただ、派生クラスを使わないと、テーブルをバインド
できないということはないのでしょうか?
(よくわかっていないのですけれど)
CDaoRecordsetの派生クラスを使う目的としては、
テーブルのフィールドをクラスのメンバ変数に
割り当てるようにすることです。
これを静的なバインドと言って、テーブルの構造が
あらかじめ分かっているようなときに利用します。
フィールドとメンバ変数の相互変換をMFCが
やってくれる(はずな)ので、コードが少なくて済みます。
1つのクラスが1テーブルになるので、テーブルが多いと
それだけクラスも増えたりするかも知れません。
Wizardを使った派生クラスの作り方はMSDNの
「ClassWizard : レコードセット クラスの作成」
を参考にしてください。
これとは別に派生クラスを使わない動的バインドも
あります。こちらは柔軟性があるもののコード量は増えます。
・・・ってほとんどMSDNからのまとめでした(^^;
EIJIさん レスありがとうございます。
>1つのクラスが1テーブルになるので、テーブルが多いと
>それだけクラスも増えたりするかも知れません。
なるほどです。
>これとは別に派生クラスを使わない動的バインドも
>あります。こちらは柔軟性があるもののコード量は増えます。
テーブルが多いので、できればクラスを増やしたくありません。
具体的には動的バインドってどんな風にやるのでしょうか?
どちらか参考になるホペや例などございますか?
アドバイスよろしくお願いいたします。m(__)m
>・・・ってほとんどMSDNからのまとめでした(^^;
MSDNよりわかりやすかったです。MSDNって、読んでいるとリンクが張ってあって
アチコチに飛ぶので、何を読んでいるのかわからなくなるんです。(笑)
MFCサンプルの「DAOVIEW」が参考になると思います。
CDaoRecordsetをそのまま使っているコードがあります。
EIJIさん
>MFCサンプルの「DAOVIEW」が参考になると思います。
>CDaoRecordsetをそのまま使っているコードがあります。
参考にさせていただきます。
ありがとうございました。m(__)m