Macro/投稿/187

http://sakura.qp.land.to/?Macro%2F%C5%EA%B9%C6%2F187


Top > Macro > 投稿 > 187

ODBC経由でSQL文実行

  • ページ: Macro/投稿
  • 作者: t_ishida?
  • カテゴリー: js
  • 投稿日: 2008-02-05 (火) 20:14:26

メッセージ

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
  /***************************************************************************************************
  * SQLのなんか.js
  * 概要
  *   エディタの中でODBCでDBにつないでSQL文を実行したり、レコードを取得したりを出来る。
  *   DAO3.6が無いと使えない
  *   うん、はじめてサクラエディタのマクロって作ったが、Emacs系のマクロAPIの便利さが身にしみてよく分かる。
  * @ver 0.0.0.1
 ***************************************************************************************************/
 //
 // 環境設定部
 //
 
 
 //DBのユーザー名
 var us  = "";
 
 //パスワード
 var ps  = "";
 
 //使うDB
 var db  = "";
 
 //ODBCデータソース名
 var dsn = "";
 
 var cn_str = "ODBC" +
              ";DSN="  + dsn +
              ";UID="  + us  +
              ";PWD="  + ps  +
              ";DB="   + db;
 
 // 実行結果の出力先(現在はcurrentしか選べん)
 //var output            = 'other';
 var output              = 'current';
 
 //currentの時、出力結果を毎度書き換えるかどうか(y/n)
 var clear_prevoutput    = 'y';
 
 //実行後に現在の行に戻るかどうか?(y/n)
 var return_current_line  = 'y';
 
 //DAOをnew ActiveXObjectするための文字列
 var DAO = "DAO.DBEngine.36";
 
 //DAOのデータタイプ
 var dat_type = {
   //数値
   16 : "数値", 9  : "数値", 1  : "数値" ,
   2  : "数値", 5  : "数値", 17 : "数値" ,
   20 : "数値", 7  : "数値", 21 : "数値" ,
   15 : "数値", 3  : "数値", 4  : "数値" ,
   11 : "数値", 19 : "数値", 6  : "数値" ,
  
   //日付
   22 : "日付"  , 23 : "日付" , 8  : "日付" ,
  
   //文字列
   12 : "文字列", 10 : "文字列" , 18 : "文字列"
 };
 var db_type = 'sqlserver';
 var cmd_query = [
   '@tab' ,
   '@col'
 ];
 var commands = {
   '@tab' : showTables ,
   '@col' : showColumns
 };
 var cmd_styntax = new RegExp( '^(' + cmd_query.join('|') + ')', 'i');
 
 //SELECT系のシンタックスを正規表現で指定
 var query_syntax = [
   'select .+(?: from)?'
 ];
 var sql_query    = new RegExp('^(?:' + query_syntax.join('|') + ')', 'i');
 
 //実行系のシンタックスを正規表現で指定
 var no_query_syntax =[
   'select .+ into' ,
   'update .+ set' ,
   'insert into' ,
   'create index' ,
   'create table' ,
   'alter table' ,
   'drop table' ,
   'delete from' ,
   'truncate table ' ,
   'bulk insert' ,
 ];
 var sql_no_query = new RegExp('^(?:' + no_query_syntax.join('|') + ')', 'i');
 
 //////////////////////////////////////////////////////////////////////////////////
 // 処理部 => こっから下はやる気のある人以外は触ったらイヤン
 //////////////////////////////////////////////////////////////////////////////////
 var st_no        = ExpandParameter('$y') - 0;
 var st_col       = ExpandParameter('$x') - 0;
 
 // 出力先の変更(バージョン1.15.11からしか、TraceOutは使えないらしいので現在は無意味)
 var say;
 if( output == 'other') {
   ActivateWinOutput();
   say = function(s){ TraceOut(s,1); };
 } else {
   say = function(s){ InsText(s + "\r\n"); };
 }
 
 var param;
 if( IsTextSelected() ){
   param = GetSelectedString();
   BeginSelect();
 } else {
   for( var i=1; i <= GetLineCount(0); i++ ) {
     param += GetLineStr(i);
   }
 }
 param = param.replace( /^\s*--.*(\r\n|\r|\n)/, "" ).replace( /(?:\r\n|\r|\n| +)/g, " " );
 if( GetLineCount(0) == ExpandParameter("$y") ){ GoFileEnd(0); say("\n\n"); Jump(st_no); }
 if( output == "current" && clear_prevoutput == "y" ){
   SearchNext("@---- SQL");
   if ( !IsTextSelected() ) {
     while( GetLineStr(0) != '' ) {
       Down(0);
       if( GetLineCount(0) == ExpandParameter( "$y" ) ) break;
     }
   } else {
     GoLineTop(0);
     while( !GetLineStr(0).match(/@---- __END__ ----@/) ){
       Down_Sel();
       if( GetLineCount(0) == ExpandParameter( "$y" ) ) break;
     }
    
     if ( GetLineStr(0).match(/@---- __END__ ----@/) ) {
       Delete();
       DeleteLine();
     }
   }
 }
 var dbe = new ActiveXObject( DAO );
 var ws  = dbe.CreateWorkspace( "", "", "", 1 );
 var cn;
 try {
   cn  = ws.OpenConnection( "", 3, false, cn_str );
 } catch(e){
   say( "接続エラー:" + e.message );
   say( "繋がらないから設定確認して" );
   throw(e);
 }
 var arr_sql = param.split(";");
 ws.BeginTrans();
 say( "@---- SQLを実行するよ(select系以外は何も出なけりゃ成功だよ) ----@" );
 for(var i = 0; i < arr_sql.length; i++ ){
  var s   = arr_sql[i].replace( /^\s*(.+)$/, "$1" );
   if( s.match( /^\s+$/ ) ) continue;
   try {
     if      ( s.match( cmd_styntax )  ) say( commands[RegExp.$1]( s, cn ) );
     else if ( s.match( sql_query )    ) say( getRecordTable( s, cn ) );
     else if ( s.match( sql_no_query ) ) cn.Execute( s );
     else                                continue;
   } catch(e) {
     ws.Rollback();
     say( "SQL実行エラー(ろーるばっくしたよ):" );
     if( dbe.Errors.Count ){
       for( var i = 0; i < dbe.Errors.Count; i++ ){
         say( "\t" + dbe.Errors(i).Description );
       }
     } else {
       say( "\t" + e.message );
     }
     say( "駄目だったやつ:");
     say( "\t" + s );
     break;
   }
   say("");
 }
 say( "@---- __END__ ----@" );
 ws.CommitTrans();
 cn.Close();
 if ( return_current_line == 'y' ) Jump( st_no );
 else                              GoFileEnd( 0 );
 
 function getRecordTable( s, cn ){
   var rs;
   var ret = '';
   rs = cn.OpenRecordSet( s, 2 );
   if( rs.EOF ) return '取れなかったよ';
   rs.MoveLast();
   if ( ( rs.RecordCount * rs.Fields.Count ) > 30000 ) {
     rs.Close();
     return 'そんなにいっぱい書けないっす(^_^;)'
   }
   rs.MoveFirst();
   var ln  = '';
   var fld = null;
   for( var i = 0; i < rs.Fields.Count; i++ ) {
     if ( ln ) ln += "\t";
     fld = rs.Fields.Item(i);
     ln += fld.Name + "(" + dat_type[fld.Type] + ")";
   }
   ret = ln + "\r\n";
  
   while( rs.EOF == false ){
     ln = '';
     for( var i=0;i < rs.Fields.Count; i++ ){
       if ( ln ) ln += "\t";
       fld = rs.Fields.Item(i);
       if      ( fld.Value == null )            ln += "NULL";
       else if ( dat_type[fld.Type] == '日付' ) ln += formatDate(fld.Value);
       else                                     ln += fld.Value;
     }
     ret += ln + "\r\n";
     rs.MoveNext();
   }
   rs.Close();
   return ret;
 }
 
 function formatDate(src){
   var dd = new Date(src);
   var y = dd.getYear(),  m  = dd.getMonth() + 1, d = dd.getDate();
   var h = dd.getHours(), mi = dd.getMinutes(),   s = dd.getSeconds();
   if ( y  < 2000 ) y += 1900;  
   if ( m  < 10 )   m  = "0" + m;
   if ( d  < 10 )   d  = "0" + d;
   if ( h  < 10 )   h  = "0" + h;
   if ( mi < 10 )   mi = "0" + mi;
   if ( s  < 10 )   s  = "0" + s;
   return y + "/" + m + "/" + d + " " + h + ":" + mi + ":" + s;
 }
 
 function showTables( cmd, cn ){
   var tab_nm = '';
   if( cmd.match( /like +(\S+)$/i ) ) tab_nm = RegExp.$1;
   var s = {
     'sqlserver' : function(){
       var x = "select o.name as tab_name from sysobjects o where o.name like @param@ order by o.id";
       if( tab_nm ) x = x.replace( /@param@/, tab_nm );
       else         x = x.replace( /where .+ order by/, "order by" );
       return x;
     }
   }[db_type]();
   return getRecordTable( s, cn );
 }
 
 function showColumns( cmd, cn ){
   var col_nm = '' , tab_nm = '';
   if ( cmd.match( / tab +like +(\S+)/i ) ) tab_nm = RegExp.$1;
   if ( cmd.match( /col +like +(\S+)/i ) )  col_nm = RegExp.$1;
   var s = {
     'sqlserver'  :  function(){
       var x = "select "                         +
               "   o.name   as tab_name "        +
               ",  c.colorder as col_no "        +
               ",  c.name   as col_nm "          +
               ",  t.name   as type_nm "         +
               ",  c.length as col_len "         +
               ",  p.value  as col_com "         +
               "from "                           +
               "   sysobjects    o  "            +
               ",  syscolumns    c  "            +
               ",  systypes      t  "            +
               ",  sysproperties p  "            +
               "where "                          +
               "     o.id        = c.id "        +
               "and  o.id       *= p.id "        +
               "and  c.xtype     = t.xtype "     +
               "and  c.colorder *= p.smallid "   +
               "and  o.xtype     = 'U' "         +
               "and  p.type      =  4 "          +
               "and  o.name      like @param1@ " +
               "and  c.name      like @param2@ " +
               "order by  "                      +
               "    o.id ,  "                    +
               "    c.colorder";
       if   ( tab_nm ) x = x.replace( /@param1@/i, tab_nm );
       else            x = x.replace( /and +o.name +like +@param1@/,' ');
       if   ( col_nm ) x = x.replace( /@param2@/i, col_nm );
       else            x = x.replace( /and +c.name +like +@param2@/,' ');
       return x;
     }
   }[db_type]();
   return getRecordTable( s, cn );
 }

リロード   新規 編集 凍結 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2014-02-03 (月) 18:47:37 (1688d)