mycat使用规范

原始语句:

INSERT INTO mail_send (
    createTime,
    updateTime,
    flag,
    accountId,
    messageID,
    sender,
    senderName,
    fromer,
    replyTo,
    toer,
    ccer,
    bccer,
    SUBJECT,
    text,
    STATUS,
    costTime,
    seperated,
    marketed,
    readCount,
    uid,
    uidValidity,
    uidBatchNum,
    attached,
    needDownloadAttach,
    syncFromMailServer,
    messageNum,
    folder,
    sentTime,
    contentSummary
)
VALUES
    (
        NOW(),
        NULL,
        0,
        1115,
        '2222000000',
        NULL,
        NULL,
        '9999',
        '9999',
        NULL,
        NULL,
        NULL,
        NULL,
        '<html><p style=\\"margin: 0px;\\">it will soon be on wuwanhua2908 vacation now,(Labor Day,01/05-05/05)</p><img style=\\"display:none\\" class=\\"just-for-mail-none-lys\\"></html>',
        0,
        NULL,
        0,
        0,
        0,
        NULL,
        NULL,
        0,
        0,
        NULL,
        0,
        0,
        NULL,
        NULL,
        NULL
    )

1,insert语句中应该避免主键缺失

  如果一个表的主键字段是ID, 那么在insert的时候语句中ID应该不能为空,尽量在业务层使用自己的ID生成器提前生成ID,避免使用数据库自增ID生成策略

  原因:mycat1.6.5版本中为了补充缺失的主键ID,会尝试修改你的sql语句,这里有一些bug,导致你的sql出错

 /**
	  * 对于主键不在插入语句的fields中的SQL,需要改写。比如hotnews主键为id,插入语句为:
	  * insert into hotnews(title) values('aaa');
	  * 需要改写成:
	  * insert into hotnews(id, title) values(next value for MYCATSEQ_hotnews,'aaa');
	  */
    public static void handleBatchInsert(ServerConnection sc, SchemaConfig schema,
            int sqlType,String origSQL, int valuesIndex,String tableName, String primaryKey) {

    	final String pk = "\\("+primaryKey+",";
        final String mycatSeqPrefix = "(next value for MYCATSEQ_"+tableName.toUpperCase()+",";

    	/*"VALUES".length() ==6 */
        String prefix = origSQL.substring(0, valuesIndex + 6);
        String values = origSQL.substring(valuesIndex + 6);

        prefix = prefix.replaceFirst("\\(", pk);
        values = values.replaceFirst("\\(", mycatSeqPrefix);
        values =Pattern.compile(",\\s*\\(").matcher(values).replaceAll(","+mycatSeqPrefix);
        processSQL(sc, schema,prefix+values, sqlType);
    }

  处理结果:

INSERT INTO mail_send (
	ID,
	createTime,
	updateTime,
	flag,
	accountId,
	messageID,
	sender,
	senderName,
	fromer,
	replyTo,
	toer,
	ccer,
	bccer,
	SUBJECT,
	text,
	STATUS,
	costTime,
	seperated,
	marketed,
	readCount,
	uid,
	uidValidity,
	uidBatchNum,
	attached,
	needDownloadAttach,
	syncFromMailServer,
	messageNum,
	folder,
	sentTime,
	contentSummary
)
VALUES
	(
		  next value for MYCATSEQ_MAIL_SEND,
			NOW(),
			NULL,
			0,
			1115,
			'2222000000',
			NULL,
			NULL,
			'9999',
			'9999',
			NULL,
			NULL,
			NULL,
			NULL,
			'<html><p style=\\"margin: 0px;\\">it will soon be on wuwanhua2908 vacation now,(next value for MYCATSEQ_MAIL_SEND,Labor Day,01/05-05/05)</p><img style=\\"display:none\\" class=\\"just-for-mail-none-lys\\"></html>',
			0,
			NULL,
			0,
			0,
			0,
			NULL,
			NULL,
			0,
			0,
			NULL,
			0,
			0,
			NULL,
			NULL,
			NULL
	)

  

2,sql语句中应该避免使用NOW()

  在sql语句中涉及到时间的字段,value不能写NOW(),尽量在业务层把时间初始化好,避免依赖数据库生成当前时间

  原因:mycat1.7版本中,为了解决第一个问题中的bug,根据括号符号拆分语句(多个values拆成多个insert语句),由于NOW()中的括号导致拆分失败,最终sql执行异常

             [Err] 1064 - com.alibaba.druid.sql.parser.ParserException: syntax error

public static List<String> handleBatchInsert(String origSQL, int valuesIndex){
		List<String> handledSQLs = new LinkedList<>();
		String prefix = origSQL.substring(0,valuesIndex + "VALUES".length());
		String values = origSQL.substring(valuesIndex + "VALUES".length());
		int flag = 0;
		StringBuilder currentValue = new StringBuilder();
		currentValue.append(prefix);
		for (int i = 0; i < values.length(); i++) {
			char j = values.charAt(i);
			if(j=='(' && flag == 0){
				flag = 1;
				currentValue.append(j);
			}else if(j=='\"' && flag == 1){
				flag = 2;
				currentValue.append(j);
			} else if(j=='\'' && flag == 1){
				flag = 2;
				currentValue.append(j);
			} else if(j=='\\' && flag == 2){
				flag = 3;
				currentValue.append(j);
			} else if (flag == 3){
				flag = 2;
				currentValue.append(j);
			}else if(j=='\"' && flag == 2){
				flag = 1;
				currentValue.append(j);
			} else if(j=='\'' && flag == 2){
				flag = 1;
				currentValue.append(j);
			} else if (j==')' && flag == 1){
				flag = 0;
				currentValue.append(j);
				handledSQLs.add(currentValue.toString());
				currentValue = new StringBuilder();
				currentValue.append(prefix);
			} else if(j == ',' && flag == 0){
				continue;
			} else {
				currentValue.append(j);
			}
		}
		return handledSQLs;
	}

  拆分结果1:

INSERT INTO mail_send (
	createTime,
	updateTime,
	flag,
	accountId,
	messageID,
	sender,
	senderName,
	fromer,
	replyTo,
	toer,
	ccer,
	bccer,
	SUBJECT,
	text,
	STATUS,
	costTime,
	seperated,
	marketed,
	readCount,
	uid,
	uidValidity,
	uidBatchNum,
	attached,
	needDownloadAttach,
	syncFromMailServer,
	messageNum,
	folder,
	sentTime,
	contentSummary
)
VALUES
	(
		NOW()

  

       拆分结果2:

INSERT INTO mail_send (
			createTime,
			updateTime,
			flag,
			accountId,
			messageID,
			sender,
			senderName,
			fromer,
			replyTo,
			toer,
			ccer,
			bccer,
			subject,
			text,
			status,
			costTime,
			seperated,
			marketed,
			readCount,
		        uid,
                        uidValidity,
                        uidBatchNum,
                        attached,
                        needDownloadAttach,
                        syncFromMailServer,
                        messageNum,
		        folder,
                        sentTime,
			contentSummary
		) VALUES
			null
			0
			1115
			'2222000000'
			null
			null
			'9999'
			'9999'
			null
			null
			null
			null
			'<html><p style=\\"margin: 0px;\\">it will soon be on wuwanhua2908 vacation now(Labor Day,01/05-05/05)

  

猜你喜欢

转载自www.cnblogs.com/wanhua-wu/p/12808820.html