2012年11月22日木曜日

mysqlでCURSORを使ったループ(LOOP)でINSERT

#まず削除

DROP PROCEDURE IF EXISTS myProc;

#作成

#日付をプロシジャーの引数に設定、戻り値はない

CREATE PROCEDURE myProc(IN aft_date DATETIME)

BEGIN

  DECLARE done INT DEFAULT FALSE;#ループを抜けるフラグ

  DECLARE dt DATETIME;#日付ごとにループ

  DECLARE tdays CURSOR FOR SELECT aod as as_of_date FROM date_ots where aod > aft_date order by aod asc;#ループする日付たち

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;#日付が全部回ったら終了フラグ



  OPEN tdays;#取得する



  read_loop: LOOP#ループ開始

    FETCH tdays INTO dt;

    IF done THEN

      LEAVE read_loop;#ループを抜ける

    END IF;



insert into fund_correction_indices

select null,f.id,rt.aod,0,ci4.correction_value * rt.rate1 * rt.rate2 * rt.rate3 * rt.rate4,ci4.correction_value * rt.rate1 * rt.rate2 * rt.rate3 * rt.rate4,0

from 

(

    select dto.aod,f.fund_small_category_id,

        avg(ci0.correction_value/ci1.correction_value) as rate1,

        avg(ci1.correction_value/ci2.correction_value) as rate2,

        avg(ci2.correction_value/ci3.correction_value) as rate3,

        avg(ci3.correction_value/ci4.correction_value) as rate4,

        avg(ci0.correction_value/ci4.correction_value) as rate_,

        dto.4thd 

    from date_ots dto 

        inner join fund_correction_indices ci0 on ci0.as_of_date = dto.aod

        inner join funds f on f.id = ci0.fund_id and f.kind not in ('平均','指数'

        inner join fund_correction_indices ci1 on ci1.as_of_date = dto.1std and ci1.fund_id = ci0.fund_id

        inner join fund_correction_indices ci2 on ci2.as_of_date = dto.2ndd and ci2.fund_id = ci0.fund_id

        inner join fund_correction_indices ci3 on ci3.as_of_date = dto.3rdd and ci3.fund_id = ci0.fund_id

        inner join fund_correction_indices ci4 on ci4.as_of_date = dto.4thd and ci4.fund_id = ci0.fund_id

    where dto.aod = dt

        and f.fund_small_category_id >=1 and f.fund_small_category_id <=57

    group by fund_small_category_id,dto.aod

) rt

    inner join funds f on f.fund_small_category_id = rt.fund_small_category_id and f.kind = '平均'

    inner join fund_correction_indices ci4 on ci4.as_of_date = rt.4thd and ci4.fund_id = f.id

order by f.id,rt.aod 

ON DUPLICATE KEY UPDATE 

  value=ci4.correction_value * rt.rate1 * rt.rate2 * rt.rate3 * rt.rate4,

  correction_value=ci4.correction_value * rt.rate1 * rt.rate2 * rt.rate3 * rt.rate4;

  END LOOP;

  CLOSE tdays;

END



呼び出し

CALL myProc('2012-02-01')


もしCREATE PROCEDUREの時「Column count of mysql.proc is wrong」みたいなエラーが出たら

$ mysql_upgrade -uroot -p
rootパスワード入力

で直してあげてください。

INSERT ON DUPLICATE KEY UPDATE

feel this useful,copy from here
http://stackoverflow.com/questions/548541/insert-ignore-vs-insert-on-duplicate-key-update


CREATE TABLE `users_partners` (
`uid` int(11) NOT NULL DEFAULT '0',
`pid` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`,`pid`),
KEY `partner_user` (`pid`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...1 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1);
...0 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1) ON DUPLICATE KEY UPDATE uid=uid
...0 row(s) affected

REPLACE INTO users_partners (uid,pid) VALUES (1,1)
...2 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...3 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4) ON DUPLICATE KEY UPDATE uid=uid
...3 row(s) affected

REPLACE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...5 row(s) affected

SQLOLEDB INSERT トランザクション付き

Sub InsertDB()
    Global cnn As New ADODB.Connection
    cnn.Open "Provider=SQLOLEDB;" & _
             "Data Source=" & srvName & ";" & _
             "Initial Catalog=" & databaseName & ";", user, pass

    Dim cmdIns As ADODB.Command
    Set cmdIns = New ADODB.Command
    cmdIns.ActiveConnection = cnn
    cmdIns.CommandTimeout = 0
    cmdIns.CommandType = adCmdText
    cmdIns.CommandText = "INSERT INTO myTable(id,name,price,bigmoney) VALUES(?,?,?,?)"

    'DB定義: id int
    Set param = cmdIns.CreateParameter("id", adInteger, adParamInput)
    cmdIns.Parameters.Append param

    'DB定義: name nvarchar(50)
    Set param = cmdIns.CreateParameter("name", adVarWChar, adParamInput, 100)
    cmdIns.Parameters.Append param

    'DB定義: price decimal(12, 6)
    Set param = cmdIns.CreateParameter("price", adDecimal, adParamInput)
    param.Precision = 12 '全桁数
    param.NumericScale = 6 '小数桁数 こんな感じ:123456.123456
    cmdIns.Parameters.Append param

    'DB定義: price bigmoney(12, 0)
    Set param = cmdIns.CreateParameter("bigmoney", adDecimal, adParamInput)
    param.Precision = 12 '全桁数
    param.NumericScale = 0 '小数桁数 こんな感じ:123456123456
    cmdIns.Parameters.Append param

    cmdIns.Parameters("id").Value = 1
    cmdIns.Parameters("name").Value = "かげんぱぱ"
    cmdIns.Parameters("price").Value = 1999.123
    cmdIns.Parameters("bigmoney").Value = 10000000000

    cnn.BeginTrans 'トランザクション開始
    cmdIns.Execute 'インサート実行
    'cnn.RollbackTrans 'ロールバック
    cnn.CommitTrans 'コミット
End Sub

2012年11月14日水曜日

mysqlテーブルコピー


/* スキーマをコピーしてテーブル作成 */
> CREATE TABLE mytable_copy LIKE mytable;
/* mytableテーブルのデータをINSERT */
> INSERT INTO mytable_copy SELECT * FROM mytable;

2012年11月9日金曜日

googleだからできること

面白い!
Googleスプレッドシートを新規して
A1セルに「mazda」
A2セルに「honda」
そしてctrlを押しながら、引っ張ったら…ほらね!

2012年11月2日金曜日

vbaで定義済みの名前NamesとRangeの参照

Sub name2range_test()
Debug.Print ThisWorkbook.Names.Count
For i = 1 To ThisWorkbook.Names.Count
    Debug.Print ThisWorkbook.Names.Item(i).Name & " -> " & ThisWorkbook.Names.Item(i).RefersTo
    Debug.Print ThisWorkbook.Names.Item(i).Name & " -> " & ThisWorkbook.Names.Item(i).RefersToRange.Address
Next
'あるいは
Debug.Print Range(ThisWorkbook.Names.Item(1).RefersTo).Address

End Sub