MySQL の特徴 (他DBと比べて)

経験上の羅列です。

1) || での連結は出来ない (CONCAT関数で同じことは出来る)

=> sql_modeの設定で出来ることがわかりました。http://wp.saoline.co/wordpress/?p=1305
2) WITHは5.7までないので、導出テーブルが入り組んだ場合、わかりにくい
3) 関数は普通に揃っている。(なければUDFを作ればよい)
4) インデックスが1テーブル1個しか効かない。(複合インデックスで対応、列の順番がパフォーマンスに影響)
5) 導出テーブルでLIMITが使えない
6) ストアドの結果を導出テーブルに出来ない
7) ストレージエンジンを選べるので。用途に合わせて最適に出来る
8) テーブル名の大文字小文字区別あり
9) 日付条件の問い合わせで数値が使える (20190101, ‘2019-01-01’ は同じ)
10) DUAL表の指定は不要
12) CONSTRAINTがない (値制約はトリガーで判断し、エラーを生成して処理しないことにすればもどきなことは出来る)
13) ユーザー認証に必ずホスト名(IP)が必要
14) 列毎にテーブル定義とは別のキャラクタセットが指定出来る
15) バルクインサートが超高速
16) SELECT検索結果をCSVに出力できる
17) JSONが格納できる(JSON型, 5.7から)
18) 日時の型が豊富で便利 (DATE, DATETIME, TIMESTAMP, TIME, YEAR)
19) innodb (デフォルト)の場合、パフォーマンス確保の為、データベースのサイズと同じ位のメモリをバッファプールで設定するのが望ましい
20) ダンプバックアップの種類が多く、便利

詳しくは、Oracleの公式ページを見て下さい。

http://otndnld.oracle.co.jp/document/products/sql/12/doc_cd/doc/appdev.120/E06020-01/oracle_mysql_compared.htm

これも詳しい : https://www.ashisuto.co.jp/corporate/column/technical-column/detail/1197236_2274.html

MySQL カレンダーストアド 応用編

基本編で紹介したものに、データをUDFで拾ってきて、CONCATしてます。

[ 実行結果 ]

[ コード ]


CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_sel_acalendar_vslccpp`(
	IN `ym` INT,
	IN `vslnm` VARCHAR(36),
	IN `idmultiple` SMALLINT

)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '船寄港国単月カレンダー (使用)'
BEGIN	

DECLARE ymprev INT;
DECLARE ymnext INT;

SET ymprev = ym - 1;
SET ymnext = ym + 1;

IF (ymprev % 100 = 0) THEN
  SET ymprev = ymprev - 88;  
END IF;
IF (ymnext % 100 = 13) THEN
  SET ymnext = ymnext + 88;  
END IF;



SELECT
  YWK * idmultiple AS id,
  YWK, 
	
	
	MON, 
	TUE, WED, THU, FRI, SAT, 
	SUN,
	
	DTMIN, DTMAX,
	
	YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN) AS DTMINVAL,
	YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX) AS DTMAXVAL,
	
	FLOOR((YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN)) / 100) AS DTMINYM,
	FLOOR((YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX)) / 100) AS DTMAXYM
	
FROM
	(
	SELECT
	  
  	YWK,
  	MIN(YM) AS YMMIN,
  	MAX(YM) AS YMMAX,
  	MAX(SUN) AS SUN,
  	MAX(MON) AS MON,
  	MAX(TUE) AS TUE,
  	MAX(WED) AS WED,
  	MAX(THU) AS THU,
  	MAX(FRI) AS FRI,
  	MAX(SAT) AS SAT,
  	MIN(dt) AS DTMIN, MAX(dt) AS DTMAX
	FROM
		(
		SELECT
  		dt, 
  
  		CASE WHEN (WEEKOFYEAR(dt) = 53) THEN 
			  (YEAR(dt) - 1) * 100 + WEEKOFYEAR(dt)
	  	
	  		ELSE YEAR(dt) * 100 + WEEKOFYEAR(dt)  
	  	  
			END AS YWK,
	
			YEAR(dt) * 100 + MONTH(dt) AS YM,
  
  		CASE WHEN (DAYOFWEEK(dt) = 1) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt)) 
			ELSE '' END AS SUN,
			
			CASE WHEN (DAYOFWEEK(dt) = 2) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS MON,
			
			CASE WHEN (DAYOFWEEK(dt) = 3) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS TUE,
			
			CASE WHEN (DAYOFWEEK(dt) = 4) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS WED,
			
			CASE WHEN (DAYOFWEEK(dt) = 5) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS THU,
			
			CASE WHEN (DAYOFWEEK(dt) = 6) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS FRI,
			
			CASE WHEN (DAYOFWEEK(dt) = 7) THEN 
			CONCAT(DATE_FORMAT(dt, '%e'), ':', fc_vesselcntry_bydt (vslnm, dt), ':', fc_vesselport_bydt (vslnm, dt))
			ELSE '' END AS SAT
			
		FROM
  		bimpsch.m_date
		WHERE
			YEAR(dt) * 100 + MONTH(dt) BETWEEN ymprev AND ymnext
			
		) a
	GROUP BY
  	YWK
	) b	
WHERE
	
	FLOOR((YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN)) / 100) = ym OR 
	FLOOR((YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX)) / 100) = ym
	
	
ORDER BY
  DTMIN;	
	
	
END

[ 利用例 ]

船の寄港国、ポップアップで港が現れる

右クリックコンテキストメニューを配置 => 列値、行IDとかで更新処理できる

[ jqGrid colModel例 ]


          colNames: ['月', '火', '水', '木', '金', '土', '日', '', '', ''],
          colModel: [
            {name: 'mon', width: '140px', classes: 'caltd calentd'},
            {name: 'tue', width: '140px', classes: 'caltd'},
            {name: 'wed', width: '140px', classes: 'caltd'},
            {name: 'thu', width: '140px', classes: 'caltd'},
            {name: 'fri', width: '140px', classes: 'caltd'},
            {name: 'sat', width: '140px', classes: 'caltd'},
            {name: 'sun', width: '140px', classes: 'caltd'},
            {name: 'id', hidden: true,
              editrules: {edithidden: true}
            },
            {name: 'dtmin', hidden: true,
              editrules: {edithidden: true}
            },
            {name: 'dtmax', hidden: true,
              editrules: {edithidden: true}
            },
          ],

MySQL カレンダーストアド 基本編

グリッドでカレンダーの配置が必要になり、いろいろ応用が効いて重宝してます。

[ 実行と結果 ]

[ コード ]


CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_sel_acalendar`(
	IN `ym` INT


)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '単月カレンダー'
BEGIN	

DECLARE ymprev INT;
DECLARE ymnext INT;

SET ymprev = ym - 1;
SET ymnext = ym + 1;

IF (ymprev % 100 = 0) THEN
  SET ymprev = ymprev - 88;  
END IF;
IF (ymnext % 100 = 13) THEN
  SET ymnext = ymnext + 88;  
END IF;



SELECT
  YWK AS id,
  YWK, 
	
	
	MON, 
	TUE, WED, THU, FRI, SAT, 
	SUN,
	
	DTMIN, DTMAX,
	
	YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN) AS DTMINVAL,
	YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX) AS DTMAXVAL,
	
	FLOOR((YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN)) / 100) AS DTMINYM,
	FLOOR((YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX)) / 100) AS DTMAXYM
	
