none
DBのフィールド名の取得 RRS feed

  • 質問

  • おはようございます。

    SQLServerのフォーラムとどちらに質問するか、悩んだのですが、こちらでお願いします。

    VB2005Express+SQLServerExpressを使用しています。

    DBのデータをバックアップとしてCSVファイルに書き出す処理を作成しています。

    テーブル名の一覧を取得することはストアドプロシージャでできたのですが、フィールド名をどのようにすれば
    取得できるのかがわかりません。

    スキーマ情報を取得すればできるというような、記述をどこかで目にしたのですが、現在調べている最中です。

    ストアドプロシージャなどで1回で取得できる方法やそれ以外の方法がありましたら、ヒントだけでも結構です
    ので、おねがいできませんでしょうか。(今後、MySQLも勉強する予定為、SQLServer以外でも使用できる
    方法も知っておきたいからです。)

    どうか、よろしくお願いします。

    2010年8月1日 18:46

回答

  • などで1回で取得できる方法やそれ以外の方法がありましたら、ヒントだけでも結構です
    ので、おねがいできませんでしょうか。(今後、MySQLも勉強する予定為、SQLServer以外でも使用できる
    方法も知っておきたいからです。)

    どうか、よろしくお願いします。

    本当に汎用的にやりたいのであれば、ODBCでSQLColumnなんかを叩けばとれますが、すごく面倒です。

    とりあえず、SQL Serverならsp_colmunsとか、MySQLだとSHOW COLMUNSなど、各DBが用意している方法を覚えた方がよいかもです。

    蛇足ですが、DB関連で調べるときは、フィールド名で検索するよりは、列名とかカラム名で検索したほうが見つかりやすいかもです。

    非常によくまとまっていたので、下記のサイトなどがご参照ください。

    列情報-WinOfSql( SQLの窓 )
    http://winofsql.jp/VA003334/dbaccess061021090518.htm

     

    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月1日 19:15
  • > テーブル名の一覧を取得することはストアドプロシージャでできたのですが、フィールド名をどのようにすれば
    > 取得できるのかがわかりません。

    プログラムベースで取得するなら、DB からテーブルの一覧が取れているので、各テーブル名から DataTable のインスタンスを取得、DataTable.Columns プロパティで、各フィールドの情報を参照できます。

    たとえば dt という変数に DataTable のインスタンスが格納されているとすれば、For Each...Next ステートメントを使えば、要素である DataColumn のインスタンスにアクセスできます。

    For Each col As DataColumn In dt.Columns
      Console.WriteLine(col.ColumnName)
    Next

     列名は DataColumn.ColumnName プロパティで取得できます。この辺りは、MySQL でも SQLServer でも全く変わりません。


    ひらぽん http://d.hatena.ne.jp/hilapon/
    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月1日 23:18
    モデレータ
  • プログラムでということでしたら、GetNameメソッドなんかも使えますね。

    SqlDataReader.GetName メソッド
    http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqldatareader.getname(VS.80).aspx

    CSVに書き出す際にデータ量が多い場合、データテーブルが使用するメモリ量が多くなりますので、SqlDataReaderで読んだ方が良いかもしれません。ただ、データベースのレコード全体を整合性が崩れないように書き出すためには、テーブル全体をロックする必要があるでしょう。(SQL Server Expressをシングルユーザーで使用するのであれば問題ないと思いますが)

    ところでなぜそもそもCSVでバックアップされたいのでしょうか? CSVですとスキーマ情報(キー情報とか型情報とか)などが欠落しますから、バックアップには全く適していないように思えるのですが・・・ SQL ServerですとSQL文のBackupコマンドを実行すればバックアップ可能です。MySQLなどについてはわかりませんが、同じようなコマンドがあるのではないでしょうか? あれば、それを使う方が簡単かつ確実です。

    (参考)
    (.Net,SQL)プログラムからSQL Serverデータベースのバックアップを行う
    http://jehupc.exblog.jp/10091319


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月2日 0:39
    モデレータ

