[SQL Server 2005] CLR によるテーブルへの INSERT

このQ&Aのポイント
  • SQL-SERVER 2005とVisual Studio 2005を使用して、VC#でCLRによるストアドプロシージャを作成しています。
  • apacheのaccesslogを正規表現で整形し、必要な項目を抽出してtableにINSERTしようとしています。
  • accesslogが膨大なサイズのため、まとめてINSERTする方法を探しています。
回答を見る
  • ベストアンサー

[SQL Server 2005] CLR によるテーブルへの INSERT

SQL-SERVER 2005 Standerd-Edition と Visual Studio 2005 を使用して、VC# で CLR によるストアドプロシージャを作成しています。 apache の accesslog を正規表現で整形し、必要な項目を抽出してからtable へ INSERT しようとしています。 http://www.atmarkit.co.jp/fdb/rensai/sqls05try05/sqls05try05_2.html http://www.atmarkit.co.jp/fdotnet/vs2005db/vs2005db_09/vs2005db_09_03.html http://www.codeguru.pl/forum-posts-6460-4.aspx このあたりの記事を参考に、どうにかできるようにはなりました。しかし、accesslog が膨大なサイズのため、1行ずつ SQL 文を発行して INSERT していると、10時間前後かかってしまっています。(1,500万record 程度になっています) 何行かずつでも、『まとめて』 INSERT する方法はないものでしょうか。 ※正規表現で整形したものを tab区切りで text 出力し(これは10数分で終わります)、それをウィザードを使用して import すると小一時間で済んだりします。 現状、accesslog の import だけなので、それでもよいのですが、今後は既存の table に対して正規表現を用いて何らかの集計を行っていく予定でいます。数千万 record の table を扱っていくことを考えると不安です。^^; そもそも CLR を「正規表現が使いたい」というだけの理由で導入していること自体、少々お恥ずかしい心持なのですが、もしヒントになるような情報をお持ちの方がいらっしゃれば、ご教授願えませんでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • NOBNNN
  • ベストアンサー率50% (93/186)
回答No.1

Insert ではなく バルクコピー Select Into  で #TempFile テンポラリーファイルに必要な データを出力し、その後Select Union文でマージする。 方法ではいかがでしょうか? Select Into でテンポラリーファイルに出力する際にCLR関数を使って 抽出すればいいのでは・・・

kchan101
質問者

お礼

ほとんど諦めていたのですが、回答していただいていたとは! ありがとうございました。 バルクコピー・・・私はまさにそれを知りたかったようです。 その扱い方がいまひとつまだよくわからないでいますが、 調べた上で後日また別の質問を立てようと思います。 ありがとうございました。

