はしくれSEめも

SEに必要情報をめも程度に残していこうと思っています。

【Handsontable】readOnly 読取専用

f:id:coogi-se:20210804235542p:plain

読取専用

Handsontable(ハンズオンテーブル)では、簡単にセルを読取専用にできます。
本日は、そのやり方についてご紹介します。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    readOnly: true,
  });
});

上記のやり方でもできたと思いますが、
これだと汎用的ではないので、もう一つ。 条件付き書式のような書き方もできますが、以下の方がスマートに書けます。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    columns: function(col) {
      return {
        readOnly: col == 1 || col == 3,
      }
    },
  });
});

おまけ

途中からreadOnly(読み取り専用)にする場合は、updateSettingsを使用します。
updateSettingsは、Handsontableを構築した際のオプションに適用されます。
使用していないオプションには、適用されません。

以下の場合は、columnsに対し設定を更新しています。

hot.updateSettings({
  columns: function() {
    return {
      readOnly: true
    }
  }
});

関連記事

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

【SQL Server】おすすめ初期設定

f:id:coogi-se:20210805104840p:plain


SQL Serverのオプションを最適化するための
おすすめ初期設定をまとめました。

照合順序

SQL Server では、文字の大小関係を比較する場合の基準を照合順序 (collation) と呼んでいます。
例えば、「朝」と「海」ではどちらが大きいのか、「あ」「ア」「ア」を大きい順に並べた場合どのように並ぶのかといった、
文字の大小関係を決めているのが照合順序です。

実はSQL Serverのデフォルトだと、アルファベットの大文字と小文字を区別しない設定になっています。
※濁点、半濁点は区別します。

そこで、アルファベットの大文字と小文字を区別するため、以下の設定をおすすめします。

おすすめ:Japanese_CS_AS_KS_WS
※デフォルト値は、Japanese_CI_AS

詳しい照合順序についてはこちら

変更前の注意点

照合順序は、データベースのオプションを変更しても既に作成しているテーブルは、元の照合順序のままです。
※変更後に作成されたテーブルは新しい照合順序で作成されます。

なので、CREATE TABLEを実行するのが早いと思います。

  1. ダミーのテーブルをCREATE TABLE
  2. ダミーテーブルにデータをINSERT SELECTで退避し、一度テーブルをDROP TABLE
  3. その後、CREATE TABLEを実行。
  4. ダミーテーブルのデータをINSERT SELECTで元のテーブルに戻す。
  5. ダミーテーブルをDROP TABLE

な感じで良いと思います。


ロック待ちを解決

SQL Serverのデフォルト設定ではトランザクション分離レベルは、
READ COMMITTEDとなってます。

これだけだと一見問題ないのですが、先のトランザクションの処理が長い場合や、
後のトランザクションがテーブルを参照できずにロック待ちとなってしまいます。 つまり、誰かが登録や更新処理を長い間実行していると、他の人がSELECTした時も
待ちになってしまいます。 SELECTでも待ちになるのは、嫌ですよね。

そこで、以下の設定をおすすめします。

Is Read Committed Snapshot On:True
スナップショット分離を許可:True
※デフォルトは両方とも、False

トランザクション分離レベルの詳細については、以下を参照ください。

関連記事

coogi-memo.hatenablog.com

【SQL Server】トランザクション分離レベルをOracleと合わせる

f:id:coogi-se:20210805104840p:plain


実は、SQL ServerOracleとでトランザクション分離レベルが違うんですね。
SQL Serverトランザクション分離レベルをOracleと同じように設定する方法をまとめました。

SQL Serverトランザクション分離レベルについて

SQL Serverで設定できるトランザクション分離レベルについて整理しました。
SQL ServerのデフォルトはREAD COMMITTEDになります。