すべての返信

  • などで1回で取得できる方法やそれ以外の方法がありましたら、ヒントだけでも結構です
    ので、おねがいできませんでしょうか。(今後、MySQLも勉強する予定為、SQLServer以外でも使用できる
    方法も知っておきたいからです。)

    どうか、よろしくお願いします。

    本当に汎用的にやりたいのであれば、ODBCでSQLColumnなんかを叩けばとれますが、すごく面倒です。

    とりあえず、SQL Serverならsp_colmunsとか、MySQLだとSHOW COLMUNSなど、各DBが用意している方法を覚えた方がよいかもです。

    蛇足ですが、DB関連で調べるときは、フィールド名で検索するよりは、列名とかカラム名で検索したほうが見つかりやすいかもです。

    非常によくまとまっていたので、下記のサイトなどがご参照ください。

    列情報-WinOfSql( SQLの窓 )
    http://winofsql.jp/VA003334/dbaccess061021090518.htm

     

    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月1日 19:15
  • > テーブル名の一覧を取得することはストアドプロシージャでできたのですが、フィールド名をどのようにすれば
    > 取得できるのかがわかりません。

    プログラムベースで取得するなら、DB からテーブルの一覧が取れているので、各テーブル名から DataTable のインスタンスを取得、DataTable.Columns プロパティで、各フィールドの情報を参照できます。

    たとえば dt という変数に DataTable のインスタンスが格納されているとすれば、For Each...Next ステートメントを使えば、要素である DataColumn のインスタンスにアクセスできます。

    For Each col As DataColumn In dt.Columns
      Console.WriteLine(col.ColumnName)
    Next

     列名は DataColumn.ColumnName プロパティで取得できます。この辺りは、MySQL でも SQLServer でも全く変わりません。


    ひらぽん http://d.hatena.ne.jp/hilapon/
    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月1日 23:18
    モデレータ
  • プログラムでということでしたら、GetNameメソッドなんかも使えますね。

    SqlDataReader.GetName メソッド
    http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqldatareader.getname(VS.80).aspx

    CSVに書き出す際にデータ量が多い場合、データテーブルが使用するメモリ量が多くなりますので、SqlDataReaderで読んだ方が良いかもしれません。ただ、データベースのレコード全体を整合性が崩れないように書き出すためには、テーブル全体をロックする必要があるでしょう。(SQL Server Expressをシングルユーザーで使用するのであれば問題ないと思いますが)

    ところでなぜそもそもCSVでバックアップされたいのでしょうか? CSVですとスキーマ情報(キー情報とか型情報とか)などが欠落しますから、バックアップには全く適していないように思えるのですが・・・ SQL ServerですとSQL文のBackupコマンドを実行すればバックアップ可能です。MySQLなどについてはわかりませんが、同じようなコマンドがあるのではないでしょうか? あれば、それを使う方が簡単かつ確実です。

    (参考)
    (.Net,SQL)プログラムからSQL Serverデータベースのバックアップを行う
    http://jehupc.exblog.jp/10091319


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答の候補に設定 山本春海 2010年8月20日 6:03
    • 回答としてマーク 山本春海 2010年9月3日 9:00
    2010年8月2日 0:39
    モデレータ
  • ご回答有難うございます。

    本来は許されないことだとは思うのですが、現在は自分の業務を少しでも楽にするためにプログラムをしています。

    そのため、DBの設計をしっかりと行うことがどうしてもできず(そもそも、自分に何ができるのかわからない状態ですので)
    勉強を続けるうちに、以前はできなかったことができるようになったため、その機能を追加しようとするとテーブル構造が
    足りない、という状況に陥ります。

    あいも変わらず、言葉足らずで恐縮なのですが、バックアップというよりもテーブルの構造を変更した場合に、新たに用意した
    DBにデータを戻すため、一時的にデータを外部に書き出しをして、それを再度取り込むという方法を考えていました。

    ということで、上記の質問にいたりました。

    ただ、この解答を書いている最中に別のDBにストアドプロシージャなどを使用して、Insert処理ができれば、もう少し簡単かな
    とも思いましたので、少し調べてみたいと思います。

    ご提示いただいた方法はこれから調べてみます。

    まずは、御礼まで。有難うございます。

    2010年8月2日 9:02
  • こんにちは、TI-cb400 さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。

    その後いかがでしょうか。

    Chuki さん、ひらぽん さん、trapemiya さん、アドバイスありがとうございます。
    Chuki さん、ひらぽん さん、trapemiya さんからの情報は、有効な情報であると思われますので、勝手ながら私のほうで回答としてマークさせていただきました。

    いただいたレスポンスの中で、解決に役立ったものや、参考になった情報など、有効な情報には回答としてマークすることをお願いしています。
    回答としてマークすることで、今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、ご協力お願いいたします。

    お時間のある時にでも、その後の状況をお知らせください。
    一旦回答としてマークさせていただきましたが、ご不明点がでてきたらまたご質問を続けてくださいね。

    今後とも、MSDN フォーラムをよろしくお願いいたします。それでは。
                                                                                                                   
    マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    2010年9月3日 9:00