FROM
	(
	SELECT
	  
  	YWK,
  	MIN(YM) AS YMMIN,
  	MAX(YM) AS YMMAX,
  	MAX(SUN) AS SUN,
  	MAX(MON) AS MON,
  	MAX(TUE) AS TUE,
  	MAX(WED) AS WED,
  	MAX(THU) AS THU,
  	MAX(FRI) AS FRI,
  	MAX(SAT) AS SAT,
  	MIN(dt) AS DTMIN, MAX(dt) AS DTMAX
	FROM
		(
		SELECT
  		dt, 
  
  		CASE WHEN (WEEKOFYEAR(dt) = 53) THEN 
			  (YEAR(dt) - 1) * 100 + WEEKOFYEAR(dt)
	  	
	  		ELSE YEAR(dt) * 100 + WEEKOFYEAR(dt)  
	  	  
			END AS YWK,
	
			YEAR(dt) * 100 + MONTH(dt) AS YM,
  
  		CASE WHEN (DAYOFWEEK(dt) = 1) THEN 
			DATE_FORMAT(dt, '%e') 
			ELSE '' END AS SUN,
			
			CASE WHEN (DAYOFWEEK(dt) = 2) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS MON,
			
			CASE WHEN (DAYOFWEEK(dt) = 3) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS TUE,
			
			CASE WHEN (DAYOFWEEK(dt) = 4) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS WED,
			
			CASE WHEN (DAYOFWEEK(dt) = 5) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS THU,
			
			CASE WHEN (DAYOFWEEK(dt) = 6) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS FRI,
			
			CASE WHEN (DAYOFWEEK(dt) = 7) THEN 
			DATE_FORMAT(dt, '%e')
			ELSE '' END AS SAT
			
		FROM
  		m_date
		WHERE
			YEAR(dt) * 100 + MONTH(dt) BETWEEN ymprev AND ymnext
			
		) a
	GROUP BY
  	YWK
	) b	
WHERE
	
	FLOOR((YEAR(DTMIN) * 10000 + MONTH(DTMIN) * 100 + DAY(DTMIN)) / 100) = ym OR 
	FLOOR((YEAR(DTMAX) * 10000 + MONTH(DTMAX) * 100 + DAY(DTMAX)) / 100) = ym
	
	
ORDER BY
  DTMIN;	
	
	
END

CREATE TABLE `m_date` (
	`dt` DATE NOT NULL COMMENT '日付',
	`IS_HOLIDAY` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '祝日フラグ',
	PRIMARY KEY (`dt`)
)
COMMENT='連続日付マスタ'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

MySQL ストアドプロシージャー カーソル

骨だけで使ってません。カーソルのテーブルを適時変更してもらえば、コピペして使えます。


CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_loopupdt_shporder_deliv`(
	IN `ivtrydt` DATE,
	IN `sessionid` VARCHAR(70)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '出庫指図在庫引き当て履歴更新店別明細(これは不要なので処理は空 テンプレート用)'
BEGIN	

/* 変数宣言 */
DECLARE noskid INT;
DECLARE noskcdgoods VARCHAR(20);
DECLARE noskcddeliv VARCHAR(8);
DECLARE noskqty INT;

/* カーソル継続判断フラグ */
DECLARE done INT DEFAULT 0;

/* カーソル定義 */
DECLARE nosk CURSOR FOR
SELECT
  ID, CD_GOODS, CD_DELIV, QTY
FROM
	h_shporder
WHERE
  DT_IVTRY = ivtrydt;	

/* 走査継続判断用 */
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN nosk;

delete from tst where 1 = 1;

REPEAT
	
	/* 変数に格納 */
	FETCH nosk INTO noskid, noskcdgoods, noskcddeliv, noskqty;
	
	/* ここにやりたい処理を入れるとよい */
	/* MySQLではストアドのデバッグは出来ないので、デバッグは一時テーブルとかで行う */
		

UNTIL done END REPEAT;
CLOSE nosk;   /* カーソルのクローズ */

END

MySQL IDEのおすすめ

何使ってもよく、好みに左右されると思いますが、

HeidiSQL  と MySQL WorkBench をお勧めします。

HeidiSQLの便利なところ

  1. テーブル定義で列のコピーペーストが出来て、他のテーブルで使える
  2. インデックス設定の列追加で、ドラッグドロップが使える
  3. 履歴が使いやすく、他に保存する必要なくなる

HeidiSQLの不便なところ

  1. ビューが1行で表示されてしまう

MySQL WorkBenchの便利なところ

  1. EXPLAINがビジュアル

  1. ビューが整形されて表示される

MySQL WorkBenchの不便なところ

  1. 日本語化されてない

 

jqGrid インライン編集 extraparamのセット

最近、やっとわかったこととして、編集列として設定してないデータを更新用として送信する場合、以前は id に文字列表現したり、隠し列設定したりして、目的は達成できるものの、列が増えたりして、ややこしいプログラムになったりしてました。

editParams , addParams の中に extraparam をセットすれば、すっきりわかりやすくなります。

[ コード例 ]


// -- 編集 -- // 
editParams: {

  extraparam: {
    idUser: function () {
      return userid;
    }
  },
// -- 追加 -- //
addParams: {

  addRowParams: {
    extraparam: {
      cdJan: function () {
        return subgrid_table_id.split("_")[1];
      },
      idUser: function () {
        return userid;
      }
    },

編集送信データ例
idUser の列はないが、ちゃんと送信されたのがわかる

画面例

jqGrid 罫線 フォント色の動的設定

 

 

 

 

固定的に列のフォント色なんかを設定したい場合は、colModel の classes に CSSのクラス名なんかを設定しておけば、コーディングする必要ないですが、

動的なことする場合は、loadComplete で DOMのCSS設定したりします。

[ サンプルコード ]


// == グリッドデータ取得 == //
var rows = $(this).getRowData();

// == userdata取得 == //
var userdata = $(this).jqGrid('getGridParam', 'userData');

// 区切線用 //
var ulineidxary = [];

if (userdata['sidx'] == 'dceta' || userdata['sidx'] == 'vessel' || userdata['sidx'] == 'berth') {
  var rowsary = $(this).getRowData();
  var wcntary = [];
  $.each(rowsary, function (i, itm) {
    //wcntary.push(itm['dcetawdiff']);
    wcntary.push(itm[lineMap[userdata['sidx']]]);
  });

  $.each(wcntary, function (i, itm) {
    if (i > 0 && wcntary[i] != wcntary[i - 1]) {
      ulineidxary.push(i - 1);
    }
  });
  //$('#divdbg').text(ulineidxary);

}

// ++ 全行走査 ++ //
$.each(rows, function (i, itm) {
	 // VOY列右をに縦線を引く //
	$("#" + rows[i]['id'] + " td").eq(2).css("border-right-color", "#224444");
	
	// 週区切り線 //
	if (ulineidxary.indexOf(i) != -1) {
	  $("#" + rows[i]['id'] + " td").css("border-bottom-color",
	          !isDarkTheme ? "#004400" : "#99DD99");
	}
	
	// 船スペックタイトル //
	td = $('#' + rows[i]['id']).children('td').eq(1);
	$(td).attr('title', rows[i]['cnt'] + ' Records exists by this vessel.' + '\n' +
	        rows[i]['vesselspec']);
	
	// カレントポジションリンク用IMOタイトル //
	curimo = rows[i]['vesselspec'].replace("\n", "").slice(-8);
	td = $('#' + rows[i]['id']).children('td').eq(2);
	$(td).attr('title', curimo);
	
	// バース日がETAより大きい場合、赤文字ワーニング //
	etaschMD = !isOld ? rows[i]['dceta'].slice(0, 5) : rows[i]['dceta'].slice(3, 8);
	berthMD = rows[i]['tmberth'].slice(0, 5);
	
	if (berthMD > etaschMD) {
	  td = $('#' + rows[i]['id']).children('td').eq(BERTHTIME_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#ff0000' : '#ff90ff');
	}
	// 早いのは青表示 //
	if (berthMD < etaschMD) { td = $('#' + rows[i]['id']).children('td').eq(BERTHTIME_COLIDX); $(td).css('color', !isDarkTheme ? '#0000aa' : '#00ffff'); } // 入港日差 遅れを赤表示 // if (rows[i]['difdceta'] > 0) {
	  td = td = $('#' + rows[i]['id']).children('td').eq(ETADIFF_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#ff0000' : '#ff90ff');
	  //$(td).css('color', 'red');
	}
	// 入港日差 早いのは青表示 //
	if (rows[i]['difdceta'] < 0) {
	  td = td = $('#' + rows[i]['id']).children('td').eq(ETADIFF_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#0000aa' : '#00ffff');
	}
	
	// SKIP行 //
	if (rows[i]['tmport'].indexOf('SKIP') != -1) {
	  $("#" + rows[i]['id'] + " td").addClass('td_lv');
	}
	
});	

画面例

jqGrid colModel, colNames (基本)

jqGridのcolNames, colModel については、下サンプルのようにプロパティで設定します。
先に変数に入れて、それを指定してもよいです。

本家 API : http://www.trirand.com/jqgridwiki/doku.php?id=wiki:colmodel_options

[ colModelインライン記述例 ]


datatype: "json",
loadui: 'block',
reloadAfterSubmit: true,
colNames: ['', 'Name', 'Home URL', 'My URL', 'Exp', 'Imp', 'LastUpdate', '', ''],
colModel: [
  {name: 'ico', width: '20px', align: 'center', classes: 'curpo'},
  {name: 'ope', width: '40px', align: 'left', classes: 'curpo'},

  {name: 'url', width: '120px', align: 'left', editable: true},
  {name: 'myurl', width: '120px', align: 'left', editable: true},

  {name: 'expcnt', width: '20px', align: 'right'},
  {name: 'impcnt', width: '20px', align: 'right'},
  {name: 'tmLastupdt', width: '50px', align: 'left', classes: 'tmcol'},
  {name: 'id', index: 'id', width: '0px', align: 'left',
    hidden: true,
    editrules: {edithidden: true}},
  {name: 'opeforedit', width: '0px', align: 'left', editable: true}
],
multiselect: false,

変数指定例


      var colnames = ['SKNo.', 'InvoiceNo.', '工場',  '揚港', 'コンテナNo.', '保税地域',
        '仕入額$', '仕入額\\', '納品日', '納品場所', '支払日', '請求額(課税)', '請求額(非課税)',
        '消費税', '税関名', '関税', '申告番号', '',
        '輸入諸掛(社内)', '輸入諸掛金額', '海上運賃', 'その他諸掛', '保険', '控除後売上', '粗利',
        '備考',  '最終更新', '', '', '', ''];

      var colmodel = [
        // SK No. //
        {name: 'noSK', index: 'NO_SK', width: '38px', align: 'left'},
        // Invoice No. //
        {name: 'noInv', index: 'NO_INV', width: '60px', align: 'left'},
        // 工場 //
        {name: 'nmFact', index: 'NM_FACT', width: '38px', align: 'left'},
        // DCPort //
        {name: 'nmDc', index: 'NM_DC', width: '20px', align: 'left'},
        // コンテナNo //
        {name: 'nmCont', index: 'NM_CONT', width: '64px', align: 'left'},

        // CYCFS 2018-09-28 //
        {name: 'cdTerminal', index: 'CD_TERMINAL', width: '40px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=cycfs',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },

        // ドル仕入額 //
        {name: 'amSuplusd', index: 'AM_SUPL_USD', width: '30px', align: 'right', editable: true,
          editrules: {number: true, minValue: 0, maxValue: 9999999}
        },
        // 円仕入額 //
        {name: 'amSupljpy', index: 'AM_SUPL_JPY', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 納品日 //
        {name: 'dtDeliv', index: 'DT_DELIV_LONG', width: '30px', align: 'center', "classes": "dtcol"},
        // 納品場所 //
        {name: 'nmDeliv', index: 'NM_DELIV', width: '50px', align: 'left'},
        // 支払日 //
        {name: 'dtPayment', index: 'DT_PAYMENT_LONG', width: '30px', align: 'center', editable: true, "classes": "dtcol"},
        // 課税請求 //
        {name: 'amInwithtax', index: 'AM_IN_WITH_TAX', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 非課税請求 //
        {name: 'amInnotax', index: 'AM_IN_NO_TAX', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 消費税 //
        {name: 'amTaxc', index: 'AM_TAXC', width: '30px', align: 'right'

        },
        // 税関名 //
        {name: 'nmCustom', index: 'NM_CUSTOM', width: '36px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=custom',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },
        // 関税 //
        {name: 'amTarrif', index: 'AM_TARRIF', width: '30px', align: 'right', editable: true, sotrable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 申告番号 //
        {name: 'noNotify', index: 'NO_NOTIFY', width: '56px', align: 'left', editable: true},
        // 通関チェック //
        {name: 'isCustomed', index: 'IS_CUSTOMED', width: '8px', align: 'center',
          editable: true,
          edittype: "checkbox", editoptions: {value: "1:0"}
        },
        // 輸入諸掛営業所名 //
        {name: 'nmDiv', index: 'NM_DIV', width: '38px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=divsk',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },
        // 輸入諸掛金額 //
        {name: 'amOutdiv', index: 'AM_OUT_DIV', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 海上運賃 //
        {name: 'amFreight', index: 'AM_FREIGHT', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // その他諸掛 //
        {name: 'amOther', index: 'AM_OTHER', width: '30px', align: 'right', editable: true},
        // 保険 //
        {name: 'amIns', index: 'AM_INS', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 控除後売上 //
        {name: 'amInfinal', index: 'AM_IN_FINAL', width: '30px', align: 'right', "classes": "cntcol",
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 粗利 //
        {name: 'amProfit', index: 'AM_PROFIT', width: '30px', align: 'right', "classes": "cntcol",
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 備考 //
        {name: 'nmRemark', index: 'NM_REMARK', width: '40px', align: 'left', editable: true},
        // 最終更新 //
        {name: 'tmLastupdt', index: 'TM_LASTUPDT', width: '56px', align: 'center', classes: 'tmcol'},
        // 隠し列 //
        {name: 'id', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'dtDelivlong', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'dtPaymentlong', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'txtOthers', width: '0px', editable: true, edithidden: true, hidden: true}
      ];

編集可能で列が多くなったりすると、ややこしく扱いにくくなるので、データベースから読み込んだりしてます。
データベースでの設定については、別途説明します。

jqGrid インライン編集 編集

[ コードサンプル ]


// ナビゲータの設定 //
	$("#opemaster").jqGrid('navGrid', "#opemasterpager",
        {edit: true, add: false, del: false});

// ++ インライン編集の設定 ++ //
$("#opemaster").jqGrid('inlineNav', "#opemasterpager", {
  edit: true,
  editicon: "ui-icon-pencil",
  // 編集 // 
  editParams: {
    oneditfunc: function (id) {     //選択行の編集時

      // フォーカス //
      $('#' + id + '_url').focus();
    },
    // 保存した後 //
    aftersavefunc: function (restxt) {
    },
    // 更新成功した時 //
    successfunc: function (resjsn, id) {

      // My URLはローカルストレージに保存する //
      //alert(JSON.stringify(resjsn));
      var resmap = JSON.parse(resjsn.responseText);
      //alert(resmap);

      if (resmap['myurl'] != null) {
        myurlMap[resmap['ope']] = resmap['myurl'];
        //alert(JSON.stringify(myurlMap));
        if (localStorage) {
          localStorage.setItem('vesselsch_myurlmap', JSON.stringify(myurlMap));
        }
      }
      // reloadAfterPostが効かないので入れる //
      $(this).jqGrid('setGridParam', {}).trigger('reloadGrid');
      //}
    }
  }
});

 

画面例

colModel


colNames: ['', 'Name', 'Home URL', 'My URL', 'Exp', 'Imp', 'LastUpdate', '', ''],
colModel: [
  {name: 'ico', width: '20px', align: 'center', classes: 'curpo'},
  {name: 'ope', width: '40px', align: 'left', classes: 'curpo'},

  {name: 'url', width: '120px', align: 'left', editable: true},
  {name: 'myurl', width: '120px', align: 'left', editable: true},

  {name: 'expcnt', width: '20px', align: 'right'},
  {name: 'impcnt', width: '20px', align: 'right'},
  {name: 'tmLastupdt', width: '50px', align: 'left', classes: 'tmcol'},
  {name: 'id', index: 'id', width: '0px', align: 'left',
    hidden: true,
    editrules: {edithidden: true}},
  {name: 'opeforedit', width: '0px', align: 'left', editable: true}
],

/* editable にした列が送信される */

送信データ例

favicon.ico の抽出

よそのサイトのページアイコンが必要な時、すぐに取得できます。

googleの以下URLで、domain= の後に、対象のURLを入力

https://www.google.com/s2/favicons?domain=https://intl3-senko.com/bimpsch/

後は、名前を付けて画像を保存