Stored Procedure で動的に Query を生成・実行したいトキは多々ある。
ので、よく使うシステム Stored Procedure がある。
それが『 sp_executesql 』。
ところが。
これの細かい仕様を理解せずに今まで使用しておりました。
Stored を組み始めて・・・早数ヶ月。お恥ずかしい。
[ sp_executesql ] のパラメーターは大雑把に ( 詳細はBOL参照 )
@stmt ( SQL ステートメント: 必須 )
,@params ( @stmt で使用するパラメーター変数定義(型 , IN / OUT ) : 既定値 NULL )
,@param1 ( @params の値設定 : 既定値 NULL )
で、第一引数の「@stmt」に注意があったんですよ。
今日、BOL をきちんと読んだら書いてあった。
--*--*--*--*--*
~。+ 演算子で 2 つの文字列を連結するなどの複雑な Unicode 式は使用できません。
--*--*--*--*--*
あたしはコレを知らず。
「@stmt」の型は 『NVARCHAR(MAX)』だけど、「+ 演算子で 2 つの文字列を連結する」と、どうもストレージを最大に使えないんだかなんだか、文字列が切り詰められちゃう。
( N''プレフィックスをつけると 4000 文字位。つけないと 8000文字位 )
で、Query が不完全になってエラーを発すると。。。
そんなワケで、『NVARCHAR(MAX)』って『NVARCHAR(4000)』と変わらない??
と勘違いしていました。
無知っておそろしい。つくづく。
ちなみに、『NVARCHAR(MAX)』のサイズ説明は BOL には下記のようにあります。(抜粋)
--*--*--*--*--*
max はストレージの最大サイズが 2^31-1 バイトであることを示しています。
ストレージのサイズは、入力文字数の 2 倍のバイト数に 2 バイトを足した数です。
--*--*--*--*--*
単純に計算して・・・536870911 文字??
( 計算苦手なんで違うかも )
今更だけど、知ってよかった。で、メモ。
2009年3月18日水曜日
2009年2月20日金曜日
[SQL_Server] Query で割算の見落とし。
【目的】Queryで割算して、小数点第一位までパーセンテージを求める。
ええ、常識かもしれないんですけどね、MEMO。
割算には [ / ](スラッシュ) を用いるワケですが、
「整数 ÷ 整数」して、戻り値には小数点付の精度を求める場合、ちょっと一手間必要。
というのも、「整数(A) ÷ 整数(B)」の戻り値は『整数』だそうで。
だから、[ 整数A ] か [ 整数B ] (若しくは両方)を、演算前に
小数持ちタイプのデータ型に型変換してあげる必要があると。
** 例 **
SELECT ( 20 / 57 ) * 100 AS Straight
,( CAST( 20 AS FLOAT ) / 57 ) * 100 AS castFLOAT_Single
,( CAST( 20 AS FLOAT ) / CAST( 57 AS FLOAT ) ) * 100 AS castFLOAT
,( CAST( 20 AS DECIMAL ) / 57 ) * 100 AS castDecimal_Single
,( CAST( 20 AS DECIMAL ) / CAST( 57 AS DECIMAL ) ) * 100 AS castDecimal;
[Result]
Straight : 0
castFLOAT_Single : 35.0877192982456
castFLOAT : 35.0877192982456
castDecimal_Single: 35.087700
castDecimal : 35.0877192982456140
** ** **
というコトで、ジブンは片側だけ [ FLOAT ] にキャストしてあげる方法をとった。
** 解決 **
SELECT CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,1 ) AS DECIMAL(4 ,1) ) AS N'切捨て'
,CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,0 ) AS DECIMAL(4 ,1) ) AS N'四捨五入';
** **** **
何故に更に [ DECIMAL(4 ,1) ] にキャストしているかは、実行してみればわかる。
ええ、常識かもしれないんですけどね、MEMO。
割算には [ / ](スラッシュ) を用いるワケですが、
「整数 ÷ 整数」して、戻り値には小数点付の精度を求める場合、ちょっと一手間必要。
というのも、「整数(A) ÷ 整数(B)」の戻り値は『整数』だそうで。
だから、[ 整数A ] か [ 整数B ] (若しくは両方)を、演算前に
小数持ちタイプのデータ型に型変換してあげる必要があると。
** 例 **
SELECT ( 20 / 57 ) * 100 AS Straight
,( CAST( 20 AS FLOAT ) / 57 ) * 100 AS castFLOAT_Single
,( CAST( 20 AS FLOAT ) / CAST( 57 AS FLOAT ) ) * 100 AS castFLOAT
,( CAST( 20 AS DECIMAL ) / 57 ) * 100 AS castDecimal_Single
,( CAST( 20 AS DECIMAL ) / CAST( 57 AS DECIMAL ) ) * 100 AS castDecimal;
[Result]
Straight : 0
castFLOAT_Single : 35.0877192982456
castFLOAT : 35.0877192982456
castDecimal_Single: 35.087700
castDecimal : 35.0877192982456140
** ** **
というコトで、ジブンは片側だけ [ FLOAT ] にキャストしてあげる方法をとった。
** 解決 **
SELECT CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,1 ) AS DECIMAL(4 ,1) ) AS N'切捨て'
,CAST( ROUND( ( CAST( 20 AS FLOAT ) / 57 ) * 100 ,1 ,0 ) AS DECIMAL(4 ,1) ) AS N'四捨五入';
** **** **
何故に更に [ DECIMAL(4 ,1) ] にキャストしているかは、実行してみればわかる。
2008年8月22日金曜日
[SQL_Server]bcpユーティリティと「xp_cmdshell」の利用。
【目的】ストアドから、SELECT結果をファイル出力してみよう。
ってコトで、調べつつ組んでみた。
結論から言うと、「xp_cmdshell」は権限がなくて使えなかった。
(ローカルの SQL Server ではなくて、共有のテストサーバーを利用しているので、権限変更できない)
でも、折角なのでメモ。
--*--* bcpユーティリティ
「bcpユーティリティは、一度に1つのテーブルを処理するコマンドラインユーティリティです。」
と説明されています。
SQL Server 2005 ストアドプロシージャプログラミングに書いてある。
この「bcp」を使うと、DBのテーブルからデータをテキストファイルにエクスポート(出力)することが可能。
また、ファイルからDBにインポートすることも可能らしい。(試していない)
bcpユーティリティ詳細(MSDN)
1. 先ず、基本的な形のコマンドを流す。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
-- 特定テーブルを一括出力
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
上記は、
dbHogeというデータベースのdbo(デフォルトのスキーマ名)というスキーマにある、
tbHuge というテーブルのデータを、SQL ServerのあるPC(ローカル)の
【C:\】ドライブ直下に『ListBackUp.csv』というファイル名の CSVファイルに出力する。
ちなみに、指定したファイル名のファイルが既に存在すれば、内容を上書き(元の内容は削除)
して、存在しなければ新規に作成して書き込んでくれる。
ローカルではなく、ネットワーク上の SQL Server とデータをやりとりするには、
「-S」オプションをつけてサーバを指定する必要がある。
この場合のファイル名は、コマンド発行したPC(自分のPC)のパスを指す。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
オプションは他にも色々ある。必要に応じて追記したらいいと思う。
詳細はMSDNで。
2.上記のコマンドを実行すると、出力形式について対話形式で確認が行われる。
指定したテーブルのフィールド数分。
確認される質問は以下な感じ。アタクシがやってみた例。
--------------------------------------------------------------------------------
"フィールド cColA [nchar] のファイルストレージ型を入力してください"
⇒「nchar」と入力してEnter押下
"フィールド cColA [1] のプレフィックス長を入力してください"
⇒「1」と入力してEnter
"フィールド ターミネータ [none] を入力してください"
⇒何も入力しないでEnter
--------------------------------------------------------------------------------
↑は、フィールド一つ分の確認。これが1セット。
指定したテーブルのフィールドが10個あれば、これが10回繰り返される。
「ファイルストレージ型」と「プレフィックス長」については、フィールドのデータ型
などで変わるので、全て同じではない。
3.この確認が終わると、最後の質問がある。
--------------------------------------------------------------------------------
"このフォーマット情報をファイルに保存しますか? [y/n]"
⇒「y」と入力してEnter、もっかいEnter
--------------------------------------------------------------------------------
すると、ファイル出力先に指定したパスに、「ListBackUp.csv」と「bcp.fmt」という
ファイルが作成される。
「ListBackUp.csv」を開いてみると、思ったようにきれいにはデータはできていない。
4.これを整形するために、「bcp.fmt」を編集する。
「bcp.fmt」をメモ帳(NotePad)で開く。
============================================================
============================================================
↑さっき、上記の対話確認の結果作成された内容(らしい)。
1行目 :「9.0」 ⇒ バージョン
2行目 :「5」フィールド数
3行目~:フィールドの出力形式
3行目以降に各々色づけしたのは以下の説明のため。
●1 ファイルでの、フィールド番号
●2 フィールドの データ型
●3 フィールドの プレフィックス長
●4 フィールドの データサイズ
●5 フィールドの 終端文字
●6 DBテーブル内での、フィールド番号
●7 DBテーブル内での、フィールド名
●8 フィールドの 照合順序
正直、「nchar」と入力した項目(1, 2, 5) が『SQLNUMERIC』となっているのは
よくわからん。なぜにニューメリック。
とにもかくにも、コレを以下のように編集と思うように出力される(た)。
太文字。
============================================================
============================================================
フィールド番号1~4 の終端文字を「,」にしたのは、 CSVファイルにしたかったから。
好きなものにしたらいい。
フィールド番号5 は、改行コード。データ1行毎に改行したいので。
6.編集したファイルを名前を付けて保存する。
名称は仮に『OutputList.fmt』にする。保存先はCドライブ直下。
7.編集した『OutputList.fmt』をフォーマットオプションで指定して、データ出力してみる。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
ちょっと中断。編集中。
テーブルの一括出力だけでなく、オプションでクエリを利用することも可能。
ほしいデータだけを出力できる。
ワタクシが使ってみたのは以下な感じ。
ってコトで、調べつつ組んでみた。
結論から言うと、「xp_cmdshell」は権限がなくて使えなかった。
(ローカルの SQL Server ではなくて、共有のテストサーバーを利用しているので、権限変更できない)
でも、折角なのでメモ。
--*--* bcpユーティリティ
「bcpユーティリティは、一度に1つのテーブルを処理するコマンドラインユーティリティです。」
と説明されています。
SQL Server 2005 ストアドプロシージャプログラミングに書いてある。
この「bcp」を使うと、DBのテーブルからデータをテキストファイルにエクスポート(出力)することが可能。
また、ファイルからDBにインポートすることも可能らしい。(試していない)
bcpユーティリティ詳細(MSDN)
1. 先ず、基本的な形のコマンドを流す。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
-- 特定テーブルを一括出力
bcp database名.schema名.table名 out "ファイル出力先パス(ファイル名)" -U username -P password
↓
bcp dbHoge.dbo.tbHuge out "C:\ListBackUp.csv" -U sa -P hogehoge
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
上記は、
dbHogeというデータベースのdbo(デフォルトのスキーマ名)というスキーマにある、
tbHuge というテーブルのデータを、SQL ServerのあるPC(ローカル)の
【C:\】ドライブ直下に『ListBackUp.csv』というファイル名の CSVファイルに出力する。
ちなみに、指定したファイル名のファイルが既に存在すれば、内容を上書き(元の内容は削除)
して、存在しなければ新規に作成して書き込んでくれる。
ローカルではなく、ネットワーク上の SQL Server とデータをやりとりするには、
「-S」オプションをつけてサーバを指定する必要がある。
この場合のファイル名は、コマンド発行したPC(自分のPC)のパスを指す。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
bcp dbHoge.dbo.tbHuge out "C:\ListBackUp.csv" -S 192.168.xx.xx -U sa -P hogehoge
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
オプションは他にも色々ある。必要に応じて追記したらいいと思う。
詳細はMSDNで。
2.上記のコマンドを実行すると、出力形式について対話形式で確認が行われる。
指定したテーブルのフィールド数分。
確認される質問は以下な感じ。アタクシがやってみた例。
--------------------------------------------------------------------------------
"フィールド cColA [nchar] のファイルストレージ型を入力してください"
⇒「nchar」と入力してEnter押下
"フィールド cColA [1] のプレフィックス長を入力してください"
⇒「1」と入力してEnter
"フィールド ターミネータ [none] を入力してください"
⇒何も入力しないでEnter
--------------------------------------------------------------------------------
↑は、フィールド一つ分の確認。これが1セット。
指定したテーブルのフィールドが10個あれば、これが10回繰り返される。
「ファイルストレージ型」と「プレフィックス長」については、フィールドのデータ型
などで変わるので、全て同じではない。
3.この確認が終わると、最後の質問がある。
--------------------------------------------------------------------------------
"このフォーマット情報をファイルに保存しますか? [y/n]"
⇒「y」と入力してEnter、もっかいEnter
--------------------------------------------------------------------------------
すると、ファイル出力先に指定したパスに、「ListBackUp.csv」と「bcp.fmt」という
ファイルが作成される。
「ListBackUp.csv」を開いてみると、思ったようにきれいにはデータはできていない。
4.これを整形するために、「bcp.fmt」を編集する。
「bcp.fmt」をメモ帳(NotePad)で開く。
============================================================
9.0
5
1 SQLNUMERIC 1 19 "" 1 cColA Japanese_CI_AS
2 SQLNUMERIC 1 19 "" 2 vcColB Japanese_CI_AS
3 SQLTINYINT 0 1 "" 3 tiColC ""
4 SQLDATETIME 0 8 "" 4 dtColD ""
5 SQLNUMERIC 1 19 "" 5 cColE Japanese_CI_AS
============================================================
↑さっき、上記の対話確認の結果作成された内容(らしい)。
1行目 :「9.0」 ⇒ バージョン
2行目 :「5」フィールド数
3行目~:フィールドの出力形式
3行目以降に各々色づけしたのは以下の説明のため。
●1 ファイルでの、フィールド番号
●2 フィールドの データ型
●3 フィールドの プレフィックス長
●4 フィールドの データサイズ
●5 フィールドの 終端文字
●6 DBテーブル内での、フィールド番号
●7 DBテーブル内での、フィールド名
●8 フィールドの 照合順序
正直、「nchar」と入力した項目(1, 2, 5) が『SQLNUMERIC』となっているのは
よくわからん。なぜにニューメリック。
とにもかくにも、コレを以下のように編集と思うように出力される(た)。
太文字。
============================================================
9.0
5
1 SYBCHAR 0 19 "," 1 cColA ""
2 SYBCHAR 0 19 "," 2 vcColB ""
3 SYBCHAR 0 1 "," 3 tiColC ""
4 SYBCHAR 0 8 "," 4 dtColD ""
5 SYBCHAR 0 19 "\r\n" 5 cColE ""
============================================================
フィールド番号1~4 の終端文字を「,」にしたのは、 CSVファイルにしたかったから。
好きなものにしたらいい。
フィールド番号5 は、改行コード。データ1行毎に改行したいので。
6.編集したファイルを名前を付けて保存する。
名称は仮に『OutputList.fmt』にする。保存先はCドライブ直下。
7.編集した『OutputList.fmt』をフォーマットオプションで指定して、データ出力してみる。
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
bcp dbHoge.dbo.tbHuge out "C:\ListBackUp.csv" -f C:\OutputList.fmt -U sa -P hogehoge--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
ちょっと中断。編集中。
テーブルの一括出力だけでなく、オプションでクエリを利用することも可能。
ほしいデータだけを出力できる。
ワタクシが使ってみたのは以下な感じ。
2008年8月6日水曜日
[SQL_Server]レコードが○件以上あり、かつ□日以上経過したレコードの抽出(削除)
こんな要望がありました。
操作ログを、一定期間で削除して欲しい。
でも、レコードが100件以内だったら、一定期間が経過していても、
そのユーザーのレコード(操作ログ)は削除しないでほしい。
ちなみに、この対象テーブルには「No列」のようなものはありません。
前回【ROW_NUMBER()を使ってみる】で使用したテーブルです。
これです。
で、前回の「ROW_NUMBER()」が登場するワケです。
とりあえず、こんな感じで。
いきなり削除しちゃうのはアレなんで、まずは抽出してみる。
抽出結果が、「削除したいものである」と確認できたら、
01行目の 'SELECT *' を 'DELETE' に直せばOK。
※エディタな感じで 行に番号付けてみた。
解説:
1つ目のポイントは、03行目の「EXISTS」で条件を指定しているトコロ。
-- というか、要件を満たす条件を指定するには、と考えたトキ、この方法しか思いつかなかった。
2つ目のポイントは、03-10行目で「EXISTS」の条件を、更にサブクエリにしているトコロ。
先ずサブクエリ(04行の「SELECT~」-10行目)で、
仮想の行番号を「ROW_NUMBER()」で付与してテーブルを作ってあげる。
この時点で、ユーザー毎に日付順で行番号が配される。(詳しくは前回を参照)
で、このテーブルを「EXISTS」の条件で SELECTして、
「WHERE句」条件(13行目)で仮想の行番号を指定( Obj.RNum > 100 )する。
こうすることで、100件以内のレコードは条件より外される。
-- ちなみに、サブクエリとして使用しないと、仮想の行番号を「WHERE句」に指定することができない。
-- ソコで初めて作成されるのだから、このQuery内では条件には使えないよね。
あとは、「DATEDIFF()」関数(返り値はINT)で削除期間を指定してあげる。
上記の場合、
DATEDIFF( 日付を, Obj.dtOperationから, 本日日時を引いた ) 数値が、'90' より大きい( > 90 )
なら、という条件になる。
Query一発でできるなんて、ステキング。
操作ログを、一定期間で削除して欲しい。
でも、レコードが100件以内だったら、一定期間が経過していても、
そのユーザーのレコード(操作ログ)は削除しないでほしい。
ちなみに、この対象テーブルには「No列」のようなものはありません。
前回【ROW_NUMBER()を使ってみる】で使用したテーブルです。
これです。
--*--* 操作ログテーブル *--*--*--*--*--
テーブル: tbOperationLog -- 操作履歴を格納するテーブル
カラム: dtOperation DATETIME -- 操作日時
cUserID NCHAR(8) -- 操作ユーザーID
cProgramID NCHAR(8) -- 操作画面ID
vcContents NVARCHAR(2) -- 操作種別コード
--*--*--*--*--*--*--*--*--*--*--*--*--*--
で、前回の「ROW_NUMBER()」が登場するワケです。
とりあえず、こんな感じで。
いきなり削除しちゃうのはアレなんで、まずは抽出してみる。
抽出結果が、「削除したいものである」と確認できたら、
01行目の 'SELECT *' を 'DELETE' に直せばOK。
※エディタな感じで 行に番号付けてみた。
------------------------------------------------------------------------------------------
01: SELECT *
02: FROM tbOperationLog
03: WHERE EXISTS( SELECT *
04: FROM ( SELECT ROW_NUMBER() OVER( PARTITION BY cUserID
05: ORDER BY dtOperation ASC ) AS RNum
06: ,dtOperation
07: ,cUserID
08: ,cProgramID
09: ,vcContents
10: FROM tbOperationLog ) Obj
11: WHERE tbOperationLog.cUserID = Obj.cUserID
12: AND tbOperationLog.dtOperation = Obj.dtOperation
13: AND Obj.RNum > 100
14: AND DATEDIFF( DAY, Obj.dtOperation, CURRENT_TIMESTAMP ) > 90 )
------------------------------------------------------------------------------------------
解説:
1つ目のポイントは、03行目の「EXISTS」で条件を指定しているトコロ。
-- というか、要件を満たす条件を指定するには、と考えたトキ、この方法しか思いつかなかった。
2つ目のポイントは、03-10行目で「EXISTS」の条件を、更にサブクエリにしているトコロ。
先ずサブクエリ(04行の「SELECT~」-10行目)で、
仮想の行番号を「ROW_NUMBER()」で付与してテーブルを作ってあげる。
この時点で、ユーザー毎に日付順で行番号が配される。(詳しくは前回を参照)
で、このテーブルを「EXISTS」の条件で SELECTして、
「WHERE句」条件(13行目)で仮想の行番号を指定( Obj.RNum > 100 )する。
こうすることで、100件以内のレコードは条件より外される。
-- ちなみに、サブクエリとして使用しないと、仮想の行番号を「WHERE句」に指定することができない。
-- ソコで初めて作成されるのだから、このQuery内では条件には使えないよね。
あとは、「DATEDIFF()」関数(返り値はINT)で削除期間を指定してあげる。
上記の場合、
DATEDIFF( 日付を, Obj.dtOperationから, 本日日時を引いた ) 数値が、'90' より大きい( > 90 )
なら、という条件になる。
Query一発でできるなんて、ステキング。
[SQL_Server]ROW_NUMBER() を使ってみる。
SQL Serverでは、'2005'から「ROW_NUMBER()」という機能(関数)を実装したらしい。
私は使ったことないが、Oracleのソレと同じ(?)ようなものみたい。
MSDN⇒ ROW_NUMBER (Transact-SQL)
簡単に言うと、「ROW_NUMBER()」は SELECT した結果(レコードの集合)に対して、
指定された条件で順位付けして番号を振ってくれる便利関数。
ちなみに、「OVER()句」とセットで使用。条件は、この「OVER( 条件 )」に書く。
先月より触り始めた SQL Server の Stored Procude で、これを使う機会がありそうなので、
ちょいと練習で使ってみた。
以下は、操作履歴テーブル【tbOperationLog】を条件なしに(全件)抽出したもの。
※ここで使用するテーブル、カラムはあくまでサンプル。
テーブル: tbOperationLog -- 操作履歴を格納するテーブル
カラム: dtOperation -- 操作日時
cUserID -- 操作ユーザーID
cProgramID -- 操作画面ID
vcContents -- 操作種別コード
サンプル その1:
解説:
「ROW_NUMBER()」は、直後の「OVER( ORDER BY dtOperation ASC )」を条件に順位付けを行う。
サンプル1 では『操作日時( dtOperation )』の昇順( ASC )で順位付けを行った。
ちなみに、コメントアウトで無効にしている最終行の【ORDER BY vcContents】を有効にすると、
順位は「OVER()句」で指定された条件で行われるが、表示される順序がこっちで行われる。
結果:(外側のORDER BY を有効にした場合)
で、条件指定にはもう少し便利なものがある。
「PARTITION BY」というもの。
「ORDER BY 句」の直前に指定する。
私もコレは初めて知ったものなので、とりあえず使ってみる。
サンプル その2:
解説:
「PARTITION BY」を指定すると、順位付けを行うグループを設定できる。
サンプル2 は「操作ユーザーID( cUserID )」内で、『操作日時( dtOperation )』の昇順( ASC )に順位付けを行った。
もちろん、「ORDER BY 句」は降順( DESC )の指定もできますよ。
私は使ったことないが、Oracleのソレと同じ(?)ようなものみたい。
MSDN⇒ ROW_NUMBER (Transact-SQL)
簡単に言うと、「ROW_NUMBER()」は SELECT した結果(レコードの集合)に対して、
指定された条件で順位付けして番号を振ってくれる便利関数。
ちなみに、「OVER()句」とセットで使用。条件は、この「OVER( 条件 )」に書く。
先月より触り始めた SQL Server の Stored Procude で、これを使う機会がありそうなので、
ちょいと練習で使ってみた。
以下は、操作履歴テーブル【tbOperationLog】を条件なしに(全件)抽出したもの。
※ここで使用するテーブル、カラムはあくまでサンプル。
テーブル: tbOperationLog -- 操作履歴を格納するテーブル
カラム: dtOperation -- 操作日時
cUserID -- 操作ユーザーID
cProgramID -- 操作画面ID
vcContents -- 操作種別コード
サンプル その1:
SELECT ROW_NUMBER() OVER( ORDER BY dtOperation ASC ) AS 'RowNum'
,dtOperation AS 'Date'
,cUserID AS 'uID'
,cProgramID AS 'pID'
,vcContents AS 'Code'
FROM tbOperationLog
-- ORDER BY vcContents
;
結果:
RowNum Date uID pID Code
-------- ------------ ---------- ---------- ----
1 2008-01-06 BLOSSOMS A2008085 00
2 2008-02-14 BLOSSOMS C2008086 01
3 2008-03-04 BLOSSOMS A2008085 02
4 2008-06-26 SAKURA39 A2008085 02
5 2008-07-19 BLOSSOMS C2008086 03
6 2008-07-19 SAKURA39 C2008086 03
7 2008-07-27 SAKURA39 C2008086 00
8 2008-08-02 SAKURA39 C2008086 01
解説:
「ROW_NUMBER()」は、直後の「OVER( ORDER BY dtOperation ASC )」を条件に順位付けを行う。
サンプル1 では『操作日時( dtOperation )』の昇順( ASC )で順位付けを行った。
ちなみに、コメントアウトで無効にしている最終行の【ORDER BY vcContents】を有効にすると、
順位は「OVER()句」で指定された条件で行われるが、表示される順序がこっちで行われる。
結果:(外側のORDER BY を有効にした場合)
RowNum Date uID pID Code
-------- ------------ ---------- ---------- ----
1 2008-01-06 BLOSSOMS A2008085 00
7 2008-07-27 SAKURA39 C2008086 00
8 2008-08-02 SAKURA39 C2008086 01
2 2008-02-14 BLOSSOMS C2008086 01
3 2008-03-04 BLOSSOMS A2008085 02
4 2008-06-26 SAKURA39 A2008085 02
5 2008-07-19 BLOSSOMS C2008086 03
6 2008-07-19 SAKURA39 C2008086 03
で、条件指定にはもう少し便利なものがある。
「PARTITION BY」というもの。
「ORDER BY 句」の直前に指定する。
私もコレは初めて知ったものなので、とりあえず使ってみる。
サンプル その2:
SELECT ROW_NUMBER() OVER( PARTITION BY cUserID ORDER BY dtOperation ASC ) AS 'RowNum'
,dtOperation AS 'Date'
,cUserID AS 'uID'
,cProgramID AS 'pID'
,vcContents AS 'Code'
FROM tbOperationLog
;
結果:
RowNum Date uID pID Code
-------- ------------ ---------- ---------- ----
1 2008-01-06 BLOSSOMS A2008085 00
2 2008-02-14 BLOSSOMS C2008086 01
3 2008-03-04 BLOSSOMS A2008085 02
4 2008-07-19 BLOSSOMS C2008086 03
1 2008-06-26 SAKURA39 A2008085 02
2 2008-07-19 SAKURA39 C2008086 03
3 2008-07-27 SAKURA39 C2008086 00
4 2008-08-02 SAKURA39 C2008086 01
解説:
「PARTITION BY」を指定すると、順位付けを行うグループを設定できる。
サンプル2 は「操作ユーザーID( cUserID )」内で、『操作日時( dtOperation )』の昇順( ASC )に順位付けを行った。
もちろん、「ORDER BY 句」は降順( DESC )の指定もできますよ。
2008年6月16日月曜日
[その他]--Firefox3「Download Day」
Firefox(ブラウザ)がNewバージョンの「3」を公開するようです。
明日。
で、24時間内の世界中でのダウンロード合計数で、ギネス登録を目指すらしい。
そして、アタクシはこのイベントに参加しております。
面白そうだったから。
以下のような方は、是非ともダウンロードしてみてください。
・「Google最高っ」な人。
・「Firefox好いよね」な人。
・Firefoxに興味がある人。
・ブラウザを自分好みにカスタマイズ(UI、操作感(プラグイン)など)したい人。
・IEしか使ったことがない、好奇心旺盛な人。
・他のブラウザに飽きた人。
・ギネス登録に参加してみたかった人。
・イベント好きな人。
・レッサーパンダが好きな人。
ダウンロードは簡単ですから。
もちろん、「オレはIE命なんだーっ」という方は無理にダウンロードすることもないのです。
▼クリックしてみたってください(即ダウンロード、ぢゃないです)▼
明日。
で、24時間内の世界中でのダウンロード合計数で、ギネス登録を目指すらしい。
そして、アタクシはこのイベントに参加しております。
面白そうだったから。
以下のような方は、是非ともダウンロードしてみてください。
・「Google最高っ」な人。
・「Firefox好いよね」な人。
・Firefoxに興味がある人。
・ブラウザを自分好みにカスタマイズ(UI、操作感(プラグイン)など)したい人。
・IEしか使ったことがない、好奇心旺盛な人。
・他のブラウザに飽きた人。
・ギネス登録に参加してみたかった人。
・イベント好きな人。
・レッサーパンダが好きな人。
ダウンロードは簡単ですから。
もちろん、「オレはIE命なんだーっ」という方は無理にダウンロードすることもないのです。
▼クリックしてみたってください(即ダウンロード、ぢゃないです)▼
[MySQL]--SELECTで文字化の対応。
【目的】CONCAT()関数で日本語を連結して、文字化したトキの対処。
●切っ掛け
以下の様に、CONCAT()関数を使用して文字を連結して、SELECTで抽出してファイルに出力したら、文字化けした。
*MySQLマニュアル:文字列関数
(各カラムの値: a.intA = 1, a.intB = 2, a.intC = 3 )
[修正前SQL] SELECT CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' )
FROM DataTbl a
[実際の結果] 1蟷エ2繝カ譛・譌・
[欲しい結果] 1年 2ヶ月 3日
で、ネットで検索して解決したので、メモっとくのです。
○解決方法
1.先ず、CONCAT()関数を使用しているカラムの文字セットを確認。
文字セットの確認は、CHARSET(str)関数を使う。
CHARSET()関数は、'str'の文字セットを返してくれる関数。
*MySQLマニュアル:情報関数
[SQL] SELECT CHARSET( CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) )
[結果] binary
文字列(型)で返してほしいのに「binary」という結果。
なので、型を文字列型にキャストすることにした。
2.integer型⇒char型へキャストして、連結する。
キャストには、CAST()関数を使用。
CAST()関数は以下のように使用する。
CAST( 変換する値 AS 変換したい型)
*MySQLマニュアル:キャスト関数と演算子
ちなみに、各値に対してキャストする必要がある。
CONCAT()毎括ってキャストしようとしても、エラーになる。
[例SQL] CAST(CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) AS CHAR)
これはエラーを返される。
で、以下のように修正。
[SQL]SELECT CONCAT( CAST( a.intA ) AS CHAR, '年 ', CAST( a.intB ) AS CHAR, 'ヶ月 ', CAST( a.intC ) AS CHAR, '日' )
FROM DataTbl a
[結果]1年 2ヶ月 3日
うん。思うとおりの結果。各値毎にキャストするのは、ちょいと面倒ですけど。
念のため、CHARSET()関数で文字セットを確認。
[SQL] SELECT CHARSET( CONCAT( CAST( 1 AS CHAR ), '年 ', CAST( 2 AS CHAR ), 'ヶ月 ', CAST( 3 AS CHAR ), '日' ) )
[結果] utf8
OK。
●切っ掛け
以下の様に、CONCAT()関数を使用して文字を連結して、SELECTで抽出してファイルに出力したら、文字化けした。
*MySQLマニュアル:文字列関数
(各カラムの値: a.intA = 1, a.intB = 2, a.intC = 3 )
[修正前SQL] SELECT CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' )
FROM DataTbl a
[実際の結果] 1蟷エ2繝カ譛・譌・
[欲しい結果] 1年 2ヶ月 3日
で、ネットで検索して解決したので、メモっとくのです。
○解決方法
1.先ず、CONCAT()関数を使用しているカラムの文字セットを確認。
文字セットの確認は、CHARSET(str)関数を使う。
CHARSET()関数は、'str'の文字セットを返してくれる関数。
*MySQLマニュアル:情報関数
[SQL] SELECT CHARSET( CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) )
[結果] binary
文字列(型)で返してほしいのに「binary」という結果。
なので、型を文字列型にキャストすることにした。
2.integer型⇒char型へキャストして、連結する。
キャストには、CAST()関数を使用。
CAST()関数は以下のように使用する。
CAST( 変換する値 AS 変換したい型)
*MySQLマニュアル:キャスト関数と演算子
ちなみに、各値に対してキャストする必要がある。
CONCAT()毎括ってキャストしようとしても、エラーになる。
[例SQL] CAST(CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) AS CHAR)
これはエラーを返される。
で、以下のように修正。
[SQL]SELECT CONCAT( CAST( a.intA ) AS CHAR, '年 ', CAST( a.intB ) AS CHAR, 'ヶ月 ', CAST( a.intC ) AS CHAR, '日' )
FROM DataTbl a
[結果]1年 2ヶ月 3日
うん。思うとおりの結果。各値毎にキャストするのは、ちょいと面倒ですけど。
念のため、CHARSET()関数で文字セットを確認。
[SQL] SELECT CHARSET( CONCAT( CAST( 1 AS CHAR ), '年 ', CAST( 2 AS CHAR ), 'ヶ月 ', CAST( 3 AS CHAR ), '日' ) )
[結果] utf8
OK。
2008年6月13日金曜日
[MySQL]--抽出テーブルに行番号を付ける
【目的】SELECTした抽出結果に、行番号のフィールドを付加する。
②「SELECT」で、変数『@i』のカラムを指定し、インクリメント(@i:=@i+1)するようにする。
ただし、他のカラムは「*」では取得できないので、抽出したいフィールド名を指定する。
-----------------------------------------------------------①先ず、「SET」で変数『@i』に'0'をセットする。SET @i:=0;
SELECT @i:=@i+1 AS 'No',
clmA,
clmB,
clmC
FROM tblHoge
WHERE ・・・・・
------------------------------------------------------------
「SET」のクエリと、「SELECT」のクエリを流す形。
②「SELECT」で、変数『@i』のカラムを指定し、インクリメント(@i:=@i+1)するようにする。
ただし、他のカラムは「*」では取得できないので、抽出したいフィールド名を指定する。
2008年5月21日水曜日
[vc2005] -- DataTable.Computeメソッドの利用。 (Sum()のみ)
これ見るときは、下の『[vc2005] -- カラム名&型の設定』と併せるとちょっぴり幸せかも。
以下のコードに登場する『dtSetTable』は、既に宣言されているDataTable。
以下のコードに登場する『dtSetTable』は、既に宣言されているDataTable。
// 総合計行追加DataRow dtTotalRow = dtSetTable.NewRow();
dtTotalRow[0] = "総合計"; // 名称
int k = 0;
foreach (DataColumn col in dtSetTable.Columns) // 列数分、
{
if (k != 0)
{
dtTotalRow[k] = dtSetTable.Compute("Sum(" + col.ColumnName + ")", null); // 集計。条件はなし
}
k++;
}
dtSetTable.Rows.Add(dtTotalRow); // テーブルに総合計行を追加
DataTable.Computeメソッドについて:
細かい事(型の種類とか、条件の設定とか)はMSDNに記載されているので記載しない。
自分が使ったとこだけメモ。
DataTable.Compute("Sum(ColumnName)", filter)
↑これで、対象データをSumしてくれる。
「filter」は「式で評価される行を制限するフィルタ」と、MSDNに書いてある。
「filter」を指定しない場合は、「null」で動いた。(vb2005なら「Nothing」)。
Sum()以外でも、Count()などのよく利用されるものは用意されている模様。
ちなみに、文字列で指定しないといけない。(""で括る。)
「filter」も、利用するときは文字列にしないといけない。
そして、この集計関数を利用する場合は、DataColumn の型指定が正しくないとダメ。
(intとか。stringぢゃ計算しちくりんばい)
アタシも何度怒られたことか・・・VS2005に。
[vc2005] -- DataTableのカラム名&型設定。
自分、VBに慣れ親しんできたんですが(といっても数ヶ月)、VCアプリの修正頼まれまして。。。
同じ「.NET」利用でも、構文の書き方が若干違うので戸惑う。
【目的】作成した DataTable へ、新しいカラム(列)を追加する。
以下のコードについて:
自作関数にて取得した DataTable (コード内:dtGetData)から、新しい DataTable (コード内:dtSetTable )へデータをコピーすることが目的のコードの一部。
上記にあたり、列名も同じくコピーしようってトコロ。
※コードに登場する Get_DataTbl() は自作関数。返り値はDataTable。
ここではこの関数の詳細は記載しない。
●補足
「駄目なやり方」の方法だと、列名は設定できるけど、型の設定ができない。
型の設定はなくてもいいときは、一応これでも動くことは動く。
※でも色々間違ってる。
・文字列型で宣言しているし、
・カラム名の取得を「.ToString()」で無理やりしてる。
ただ、今回どうしても型を設定したかった。
ここにコードは載せていないが、上記コードを含むプログラムで行っている内容が
1.取得した DataTable『dtGetData』から、
新しい DataTable 『dtSetTable』へデータをコピーする処理を12回繰り返し、
2.dtSetTable に溜めたデータを列毎に集計して「総合計」として最終行に追加する。
というもので、この集計の際に【DataTable.Compute メソッド】を使いたかったのよ。
【.Compute メソッド】さん、便利関数。Sum() とかCount() とか Max() とか、手軽にやってくれる。
あ、これもメモっとこう。次で。
同じ「.NET」利用でも、構文の書き方が若干違うので戸惑う。
【目的】作成した DataTable へ、新しいカラム(列)を追加する。
以下のコードについて:
自作関数にて取得した DataTable (コード内:dtGetData)から、新しい DataTable (コード内:dtSetTable )へデータをコピーすることが目的のコードの一部。
上記にあたり、列名も同じくコピーしようってトコロ。
※コードに登場する Get_DataTbl() は自作関数。返り値はDataTable。
ここではこの関数の詳細は記載しない。
DataTable dtGetData = new DataTable();
DataTable dtSetTable = new DataTable();
// DataTable 取得&保持。
dtGetData = Get_DataTbl();
// 列(名)設定。
dtSetTable.Columns.Add("年月"); // 一つ目のカラムを設定
foreach (DataColumn Col in dtGetData.Columns)
{
// ↓駄目なやり方。(最初にかいたコード)
//string strCol = Col.ToString();
//dtSetTable.Columns.Add(strCol);
// ↓MSDNに載っていた方法。
DataColumn dtCol = new DataColumn(Col.ColumnName); // 新しいDataColumnを作成し、カラム名を設定する
dtCol.DataType = System.Type.GetType("System.Int32"); // 作成したDataColumnの型を設定する
dtSetTable.Columns.Add(dtCol); // 作成したDataColumnを、テーブルに追加する
Console.WriteLine("[Debug--ColumnName]" + dtCol.ColumnName); // デバッグ出力(カラム名)
}
●補足
「駄目なやり方」の方法だと、列名は設定できるけど、型の設定ができない。
型の設定はなくてもいいときは、一応これでも動くことは動く。
※でも色々間違ってる。
・文字列型で宣言しているし、
・カラム名の取得を「.ToString()」で無理やりしてる。
ただ、今回どうしても型を設定したかった。
ここにコードは載せていないが、上記コードを含むプログラムで行っている内容が
1.取得した DataTable『dtGetData』から、
新しい DataTable 『dtSetTable』へデータをコピーする処理を12回繰り返し、
2.dtSetTable に溜めたデータを列毎に集計して「総合計」として最終行に追加する。
というもので、この集計の際に【DataTable.Compute メソッド】を使いたかったのよ。
【.Compute メソッド】さん、便利関数。Sum() とかCount() とか Max() とか、手軽にやってくれる。
あ、これもメモっとこう。次で。
[vb2005] -- 継承コントロールの作成_その3。 (利用)
作成した自作コントロールを、実際に別のアプリで利用してみる。
※アタシは結構これに悩んで調べてわからなくて、
試行錯誤の上やっと利用方法がわかったのでメモるのです。
以下では、自作したコントロールのdllファイル名を、仮に『hoge.dll』とする。
①ファイル追加
1.新規に作成したプロジェクトの、ソースファイルディレクトリにビルドしてできた「hoge.dll」ファイルを入れる。
2.プロジェクトを開いてソリューションエクスプローラを確認すると、ディレクトリに追加した「hoge.dll」が表示される。
アイコン(?)は点線な感じ。 この時点では、まだ「hoge.dll」を参照できていない。
(ファイルはいるけど利用できない状態。)
3.ソリューションエクスプローラの「hoge.dll」にカーソルを当てて、右クリック。
4.メニューが表示されるので【プロジェクトに含める(J)】をクリック。
5.このプロジェクトに「hoge.dll」を追加完了。
②参照設定
1.ソリューションエクスプローラの【参照設定】にカーソルを当てて、右クリック。
2.メニューが表示されるので【参照の追加(R)】をクリック。
3.『参照の追加』が表示されるので、プロジェクトに含めた 「hoge.dll」を選択して[OK]を押す。
4.追加した「hoge.dll」を参照する設定完了。
③アイテムの追加
1.ツールボックスで右クリック。
2.メニューが表示されるので【アイテムの選択(I)】をクリック。
3.『ツールボックス アイテムの選択』が開くので、[参照(B)]を押す。
4.プロジェクトに含めた 「hoge.dll」を選択して[OK]を押す。
5.[OK]を押す。
6.hogeコントロールの追加完了。
基底のコントロールと同じように利用できるようになる。
※注意
もしかしたら、上記には無駄があるかもしれない。
色々弄りながらやっと辿りついたもんで。。。
でも、これ全部やって使えるようになったんだよね。
※アタシは結構これに悩んで調べてわからなくて、
試行錯誤の上やっと利用方法がわかったのでメモるのです。
以下では、自作したコントロールのdllファイル名を、仮に『hoge.dll』とする。
①ファイル追加
1.新規に作成したプロジェクトの、ソースファイルディレクトリにビルドしてできた「hoge.dll」ファイルを入れる。
2.プロジェクトを開いてソリューションエクスプローラを確認すると、ディレクトリに追加した「hoge.dll」が表示される。
アイコン(?)は点線な感じ。 この時点では、まだ「hoge.dll」を参照できていない。
(ファイルはいるけど利用できない状態。)
3.ソリューションエクスプローラの「hoge.dll」にカーソルを当てて、右クリック。
4.メニューが表示されるので【プロジェクトに含める(J)】をクリック。
5.このプロジェクトに「hoge.dll」を追加完了。
②参照設定
1.ソリューションエクスプローラの【参照設定】にカーソルを当てて、右クリック。
2.メニューが表示されるので【参照の追加(R)】をクリック。
3.『参照の追加』が表示されるので、プロジェクトに含めた 「hoge.dll」を選択して[OK]を押す。
4.追加した「hoge.dll」を参照する設定完了。
③アイテムの追加
1.ツールボックスで右クリック。
2.メニューが表示されるので【アイテムの選択(I)】をクリック。
3.『ツールボックス アイテムの選択』が開くので、[参照(B)]を押す。
4.プロジェクトに含めた 「hoge.dll」を選択して[OK]を押す。
5.[OK]を押す。
6.hogeコントロールの追加完了。
基底のコントロールと同じように利用できるようになる。
※注意
もしかしたら、上記には無駄があるかもしれない。
色々弄りながらやっと辿りついたもんで。。。
でも、これ全部やって使えるようになったんだよね。
[vb2005] -- 継承コントロールの作成_その2。 (デバッグ)
部品の動作を確認するためには、部品単体ではできない。
このため、デバッグ用のプロジェクトを同じソリューション内に作成する必要がある。
このデバッグ用プロジェクトのフォームへ作成した部品を貼り付けて、やっと動作確認できるようになる。
①デバッグ用プロジェクトの作成
1.ソリューションエクスプローラで「ソリューション’ソリューション名’」にカーソルを当てて、右クリックする。
2.メニューが表示されるので【追加 -> 新しいプロジェクト(N)】をクリックする。
『新しいプロジェクトの追加』が表示される。
3.「Windows アプリケーション」を選択。
プロジェクト名を入力して、[OK]を押す。
4.ソリューションエクスプローラにプロジェクトが追加され、このプロジェクトのフォームが表示される。
②デバッグ方法
1.表示されたフォーム(Form1)に、自作したコントロールを乗せる。
自作したコントロールは、ツールボックスに表示されている。
※ ツールボックスに自作コントロールがない場合は、一度ビルドすればOK。
2.ビルドする。
3.あとはデバッグ用アプリを、好きにプログラムる。
●注意
ビルドしたときに、ArgmentExceptionをスローする場合がある。
この場合は、デバッグ用に作成したプロジェクトをスタートアッププロジェクトに設定すればOK。
※ 細かい理由は説明できない(勉強不足)。
○スタートアップ プロジェクトに設定方法
1.ソリューションエクスプローラで、デバッグ用に作成したプロジェクトにカーソルを当てて、右クリック。
2.メニューが表示されるので【スタートアップ プロジェクトに設定(A)】をクリックする。
3.ビルドしてみる。
このため、デバッグ用のプロジェクトを同じソリューション内に作成する必要がある。
このデバッグ用プロジェクトのフォームへ作成した部品を貼り付けて、やっと動作確認できるようになる。
①デバッグ用プロジェクトの作成
1.ソリューションエクスプローラで「ソリューション’ソリューション名’」にカーソルを当てて、右クリックする。
2.メニューが表示されるので【追加 -> 新しいプロジェクト(N)】をクリックする。
『新しいプロジェクトの追加』が表示される。
3.「Windows アプリケーション」を選択。
プロジェクト名を入力して、[OK]を押す。
4.ソリューションエクスプローラにプロジェクトが追加され、このプロジェクトのフォームが表示される。
②デバッグ方法
1.表示されたフォーム(Form1)に、自作したコントロールを乗せる。
自作したコントロールは、ツールボックスに表示されている。
※ ツールボックスに自作コントロールがない場合は、一度ビルドすればOK。
2.ビルドする。
3.あとはデバッグ用アプリを、好きにプログラムる。
●注意
ビルドしたときに、ArgmentExceptionをスローする場合がある。
この場合は、デバッグ用に作成したプロジェクトをスタートアッププロジェクトに設定すればOK。
※ 細かい理由は説明できない(勉強不足)。
○スタートアップ プロジェクトに設定方法
1.ソリューションエクスプローラで、デバッグ用に作成したプロジェクトにカーソルを当てて、右クリック。
2.メニューが表示されるので【スタートアップ プロジェクトに設定(A)】をクリックする。
3.ビルドしてみる。
2008年4月28日月曜日
[vb2005] -- 継承コントロールの作成_その1。(準備)
【目的】汎用的なコントロールの作成、利用。
01.『Windowsコントロールライブラリ』で新規作成する。
02.『UserControl1』が作成されるので、「コードを表示」する。
03.コードは以下のようになっている
Public Class UserControl1
End Class
04.下記のように継承コードを一文追加する。
(下記はラベルコントロールの継承)
Public Class UserControl1
Inherits System.Windows.Forms.Label ' ← Inherits = 継承
End Class
05.すると、「System.Windows.Forms.Label」の下に警告の波線が表示される。
06.この一文にカーソルを当てると、赤丸感嘆符と以下のようなメッセージが表示される。
「クラス 'UserControl1' に指定された基本クラス 'System.Windows.Forms.Label' は、
その他の partial 型の 1 つである基本クラス 'System.Windows.Forms.UserControl' と
異なることはできません。」
07.このエラーを解消するために、赤丸感嘆符にカーソルを当ててクリックする。
08.以下の選択肢がリンクで表示される。
・System.Windows.Forms.Label から継承するために UserControl1 を変更します。
・System.Windows.Forms.UserControl から継承するために UserControl を変更します。
09.「System.Windows.Forms.Label から継承するために UserControl1 を変更します。」をクリックする。
10.すると、エラー一覧に次のエラーが表示される。
説明 :'AutoScaleMode' は 'ソリューション名.UserControl1' のメンバではありません。
ファイル :UserControl1.Designer.vb
行 :26
列 :9
プロジェクト:(プロジェクト名)
11.このエラーをダブルクリックする。
12.エラーの箇所がエディタに表示される。
このエラーは『UserControl1.Designer.vb』にあるので、このファイルが開く。
13.すると、26行目の「Me.AutoScaleMode」の下に警告の波線が表示されている。
14.この一文をコメントアウト、もしくは削除する。
15.「UserControl1.Designer.vb」を保存して、閉じる。
16.これで準備完了。後は好きにプログラムる。
※ 「10」のエラーや「05」のエラーの理由。
プロジェクト作成すると、最初は「System.Windows.Forms.UserControl」を
継承して作成されており、自動生成されるデザイン定義ファイル「~.Designer.vb」
も最初は「Inherits System.Windows.Forms.UserControl」と記載されている。
併せて、System.Windows.Forms.UserControlのプロパティ設定が記載されている。
今回のエラーは「~.Designer.vb」に記載されていたUserControlのプロパティである
「Me.AutoScaleMode」が、「System.Windows.Forms.Label 」に互換しない
(Label のプロパティでない)ために起こった。
「~.Designer.vb」ファイルは、「「Inherits ・・・」の部分を修正してくれても、
このプロパティのところは自動修正できないらしい。。。
2008年4月23日水曜日
[vb2005] -- MDBのテーブルから主キー情報を取得する。
整理は後程。ひとまずメモる。
Dim OleDbCn As New OleDbConnection() '○ OLEDBのクラスインスタンス
Dim SchemaTbl As DataTable ' 取得情報保持用データテーブル' 接続先DB
Dim strDtSrc As String
strDtSrc = "PROVIDER=Microsoft.jet.OLEDB.4.0;" & _
"DATA SOURCE=./XXX.mdb;"' 対象テーブル
Dim strTblName As String
strTblName = "TBL_SAKURA"Try
OleDbCn.ConnectionString = strDtSrc
OleDbCn.Open()SchemaTbl = OleDbCn.GetOleDbSchemaTbl( & _
OleDbSchemaGuid.Primary_Keys, _
New Object() { Nothing, Nothing, strTblName } )' ItemArray は配列で全ての値を取得する。ので、
' この配列分 For文をループさせている
For i As Integer = 0 To SchemaTbl.Rows(0).ItemArray.Length - 1
' 全ての配列の値を、出力
Debug.WriteLine( SchemaTbl.Rows(0).Item(i).ToString() )
Next i' 主キーが存在すれば、行を取得する ( Rows.Count は "1" 以上 )
If SchemaTbl.Rows.Count > 0 Then
'----Debug---------------------
Debug.WriteLine( "主キーを発見。" )
Debug.WriteLine( "項目名:" & SchemaTbl.Rows(0).Item(3).ToString() )
'------------------------------
Else
'----Debug---------------------
Debug.WriteLine( "主キーは見つかりません。" )
'------------------------------
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "エラー:SchemaCheck")
Finally
'○ DB閉鎖
If OleDbCn.State = ConnectionState.Open Then
OleDbCn.Close()
End If
End Try
登録:
投稿 (Atom)