データーベース テーブルを作成したい

[戻る]
kai 2003/02/24(月) 16:49:05
VCとは直接関係ない質問かもしれませんが、ご容赦願います。m(__)m

Win2000,VC6,MFC,SDIの環境です。
データーベースは ODBC MS SQL7 を使っています。

CDaoDatabase::Execute()を使って SQLの CREATE TABLE を実行すると
この操作は実行できません というメッセージボックスが出てしまいます。

どうすればテーブルを作成できるでしょうか?
もしくわエンタープライズマネージャーでテーブルを作成する方法を
教えてください。
(単にテーブルを作成しただけでは、 SELECT 文に対して、テーブルまたはクエリーが
見つからないというエラーになってしまいます)

よろしくお願いいたします。m(__)m

wood 2003/02/24(月) 23:07:49
データベースのオープンはできているのですか?
または、connect はきちんと成功しているんですよね?

>エンタープライズマネージャーでテーブルを作成する方法
具体的に何がわからないのでしょうか

セキュリティのログインは定義しているんですよね

ODBCと言うことは「コントロールパネル」や「管理ツール」にある
データソースの設定しているんですよね

kai 2003/02/25(火) 09:01:10
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

wood 2003/02/25(火) 12:21:01
CDaoDatabase::Open などでデータベース接続確立していると思いますが
接続文字列の「ユーザーID」はSQL Server上の
DBまたはテーブルに対する権限設定はどうなってますか?
テーブル毎の設定の場合「SELECT」・「INSERT」・「DELETE」・「DIR」
などチェックする場所があったはずですけど

SQLでのGRANTのことですけど

kai 2003/02/25(火) 13:15:12
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

wood 2003/02/25(火) 22:13:33
>pDB->Execute(sInsert);
これに対して何で「AddNew()」いるのでしょうか
レコードセットとしては何も操作していないと思うのですけど

>pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
>BOOL bRet = pRS->CanUpdate(); //ここで0が返ってきてしまいます
「dbAppendOnly」の説明では「新しいレコードの追加だけが可能です 」
となっていますので「CanAppend」を使うのが正しくありませんか

kai 2003/02/26(水) 09:33:45
woodさん レスありがとうございます。

>>pDB->Execute(sInsert);
>これに対して何で「AddNew()」いるのでしょうか
>レコードセットとしては何も操作していないと思うのですけど

SQLの INSERT INTO ステートメントは「レコードの追加」だと思っているのですが
違うのでしょうか?

>>pRS->Open(dbOpenDynaset, sQuery, dbAppendOnly);
>>BOOL bRet = pRS->CanUpdate(); //ここで0が返ってきてしまいます
>「dbAppendOnly」の説明では「新しいレコードの追加だけが可能です 」
>となっていますので「CanAppend」を使うのが正しくありませんか

はい、CanAppendだとゼロ以外が返ってきました。

今回データベースを初めて扱うので、ご迷惑をおかけします。
よろしくお願いします。m(__)m

kai 2003/02/26(水) 10:06:00
[[解決]]
データのバインドをしないといけなかったようです。
(よくわかっていませんけど)
結論は CRecordset ではなく その派生クラスを使って解決できました。

http://www.aa.wakwak.com/~dragoon/mdb.htm

こちらを参考にさせていただきました。EIJIさん 直リンク ごめんなさい。

woodさん お付き合いくださり、ありがとうございました。

EIJI 2003/02/26(水) 13:03:00
解決したようですが、誤解されてる部分が
あるようなのでレスします。

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のやってることは結果的に同じ(になるはず)です。
派生クラスを使うこととは関係ありません。

kai 2003/02/26(水) 13:45:53
EIJIさん レスありがとうございます。

>1と2のやってることは結果的に同じ(になるはず)です。
>派生クラスを使うこととは関係ありません。

そういうことでしたか、納得です。
わざわざありがとうございました。m(__)m

ただ、派生クラスを使わないと、テーブルをバインド
できないということはないのでしょうか?
(よくわかっていないのですけれど)

EIJI 2003/02/26(水) 15:03:25
CDaoRecordsetの派生クラスを使う目的としては、
テーブルのフィールドをクラスのメンバ変数に
割り当てるようにすることです。
これを静的なバインドと言って、テーブルの構造が
あらかじめ分かっているようなときに利用します。
フィールドとメンバ変数の相互変換をMFCが
やってくれる(はずな)ので、コードが少なくて済みます。
1つのクラスが1テーブルになるので、テーブルが多いと
それだけクラスも増えたりするかも知れません。

Wizardを使った派生クラスの作り方はMSDNの
「ClassWizard : レコードセット クラスの作成」
を参考にしてください。


これとは別に派生クラスを使わない動的バインドも
あります。こちらは柔軟性があるもののコード量は増えます。

・・・ってほとんどMSDNからのまとめでした(^^;

kai 2003/02/26(水) 15:25:08
EIJIさん レスありがとうございます。

>1つのクラスが1テーブルになるので、テーブルが多いと
>それだけクラスも増えたりするかも知れません。

なるほどです。

>これとは別に派生クラスを使わない動的バインドも
>あります。こちらは柔軟性があるもののコード量は増えます。

テーブルが多いので、できればクラスを増やしたくありません。
具体的には動的バインドってどんな風にやるのでしょうか?
どちらか参考になるホペや例などございますか?
アドバイスよろしくお願いいたします。m(__)m

>・・・ってほとんどMSDNからのまとめでした(^^;

MSDNよりわかりやすかったです。MSDNって、読んでいるとリンクが張ってあって
アチコチに飛ぶので、何を読んでいるのかわからなくなるんです。(笑)

EIJI 2003/02/26(水) 15:46:04
MFCサンプルの「DAOVIEW」が参考になると思います。
CDaoRecordsetをそのまま使っているコードがあります。

kai 2003/02/26(水) 16:10:11
EIJIさん

>MFCサンプルの「DAOVIEW」が参考になると思います。
>CDaoRecordsetをそのまま使っているコードがあります。

参考にさせていただきます。
ありがとうございました。m(__)m

古いスレッドには追加発言できません。