トランザクション
分離レベル
ロックの
種類
ダーティ
リード
ノンリピータブル
リード
ファントム
リード
READ UNCOMMITTED 悲観的
ロック
READ COMMITTED 悲観的
ロック
×
REPEATABLE READ 悲観的
ロック
× × ×
SERIALIZABLE 悲観的
ロック
× × ×
SNAPSHOT 楽観的
ロック
× × ×
READ COMMITTED SNAPSHOT 楽観的
ロック
×

SQL serverREAD COMMITTED SNAPSHOTについては、
更新時の断面をTempdbSNAPSHOTをとってから処理する動きになります。
OracleREAD COMMITTEDと似たような処理になるかと思います。

Oracleと同じ設定方法

現状の設定を確認するSQLは以下の通りとなります。

DBCC USEROPTIONS

設定を変更するSQLは以下の通りとなります。

-- Sessionレベルの設定の変更
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

-- DatabaseレベルのREAD COMMITTED SNAPSHOT 設定の有効化
ALTER DATABASE Database_name SET READ_COMMITTED_SNAPSHOT ON

悲観的ロックと楽観的ロックについて

悲観的ロックと楽観的ロックについては、
一般的に以下のような理解でよいかと思います。

悲観的ロック
更新処理時に更新対象のデータを参照してから更新が完了するまでの間、
他のトランザクションからの参照をブロックします。 つまり、SELECTでも他の更新処理が完了するまで待ち状態となります。

楽観的ロック
更新対象のデータを参照した時点ではロックをかけず、
更新直前に他のトランザクションによって更新されていないことを確認してから対象をロックします。
すでに更新されてしまっていた場合は、エラーとなります。

SQL ServerOracleのデフォルト

SQL Serverのデフォルトは、悲観的ロックの設定となります。
Oracleのデフォルトは、楽観的ロックの設定となります。

SQL Serverにおいては更新時に排他ロックを取得しますので、参照するための共有ロックがブロックされ待たされるような形になります。
複数のトランザクションを順番に処理できますので、トランザクション時間が短く、頻繁に同時更新が発生するような処理(例えば金額計算処理)に向いているとされています。
一方、楽観的ロックについては更新頻度が少なく同時に更新されにくいようなデータに対する処理に向いています。

悲観的ロックのデメリット

  1. 更新完了までのロック解放待ちが発生しますのでパフォーマンスは悪くなります。
  2. ロックを保持する時間が長い分、デッドロックの危険も増えます。

楽観的ロックのデメリット

  1. 更新が競合してしまった場合のロールバック後処理も考慮する必要があります。

関連記事

coogi-memo.hatenablog.com

【Handsontable】hiddenColumns 列を非表示にする

f:id:coogi-se:20210804235542p:plain


Handsontable(ハンズオンテーブル)で列の非表示について紹介します。

HandsontableとHandsontable Proとでやり方が違うので注意してください。
※Handsontable Proは、どちらのやり方でも非表示にできます。

以下を参考にしてみてください。





Handsontableの場合

Handsontableの公式ドキュメントを確認すると、
Pro用のプラグインがあり、内容を確認すると幅のサイズを
0pxにしているもよう。
なので、単純に列の幅を0pxにしてみました。

今回は、オプションのcolWidthsを使用して列幅を指定しました。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {

    data: data,

    colWidths: [200, 0, 20, 20, 20],

  });
});

2列目が非表示になったと思います。
幅を0pxにしているだけなので、データの取得時によく使う getDataAtCellなどで非表示列のデータを取得することができます。





Handsontable Proの場合

Handsontable Proにはプラグインが用意されています。hiddenColumnsです。
hiddenColumnsプラグインは、特定の列を非表示にすることができます。

今回は、動的に非表示にしたい場合を紹介します。
hiddenColumnsプラグインhideColumnhideColumns
使用してみます。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    hiddenColumns: true,
    hiddenColumns: {
      columns: [1]
    },
  });

  var hiddenColumns = hot.getPlugin("hiddenColumns");

  // 非表示
  hiddenColumns.hideColumn(2, 3);

  // 非表示(配列)
  hiddenColumns.hideColumns([2, 3])

  // 表示
  //hiddenColumns.showColumn(1);

  hot.render();
});

