開発者向け機能:API:テーブル操作:レコード一括作成・更新
## 概要
APIを使用して複数レコードを作成または更新する事ができます。
指定したキー項目が一致するレコードがある場合はそのレコードを更新、一致するレコードがない場合は新規作成(※1)を行います。
キー項目が無い場合は全てのレコードの新規作成を行います。
処理が正常に終了した場合に通知タイミングがインポート後の[通知](/ja/manual/table-management-notification)を行います。
(※1)KeyNotFoundCreateパラメータがfalseの場合は新規作成されません。
## 注意事項
1. レコード単位で処理をおこない途中がエラーが発生した場合は以降の処理は中止されます。
## 制限事項
1. 対象の[サイト](/ja/manual/site)に「作成」および「更新」権限が必要です。
1. パラメータ[General.json](/ja/manual/general.json)の「BulkUpsertMax」で設定した値を超えたレコードがあった場合は処理を行いません。
## 事前準備
APIの操作を行う前に[APIキーの作成](/manual/api-key)を実施してください。
## リクエスト
下記のリクエスト形式で、jsonデータを送信します。
|設定項目|値|
|:--|:--|
|HTTPメソッド|POST|
|Content-Type |application/json|
|文字コード|UTF-8|
|URL|http://{サーバー名}/api/items/{サイトID}/bulkupsert(※2)|
|Body|以下のjsonデータを参考のこと|
(※2){サーバー名}、{サイトID}の部分は、適宜、環境に合わせて編集してください。
pleasanter.netの場合は以下の形式になります。
https\://pleasanter.net/fs/api/items/{サイトID}/bulkupsert
##### JSON
```
{
"ApiVersion": "1.1",
"ApiKey": "345yuAjA6789dA09d8uj6...",
"Keys": [
"ClassA"
],
"KeyNotFoundCreate": true,
"Data": [
{
"Title": "新機能XXを開発する1",
"ClassHash": {
"ClassA": "RC0001"
}
},
{
"Title": "新機能XXを開発する2",
"ClassHash": {
"ClassA": "RC0002"
}
}
]
}
```
|カラム|設定内容|
|:--|:--|
|Keys|キーとなる項目を指定。複数の項目を指定可能。(省略時:全てのレコードの新規作成)|
|KeyNotFoundCreate|キーと一致するレコードが無い場合に新規作成します。(省略時:true)|
|Data|レコードの配列|
#### 指定するキー項目について
指定したキー項目をもとにAPIによるレコード作成・更新(upsert)を行います。キー項目の指定は以下のパラメータで指定します。
キー項目の指定が無い場合は全てのレコードの新規作成を行います。
詳細につきましては、下記の (a)キーが無い場合、(b)単一キーの場合、(c)複合キーの場合 をご参照ください。
#### APIによる画像の挿入について
BodyにImageHashを指定することで[内容](/ja/manual/table-management-body)[コメント](/ja/manual/table-management-comments)[説明](/ja/manual/table-management-column-description)項目に画像を挿入することが可能です。
更新系のAPI(update/upsert)で本機能によるレコード更新を行う場合、既存レコードの該当項目は[内容](/ja/manual/table-management-body)[説明](/ja/manual/table-management-column-description)項目では上書き、[コメント](/ja/manual/table-management-comments)項目では追加となります。また、更新系のAPIで[内容](/ja/manual/table-management-body)[説明](/ja/manual/table-management-column-description)項目に登録する文字列を指定するBodyやDescriptionHashを省略した状態でImageHashのみを指定すると、上書きではなく追加となります。
##### ImageHashの指定方法
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
overflow:hidden;padding:10px 5px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
.tg .tg-0lax{text-align:left;vertical-align:top}
</style>
<table class="tg">
<thead>
<tr>
<th class="tg-0lax">第1階層</th>
<th class="tg-0lax">第2階層</th>
<th class="tg-0lax">第3階層</th>
<th class="tg-0lax">説明</th>
<th class="tg-0lax">例</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-0lax" rowspan="9">ImageHash</td>
<td class="tg-0lax" rowspan="6">Body</td>
<td class="tg-0lax">HeadNewLine</td>
<td class="tg-0lax">画像を挿入する際の先頭の改行有無をtrue/falseで指定します。省略した場合は改行無しになります。</td>
<td class="tg-0lax">true</td>
</tr>
<tr>
<td class="tg-0lax">EndNewLine</td>
<td class="tg-0lax">画像を挿入する際の末尾の改行有無をtrue/falseで指定します。省略した場合は改行無しになります。</td>
<td class="tg-0lax">true</td>
</tr>
<tr>
<td class="tg-0lax">Position</td>
<td class="tg-0lax">同じリクエスト内で対象項目に文字列を設定する場合に画像を何文字目に挿入するかを数値で指定します。-1を指定した場合および省略した場合は末尾に挿入されます。</td>
<td class="tg-0lax">3</td>
</tr>
<tr>
<td class="tg-0lax">Alt</td>
<td class="tg-0lax">alt属性(Webブラウザで画像が表示できないときに、画像の代わりに表示されるテキスト)に挿入する文字列を指定します。省略した場合は「image」が設定されます。</td>
<td class="tg-0lax">hayato</td>
</tr>
<tr>
<td class="tg-0lax">Extension</td>
<td class="tg-0lax">Binariesテーブルに登録するファイル拡張子を指定します。省略した場合は「.png」が設定されます。</td>
<td class="tg-0lax">.jpeg</td>
</tr>
<tr>
<td class="tg-0lax">Base64</td>
<td class="tg-0lax">Base64エンコードした画像のバイナリデータを文字列で指定します。ImageHashを指定する場合、省略はできません。</td>
<td class="tg-0lax">iVBORw0KG…(以下略)</td>
</tr>
<tr>
<td class="tg-0lax">Comments</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">-</td>
</tr>
<tr>
<td class="tg-0lax">DescriptionA</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">-</td>
</tr>
<tr>
<td class="tg-0lax">DescriptionB</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">(同上)</td>
<td class="tg-0lax">-</td>
</tr>
</tbody>
</table>
#### APIによるプロセスの実行について
リクエストデータに、プロセスIDを指定し、プロセスを実行することが可能です。
##### 事前準備
事前に[プロセス](/ja/manual/process)を設定してください。
##### 制限事項
APIからプロセスを実行する場合、プロセスで設定した入力検証は適用されません。
##### プロセスの指定方法
|設定項目|説明|例|
|:--|:--|:--|
|ProccessId|プロセスのIDを指定します。|1|
#### (a)キーが無い場合
Keys パラメータが無い場合には、全てのレコードを新規作成します。
KeyNotFoundCreate パラメータの値は無視されます。
##### JSON
```
{
"ApiVersion": 1.1,
"ApiKey": "145Afa9AF2A10SafaA21641...",
"Data": [
{
"Title": "新機能XXを開発する1",
"Body": "ボディ1",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0001",
"ClassB": "分類2"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明1"
},
"CheckHash": {
"CheckA": false
},
"ImageHash": {
"Body": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageBody",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
},
"DescriptionA": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageDescriptionA",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
}
}
},
{
"Title": "新機能XXを開発する2",
"Body": "ボディ2",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0002",
"ClassB": "分類3"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明2"
},
"CheckHash": {
"CheckA": false
}
}
]
}
```
#### (b)単一キーの場合
Keys パラメータにキーとなる項目の項目名を配列形式で設定します。Keys に指定した項目について、パラメータで指定した値と一致するレコードを検索します。
下記の例では、1つ目のレコード「ClassA」項目の値が "RC0001" のレコードを検索します。 2つ目のレコード「ClassA」項目の値が "RC0002"のレコードを検索します。
レコードを検索した結果に応じて下記の処理が実行されます。
1. 対象のレコードが存在しなかった場合: レコードが新規作成されます。ただしKeyNotFoundCreateパラメータがfalseの場合は新規作成されません。
1. 対象のレコードが1件存在した場合: そのレコードが更新されます。
1. 対象のレコードが複数件存在した場合: レコードの作成・更新は行われず、エラーレスポンスが返却されます。
##### JSON
```
{
"ApiVersion": 1.1,
"ApiKey": "145Afa9AF2A10SafaA21641...",
"Keys": [
"ClassA"
],
"KeyNotFoundCreate": true,
"Data": [
{
"Title": "新機能XXを開発する1",
"Body": "ボディ1",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0001",
"ClassB": "分類2"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明1"
},
"CheckHash": {
"CheckA": false
},
"ImageHash": {
"Body": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageBody",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
},
"DescriptionA": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageDescriptionA",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
}
}
},
{
"Title": "新機能XXを開発する2",
"Body": "ボディ2",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0002",
"ClassB": "分類3"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明2"
},
"CheckHash": {
"CheckA": false
}
}
]
}
```
#### (c)複合キーの場合
Keys パラメータに複数の項目名を設定した場合、Keys に指定したすべての項目について、パラメータで指定した値と一致するレコードを検索します。
下記の例では、1つ目のレコード「ClassA」項目の値が "RC0001" かつ、「ClassB」項目の値が "001" のレコードを検索します。 2つ目のレコード「ClassA」項目の値が "RC0001" かつ、「ClassB」項目の値が "002" のレコードを検索します。
1. 対象のレコードが存在しなかった場合: レコードが新規作成されます。ただしKeyNotFoundCreateパラメータがfalseの場合は新規作成されません。
1. 対象のレコードが1件存在した場合: そのレコードが更新されます。
1. 対象のレコードが複数件存在した場合: レコードの作成・更新は行われず、エラーレスポンスが返却されます。
##### JSON
```
{
"ApiVersion": 1.1,
"ApiKey": "145Afa9AF2A10SafaA21641...",
"Keys": [
"ClassA",
"ClassB"
],
"KeyNotFoundCreate": true,
"Data": [
{
"Title": "新機能XXを開発する1",
"Body": "ボディ1",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0001",
"ClassB": "001"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明1"
},
"CheckHash": {
"CheckA": false
},
"ImageHash": {
"Body": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageBody",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
},
"DescriptionA": {
"HeadNewLine": true,
"EndNewLine": true,
"Position": 3,
"Alt": "imageDescriptionA",
"Extension": ".jpeg",
"Base64": "iVBORw0KG..."
}
}
},
{
"Title": "新機能XXを開発する2",
"Body": "ボディ2",
"CompletionTime": "2018/3/31",
"ProcessId": 1,
"ClassHash": {
"ClassA": "RC0001",
"ClassB": "002"
},
"NumHash": {
"NumA": 100
},
"DateHash": {
"DateA": "2019/01/01"
},
"DescriptionHash": {
"DescriptionA": "説明2"
},
"CheckHash": {
"CheckA": false
}
}
]
}
```
## レスポンス
下記の形式のjsonデータが返却されます。
##### JSON
レコードが新規作成された場合
```
{
"Id": 12345,
"StatusCode": 200,
"LimitPerDate": 10000,
"LimitRemaining": 9994,
"Message": "記録テーブル: 1 件追加し、0 件更新しました。"
}
```
レコードが更新された場合
```
{
"Id": 12345,
"StatusCode": 200,
"LimitPerDate": 10000,
"LimitRemaining": 9994,
"Message": "記録テーブル: 0 件追加し、1 件更新しました。"
}
```
サイト単位でエラーとなった場合
```
{
"Id": 12345,
"StatusCode": 401,
"Message": "認証できませんでした。"
}
```
レコード単位でエラーとなった場合
```
{
"Id": 12345,
"StatusCode": 500,
"Message": "記録テーブル:エラーが発生しました。0 件追加し、0 件更新。\nIndex:1(ClassA=RC00011)\nエラー内容:条件に一致するレコードが複数存在します。"
}
```
パラメータ[General.json](/ja/manual/general.json)の「BulkUpsertMax」で設定した値を超えたレコードがあった場合。
```
{
"Id": 12345,
"StatusCode": 500,
"Message": "1000 行を超えるデータは一度にインポートできません。"
}
```
## 対応バージョン
|No|内容|対応バージョン|
|:--:|:--|:--|
|1|機能追加|1.4.6.0以降|
## エラー時の確認事項
[・API使用時の注意点やエラーが発生する場合の確認事項](/manual/faq-api)
[・FAQ:変更後の設定ファイルやAPIリクエスト(JSON形式)が正しく認識されない場合の確認事項](/manual/faq-json-format)