関連するQ&A

  • SQL Server(MSDE2000) : ALTER TABLE

    SQL Server(MSDE2000) : ALTER TABLE した項目に対し、直後に UPDATE で値をセットできない 既存のテーブルを仕様変更するため、列を追加し、初期値で埋める SQL 文を書こうとしていますが、うまく動かず、エラーとなってしまい、原因が判らず困っています。 サンプル SQL 文: ------ CREATE TABLE TEST_TABLE ( TEST_FIELD1 SMALLINT, TEST_FIELD2 SMALLINT) INSERT INTO TEST_TABLE VALUES( 1, 2 ) ALTER TABLE TEST_TABLE ADD TEST_FIELD3 SMALLINT UPDATE TEST_TABLE SET TEST_FIELD3 = 3 ------ ※テスト毎に、必ず DROP TABLE TEST_TABLE されている事が前提です。 上記 SQL 文のうち、1行目~3行目までを抜粋して実行すると、ちゃんと CREATE TABLE され、INSERT され、ALTER TABLE される事を確認しました。 ところが、4行目までを一気に実行しようとすると、 ------ SQL実行中に以下のエラーが発生しました。 エラーコード:207 [Microsoft][ODBC SQL Server Driver][SQL Server]列名 'TEST_FIELD3' は無効です。 SQLステータス:S0022 ------ となってしまい、UPDATE で初期値を埋める事ができません。 しかも、UPDATE に失敗するどころか、2行目の INSERT から以降が結果に反映されなくなるという状況に陥ってしまいます。 また、既存のテーブルの仕様変更が目的なので、その状況に近づけるために、まず、 ------ CREATE TABLE TEST_TABLE ( TEST_FIELD1 SMALLINT, TEST_FIELD2 SMALLINT) INSERT INTO TEST_TABLE VALUES( 1, 2 ) ------ を実行し、既存のテーブル(とレコード内容)が存在する状態を作り出された事を、ツール等で確認してから、 ------ ALTER TABLE TEST_TABLE ADD TEST_FIELD3 SMALLINT UPDATE TEST_TABLE SET TEST_FIELD3 = 3 ------ の2行を実行してみると、やはり UPDATE は失敗し、前述と同じエラーが発生します。 またこの場合、ALTER TABLE の実行結果も反映されていません。(つまり、TEST_FIELD3 が列追加されていない) もちろん、ALTER TABLE だけを実行した場合には、ちゃんと列は追加されます。 その後に、UPDATE を実行すれば、ちゃんと追加列に初期値がセットされます。 どうやら、「一回の SQL 文の実行の中で、ALTER TABLE によって新設した列に対しては、UPDATE などでのアクセスはすぐにはできない」のではないか?という状況のようなのです。一回の SQL 文の実行の中において、何らかのトランザクション動作っぽい挙動を感じます。 つまり、ALTER TABLE で追加された列は、その時点ではまだ完全にシステムに認知されていないため、直後の UPDATE 文で認識できずに失敗するのではないか?と。そして、そこでのエラー発生が、ロールバック的に実行した処理をキャンセルしてしまうため、結果として、ALTER TABLE が実行されなかった事になったり、INSERT が実行されなかった事になったりしているのではないか?と思う次第です。 考えられる回避策としては、SQL 文を別々に作成し、個別に実行すれば良いだけの事なのですが、できれば、SQL 文一つにまとめたいと考えています。 どなたか、こういった現象に対する原因・理由の説明、或いは回避策など、何か情報をお持ちの方はいらっしゃいませんでしょうか? 宜しくお願いします。

  • [SQLServer]既に存在するテーブルに他のテーブルからデータをINSERT

    SQL初心者です。 既に存在するTable_A(レコード0件)に対して、これまた既に存在するTable_B(レコード100件)の内容をINSERTしたいです。次のように書くとだめですよね。 (Table_AとTable_Bのレイアウトはまったく同じ) select * into Table_A from Table_B 何か策はあるのでしょうが、ちょっと探しきれません。お分かりになるかた教えてください。

  • insertを用いてテーブルにレコードを追加することができるのにもかか

    insertを用いてテーブルにレコードを追加することができるのにもかかわらず、load data infile を用いるとerror1366と表示されてしまいます。解決方法を教えてください。 Windows7 mysqlは最新版を使っています。 インストールしたそのままの状態だと、insertを用いて日本語を挿入しようとするとerror 1366と出てしまってましたが、my.iniを書き換えることによってinsert table1 values (1,'ああ');といった操作でエラーが出ることはなくなりました。 しかしcsvファイルをload data infileを用いてインポートしようとすると、またerror 1366が出てしまいました。 インポートしようとしたファイルには日本語が書かれています。 英字だけのファイルを同様にインポートすると、エラーは出ませんでした。 <table1> id int(15) name varchar(255) 1,a 2,b 3,asdf … はインポート可能 。また insert table1 values (1,'あ'); も正常に動作。 1,あ 2,い … をインポートするとエラー。 これができないと先に進めません・・・ ご教授お願いします。

  • 同じカラム直下に複数のレコードをinsert

    初心者です。 DBの同じカラム直下に複数のレコードをinsertさせるにはどうすればよいかどなたか教えて頂けますでしょうか。 以下は入力フォームで入力した複数の日付を確認画面で受け取ったものです。 <table> <th>休日年月日</th> <td>2016/9/12,2016/9/14,2016/9/20,2016/9/26,2016/9/28</td> </table> 日付が一つでしたらinsertは可能ですが、複数の場合はinsertできませんでした。 複数でinsertした場合のDBのイメージは以下の通りです。 holiday(カラム名) 2016/9/12(レコード1行目) 2016/9/14(レコード2行目) 2016/9/20(レコード3行目) 2016/9/26(レコード4行目) 2016/9/28(レコード5行目) どなたか教えて頂けたら幸いです。 よろしくお願い致します。

    • 締切済み
    • PHP
  • CでSQLのテーブルを読む

    SQLのテーブルがあります。 レコードを1行ずつ読むソースを教えてください。 データベースはさっぱり分かりません。 create table mytable (  name text,  age int ); このテーブルからint型のageを列挙したいと思います。 intを読むわけですから EXEC SQL BEGIN DECLARE SECTION; int i; EXEC SQL END DECLARE SECTION; が必要ですよね。あとはさっぱり分かりません。

  • SQLでできますか?

    SQLでできますか? INSERT INTO test (A) VALUES (B)というSQLを発行したいのですが、このSQLのVALUESのBにあたる部分を正規表現的に指定して、一度のクエリで以下のような結果を得たいのです。 1.テーブルhogeのpiyoカラムの値の先頭がappleになっている行を探す。 2.(1.)で抽出した行のidの値をBとする。 例えば、以下のようにです。 ■皆様が回答してくださるSQL文(1クエリで行いたい) ???????????? ■皆様が回答してくださるSQL文と同等の意味を持つSQL群 INSERT INTO test (A) VALUES (100) INSERT INTO test (A) VALUES (101) INSERT INTO test (A) VALUES (102) ■テーブルhoge _____id_____piyo__________created 1. 100 applebanana 2009/01/02 2. 101 apple_12345 2009/01/03 3. 102 appleXXXXXX 2009/01/04 4. 103 bananananan 2009/01/05 5. 104 ringogogogo 2009/01/06 分かりにくい説明ですが、お詳しい方、どうかご回答の程を宜しくお願いいたします。

    • ベストアンサー
    • MySQL
  • INSERT文とUPDATE文の使い分け

    いつもお世話になっております。 MYSQLで x_table ID SUBID  1  aaa 2 aaa 3 bbb 4 ccc というテーブルがあったとして、「IDが 1 かつ、SUB_IDが aaa」の項目が存在する場合はUPDATE、存在しない場合はINSERT、という形でSQLを使い分けたいと考えています。 現在は SELECT * FROM x_table WHERE ID=1 AND SUBID='aaa' というSQLでレコードの存在確認をし、その結果によりif文でUPDATE文とINSERT文を使い分けているのですが、レコードの存在確認とINSERTやUPDATEのSQLを一つにまとめる事が出来るようなやり方って無いでしょうか? 無さそうな場合は「無い」とだけでも答えていただけるとうれしいです。

    • ベストアンサー
    • PHP
  • Doctrine(ORM)での複数行Insert

    PHP/MySQL/Doctrineで開発しております。 配列フィールドを持つオブジェクトを永続化する際、パフォーマンスのため、INSERTの際に複数行をまとめてInsertしたいのですが、Doctrine_Recordのsaveメソッドを使うと、配列の各要素に対して1つのSQLが発行されてしまいます。 DQL等を用いた複数行Insertは可能でしょうか? また、不可能であれば、PHPでそういったことが可能であるORMは存在しますでしょうか? 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • BULK INSERTのエラー取得は可能なのでしょうか?

    こんばんは。 お世話になります。 SQL Server初心者です。 現在、CSVファイルに出力された他のデータベース(Paradox)のデータをSQL Server2005に移行するためのツールを作成しています。 Paradoxでは、以下のように、(1)と(2)のレコードが存在した場合、重複エラーとならなかったのですが、SQL Serverでは、当然ながら、重複エラーとなってしまいます。  (1)aaaaa, 1, あいうえお  (2)AAAAA, 1, かきくけこ  ※aaaaaとAAAAAが主キーの場合 CSVファイルのレコードは、多いもので700万件も含まれ、これを1行読み込み、既存データか否かをチェックし、既存の場合はINSERTしないという処理を700万回繰り返すと、相当な時間がかかり、性能向上を求められています。 そのため、BULK INSERTを使用する方向で検討してみました。 しかし、CSVファイルに主キー重複したレコードが存在すると、エラーが返されますが、BULK INSERTでは、どのレコードでエラーになったかまでは取得することができません。 ずいぶん、調べてみたのですが、無理のようでした。 BULK INSERTでエラーとなる箇所を特定する方法は本当にないでしょうか? もし、無理ならば、何か他にエラー箇所を特定して速くINSERTするコマンド、方法はないでしょうか? お知恵をお借りしたく、よろしくお願いいたします。

  • 既存データをINSERT文にして出力するツールは?

    Oracleデータベース内のデータを取り出して、SQL(INSERT文)として出力できるツールは無いでしょうか。 例えば TABLE_A というテーブル内に次のようなレコードが入っているものとして、下記のようなINSERT文を生成してくれるフリーの(もしくは安価な)ツールは無いでしょうか。 MY_ID MY_NAME MY_DESC ----- ------- ------- 00001 hoge1 説明1 00002 hoge2 説明2 insert into TABLE_A (MY_ID, MY_NAME, MY_DESC) values ('00001', 'hoge1', '説明1'); insert into TABLE_A (MY_ID, MY_NAME, MY_DESC) values ('00002', 'hoge2', '説明2'); CSV形式で出力するようなツールは見つけたのですが、INSERT文にしてくれるツールがなかなか見つかりませんでした。 「PL/SQL Developer」というものを見つけたので試してみたところ、これはまさにうってつけのツールだったのですが、それなりのお値段(25,000円ほど?)でした。 このような本格的なツールでなくて良いので、フリーソフト(もしくは安価な)で無いでしょうか。 ちなみに Oracle のバージョンは Oracle 10g です。