showColumnで非表示にした列を表示させることができます。 showColumnsもあります。

列を非表示にしていても、データの取得時によく使う
getDataAtCellなどで非表示列のデータを取得することができます。

関連記事

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

【Handsontable】autoColumnSize 列数の取得

f:id:coogi-se:20210804235542p:plain


Handsontable(ハンズオンテーブル)で表示されている最初(min)の列(Column)と最後(max)の列(Column)の値を取得します。
autoColumnSizeというプラグインを使用します。
autoColumnSizeはHandsontableがレンダリングされない場合は、-1を返します。

以下を参考にしてみてください。
たぶん、そのままコピペで動くと思います。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    autoColumnSize: true,
  });

  var autoColumnSize = hot.getPlugin("autoColumnSize");

  // サンプルの場合、「0」がコンソールに出力されます。
  console.log(autoColumnSize.getFirstVisibleColumn());

  // サンプルの場合、「4」がコンソールに出力されます。
  console.log(autoColumnSize.getLastVisibleColumn());
});

※最初の列は基本的に「0」だと思いますが、列を非表示とかにしている場合は、 「0」以外が取得されます。

プラグインを使用しなくても列数の取得が可能

// サンプルの場合、「5」がコンソールに出力されます。
console.log(hot.countCols(());

関連記事

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

【Handsontable】countRows 行数の取得

f:id:coogi-se:20210804235542p:plain


Handsontable(ハンズオンテーブル)で表示されている行数の取得方法について
紹介します。

countRows

countRows()は、Handsontableの行の総数が取得できます。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
  });

  // サンプルの場合、「4」がコンソールに出力されます。
  console.log(hot.countRows());

});

autoRowSizeというプラグインを使用しても取得が可能です。
こちらは、行のインデックスになります。
autoRowSizeはHandsontableがレンダリングされない場合は、-1を返します。

最初の行(FirstVisibleRow)の取得

getFirstVisibleRow()は、表示されている最初の行インデックスを取得します。 基本的には'0'が取得されますが、行を非表示とかにしている場合は、'0'以外が取得されます。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    autoRowSize: true,
  });

  var autoRowSize = hot.getPlugin("autoRowSize");

  // サンプルの場合、'0'がコンソールに出力されます。
  console.log(autoRowSize.getFirstVisibleRow());

});

最後の行(LastVisibleRow)の取得

getFirstVisibleRow()は、表示されている最後の行インデックスを取得します。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
    autoRowSize: true,
  });

  var autoRowSize = hot.getPlugin("autoRowSize");

  // サンプルの場合、'3'がコンソールに出力されます。
  console.log(autoRowSize.getLastVisibleRow());
});

getLastVisibleRow()countRows()で取得できる値が違うので、
注意してください。

関連記事

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

【Handsontable】skipColumnOnPaste ペースト スキップ

f:id:coogi-se:20210804235542p:plain

ペースト時のテクニック

Handsontable(ハンズオンテーブル)には
columnsプロパティにskipColumnOnPasteというメンバーがいる。 型:Bool デフォルト値:false skipColumnOnPastetureにすることで、
ペースト時に該当列はスキップしてくれるという便利なオプションがあります。 意外とかゆいところまで考えてくれています。

以下を参考にしてみてください。
たぶん、そのままコピペで動くと思います。

$(function(){
  
  var data = [
    ["", "Ford", "Tesla", "Toyota", "Honda"],
    ["2017", 10, 11, 12, 13],
    ["2018", 20, 11, 14, 13],
    ["2019", 30, 15, 12, 13]
  ];
  
  var container = document.getElementById('handsonTable');
  
  var hot = new Handsontable(container, {
    data: data,
  
    columns: function(col) {
      return {
        skipColumnOnPaste: col == 1,
      }
    },
  });
});

関連記事

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com

coogi-memo.hatenablog.com