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)

浙公网安备 33010602011771号