SQLInsert[conn,table,cols,data]
SQL接続中の表にデータを挿入する.
SQLInsert
SQLInsert[conn,table,cols,data]
SQL接続中の表にデータを挿入する.
詳細とオプション
- SQLInsertを使うためには,まずNeeds["DatabaseLink`"]を使って DatabaseLink をロードする必要がある.
- 使用可能なオプション
-
"ColumnSymbols" None 結果に関連付けるシンボル "EscapeProcessing" True プされたJDBC関数シンタックスを変換する "FetchSize" Automatic JDBCドライバへの結果セットの大きさの提示 "GetAsStrings" False すべての結果を文字列として返す "GetGeneratedKeys" False 更新されたレコードに関連付けられたキーを返す "MaxFieldSize" Automatic 可変長の列のタイプのバイト制限 "MaxRows" Automatic 返される最大行数 "ShowColumnHeadings" False 結果とともに列見出しを返すかどうか "Timeout" $SQLTimeout クエリのタイムアウト "BatchSize" 1000 この大きさのレコードのバッチで挿入を処理する "JavaBatching" True Wolfram言語層ではなく,Java層でパラメータのバッチ処理を行う
例題
すべて開く すべて閉じる例 (1)
Needs["DatabaseLink`"]このセクションの例を実際に試してみて,記載の通りに動作しなかった場合は,データベースの例の使用で述べているようにDatabaseLink`DatabaseExamples`パッケージを使ってデータベースをインストールするか,もとの状態に戻す必要がある可能性がある.
conn = OpenSQLConnection["demo"];SQLCreateTable[conn, SQLTable["TEST"], {SQLColumn["COL1", "DataTypeName" -> "INTEGER"], SQLColumn["COL2", "DataTypeName" -> "DOUBLE"]}];SQLInsert[conn, "TEST", {"COL1", "COL2"}, {10, 10.5}]SQLSelect[conn, "TEST"]SQLInsert[conn, "TEST", {"COL1", "COL2"}, {{10, 10.5}, {20, 55.1}}]SQLSelect[conn, "TEST"]SQLDropTable[conn, "TEST"];CloseSQLConnection[conn]; スコープ (1)
日付と時刻の使用 (1)
Needs["DatabaseLink`"]日付と時刻のデータは,DateObject,TimeObject,またはSQLDateTimeを使って与えることができる.コラムタイプがDATE,TIME,DATETIME である表を作成する:
conn = OpenSQLConnection[JDBC["HSQL(Memory)", "temp"]];SQLCreateTable[conn, SQLTable["DateTimeTable"], {SQLColumn["Col1", "DataTypeName" -> "INTEGER", "Nullable" -> True],
SQLColumn["Col2", "DataTypeName" -> "DATE", "Nullable" -> True], SQLColumn["Col3", "DataTypeName" -> "TIME", "Nullable" -> True],
SQLColumn["Col4", "DataTypeName" -> "TIMESTAMP", "Nullable" -> True]}];lower = Round@AbsoluteTime[Now];
upper = Round@AbsoluteTime[DatePlus[Now, {1, "Year"}]];
randomRow[i_Integer] := With[{t = DateList@DateObject[RandomInteger[{lower, upper}]]},
{RandomInteger[100], DateObject[t], TimeObject[t[[-3 ;; ]]], SQLDateTime[t]}
]in = Table[randomRow[i], {i, 10 ^ 4}];
RandomSample[in, 1]SQLInsert[conn, "DateTimeTable", {"Col1", "Col2", "Col3", "Col4"}, in]//Length選択された日付と時刻は頭部SQLDateTimeで返される:
Column[out = SQLSelect[conn, SQLTable["DateTimeTable"], "MaxRows" -> 3]]Inner[Apply, {Identity, DateObject, TimeObject, Identity}, #, List]& /@ out//ColumnSQLDelete[conn, "DateTimeTable"]DATE列は与えられた日付構造の分,時間,秒の要素を無視する.TIME列は与えられた日付構造の年,月,日の要素を無視する:
SQLInsert[conn, "DateTimeTable", {"Col2", "Col3"}, {
{DateObject[], DateObject[]}
}];SQLSelect[conn, "DateTimeTable", {"Col2", "Col3", "Col4"}]日付と時刻の両方の要素を記録する列のタイプについては,時刻は与えられていない場合は00:00:00であるとみなされる.日付は与えられていない場合は今日であるとみなされる:
SQLDelete[conn, "DateTimeTable"];
SQLInsert[conn, "DateTimeTable", {"Col4"}, {
{DateObject[{2019, 1, 1}]},
{TimeObject[]}
}];
SQLSelect[conn, "DateTimeTable", {"Col4"}]//ColumnSQLDropTable[conn, "DateTimeTable"];CloseSQLConnection[conn];オプション (2)
"BatchSize" (1)
Needs["DatabaseLink`"];
Needs["JLink`"];長いパラメータリストを含むクエリを生成する際に,使用メモリ量と速度のトレードオフをバッチサイズで調整する:
AddToClassPath["/Users/me/Documents/DatabaseLink/drivers"];
connSpec = {JDBC["oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@server.domain.com:1521:xe"], Username -> "GUEST", Password -> "GUEST"};conn = OpenSQLConnection@@connSpecSQLCreateTable[conn, SQLTable["SCRATCH"], {
SQLColumn["A", "DataTypeName" -> "FLOAT"],
SQLColumn["B", "DataTypeName" -> "INTEGER"],
SQLColumn["C", "DataTypeName" -> "VARCHAR", "DataLength" -> 128]
}]randomRows[n_] := Transpose[{RandomInteger[10000, n], RandomReal[1, n], RandomChoice[WordData[], n]}];data = randomRows[2 * 10 ^ 5];ByteCount@datajavaMem[] := Module[{rt},
LoadJavaClass["java.lang.Runtime"];
rt = Runtime`getRuntime[];
rt@totalMemory[](* allocated; some is free for jvm use *)
];
memReport[] := TableForm[List@{MemoryInUse[], javaMem[], MemoryInUse[] + javaMem[]}, TableHeadings -> {None, {"Kernel", "Java", "Total"}}]memReport[]小さいバッチサイズでクエリを実行すると,Java側のメモリ使用量は比較的小さくなる:
AbsoluteTiming@SQLInsert[conn, "SCRATCH", {"A", "B", "C"}, data,
"BatchSize" -> 10
]//FirstmemReport[]SQLDelete[conn, "SCRATCH"];
CloseSQLConnection[conn];
ReinstallJava[];
conn = OpenSQLConnection@@connSpec;
memReport[]大きいバッチサイズでもう一度実行すると,必要なサーバートリップが少なくなる:
AbsoluteTiming@SQLExecute[conn, "INSERT INTO SCRATCH (A, B, C) VALUES (?, ?, ?)",
data,
"BatchSize" -> 100000
]//FirstmemReport[]SQLDropTable[conn, "SCRATCH"]CloseSQLConnection[conn];"JavaBatching" (1)
Needs["DatabaseLink`"];
Needs["JLink`"];パラメータのバッチ処理をJava層からWolfram言語層に切り換え,速度を落とす代りにメモリ使用量を減らす:
AddToClassPath["/Users/me/Documents/DatabaseLink/drivers"];
connSpec = {JDBC["oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@server.domain.com:1521:xe"], Username -> "GUEST", Password -> "GUEST"};conn = OpenSQLConnection@@connSpecSQLCreateTable[conn, SQLTable["SCRATCH"], {
SQLColumn["A", "DataTypeName" -> "FLOAT"],
SQLColumn["B", "DataTypeName" -> "INTEGER"],
SQLColumn["C", "DataTypeName" -> "VARCHAR", "DataLength" -> 128]
}]randomRows[n_] := Transpose[{RandomInteger[10000, n], RandomReal[1, n], RandomChoice[WordData[], n]}];data = randomRows[5 * 10 ^ 4];ByteCount@datajavaMem[] := Module[{rt},
LoadJavaClass["java.lang.Runtime"];
rt = Runtime`getRuntime[];
rt@totalMemory[](* allocated; some is free for jvm use *)
];
memReport[] := TableForm[List@{MemoryInUse[], javaMem[], MemoryInUse[] + javaMem[]}, TableHeadings -> {None, {"Kernel", "Java", "Total"}}]memReport[]AbsoluteTiming@SQLInsert[conn, "SCRATCH", {"A", "B", "C"}, data,
"JavaBatching" -> True,
"BatchSize" -> 10
]//FirstmemReport[]SQLDelete[conn, "SCRATCH"];
CloseSQLConnection[conn];
ReinstallJava[];
conn = OpenSQLConnection@@connSpec;
memReport[]AbsoluteTiming@SQLExecute[conn, "INSERT INTO SCRATCH (A, B, C) VALUES (?, ?, ?)",
data,
"JavaBatching" -> False,
"BatchSize" -> 10
]//FirstmemReport[]SQLDropTable[conn, "SCRATCH"];CloseSQLConnection[conn];考えられる問題 (1)
DateObjectはTimeZoneオプションの設定が入力されなかった場合にはデフォルトの$TimeZoneを使用する. 時刻帯の数値は,その日付が夏時間に相当する場合でも調整されない.
$TimeZoneこの時刻帯設定はDateObject[{2017,1,1}]で使用される.
data = {25, DateObject[{2017, 3, 12}], TimeObject[] , DateObject[{2017, 1, 1}]};SQLInsert[conn, "DateTimeTable", {"Col1", "Col2", "Col3", "Col4"}, data]1SQLDateTimeが返す時間は「米国シカゴ」のデフォルトの時刻帯を使って返される.
SQLSelect[conn, "DateTimeTable"]{{25, SQLDateTime[{2017, 3, 11}], SQLDateTime[{10, 45, 39.}], SQLDateTime[{2016, 12, 31, 23, 0, 0.}]}}この問題を回避するために,名前付きの時刻帯IDまたは$TimeZoneEntityを使用する.
data = {26, DateObject[{2017, 3, 12}, TimeZone -> "America/Chicago"], TimeObject[] , DateObject[{2017, 1, 1}, TimeZone -> $TimeZoneEntity]};SQLInsert[conn, "DateTimeTable", {"Col1", "Col2", "Col3", "Col4"}, data]1SQLSelect[conn, "DateTimeTable"]{{26, SQLDateTime[{2017, 3, 12}], SQLDateTime[{10, 46, 30.}], SQLDateTime[{2017, 1, 1, 0, 0, 0.}]}}