代码拉取完成,页面将自动刷新
同步操作将从 myDcool/Corner-DB-OnlineBuild 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=yes">
<title>在线创建表(MySQL)</title>
<script src="./zbEditTable.js"></script>
<style>
.group {border-radius: 5px; padding: 5px; margin: 5px; background-color: #f8f8f8;}
.gap {margin-top: 5px;}
.option {height: 20px; line-height: 20px; margin: 5px; padding: 3px; text-align: center; font-size: 11px; background-color: #fff; border-radius: 4px; cursor: pointer;}
label {font-size: 12px;}
thead td {text-align: center; font-size: 14px;}
pre {border-radius: 5px; padding: 5px; margin: 5px; background-color: #f8f8f8;}
input {height: 18px;}
code {font-family: 'Arial'; font-size: 14px;}
</style>
</head>
<body>
<div class="group">
<label>基本信息</label>
<div id="basic_info" class="gap"></div>
<div id="basic_info_desc" class="gap"></div>
</div>
<div class="group">
<label>字段信息</label>
<div id="fields_info" class="gap"></div>
<div id="fields_desc" class="gap"></div>
</div>
<div class="group">
<label>索引信息</label>
<div id="index_info" class="gap"></div>
<div id="index_desc" class="gap"></div>
</div>
<span><button onclick="form_to_sql()">从表单生成SQL</button></span>
<pre><code id="sql"></code></pre>
<!--此处仅用来统计访问量使用-->
<div style="display: none;"><img src="https://article.hearu.top/stat_db_create_table"></div>
<script type="text/javascript">
var et = new zbEditTable();
et.onClickInput = function() {
let table_id = this.getAttribute('table_id');
if (!table_id) {
return '';
}
let clicked = document.getElementsByClassName('clicked');
for (let i=0; i<clicked.length; i++) {
clicked[i].classList.remove('clicked');
}
this.classList.add('clicked');
let coordinate = this.getAttribute('coordinate'); //被点击的input的坐标
let field_name = this.getAttribute('name'); //被点击的input的name属性
let options = [];
//table_id对应的显示描述信息的div
let map_id_desc = {
table_basic: 'basic_info_desc',
field_list: 'fields_desc',
index_list: 'index_desc',
};
let desc_id = map_id_desc[table_id];
if (table_id === 'table_basic') {
let map_basic = {
'table_name' : [],
'engine': ['InnoDB', 'MyISAM', 'MEMORY'],
'charset': ['utf8','utf8mb4'],
'collate': ['utf8_general_ci', 'utf8mb4_0900_ai_ci', 'utf8mb4_general_ci'],
'table_comment': [],
}
options = map_basic[field_name];
//字符集过滤
if (field_name === 'collate') {
let charset = et.getInputByCoordinate(table_id, '0,2').value; //取最新的值
if (charset) {
options = options.filter(function (item) {
if (item.indexOf(charset+'_') !== -1) {return true;}
}, charset)
}
}
} else if (table_id === 'field_list') {
let map_fields = {
'COLUMN_NAME':[],
'COLUMN_TYPE':['tinyint', 'int', 'bigint', 'float()', 'double()', 'decimal(10,2)', 'char()', 'varchar()', 'text', 'date', 'datetime'],
'COLUMN_KEY':['PRI'],
'IS_NULLABLE':['NO', 'YES'],
'COLUMN_DEFAULT':["''", '0', 'CURRENT_TIMESTAMP'],
'EXTRA':['AUTO_INCREMENT', 'ON UPDATE CURRENT_TIMESTAMP'],
'COLUMN_COMMENT':[],
};
options = map_fields[field_name];
} else if (table_id === 'index_list' && field_name === 'index_fields') {
let inputs = et.getInputByCoordinate('field_list', ',0');
for (let i=0; i < inputs.length; i++) {
options.push(inputs[i].value);
}
} else {
document.getElementById(desc_id).innerHTML = '';
return [];
}
//显示可选值
let tpl = '';
if (table_id === 'index_list' && field_name === 'index_fields') {
tpl = '<span class="option" onclick="copyText(\'{val1}\', 2)" title="点击复制">{val}</span>';
} else {
tpl = '<span class="option" onclick="copyText(\'{val1}\', 1)" title="点击复制">{val}</span>';
}
let content = [];
for (let i = 0; i < options.length; i++) {
let tmp = tpl.replace('{val}', options[i]);
tmp = tmp.replace('{val1}', options[i].replace(/(['"])/g, "\\$1"));
content.push(tmp);
}
if (content.length > 0) {
document.getElementById(desc_id).innerHTML = '<label>可选值: </label>' + content.join(',');
}
}
</script>
<script type="text/javascript">
//构建SQL语句
function json_to_sql(basic, field_list, index_list) {
//字段
let fields = [];
let pad = ' ';
for (let i = 0; i < field_list.length; i++) {
let field = field_list[i];
let tmp = [];
//字段名
let field_name = '`'+field['COLUMN_NAME']+'`';
//tmp.push(field_name.padEnd(25, pad));
tmp.push(field_name);
//数据类型
tmp.push(field['COLUMN_TYPE']);
//是否是主键
let primary_key = '';
if (field['COLUMN_KEY'] === 'PRI') {
primary_key = 'PRIMARY KEY';
}
tmp.push(primary_key);
//是否允许为NULL
let is_null = '';
if (field['IS_NULLABLE'] === 'NO') {
is_null = 'NOT NULL';
}
tmp.push(is_null);
//默认值
let deft = '';
if (field['COLUMN_KEY'] === 'PRI') {
deft = '';
} else if (field['COLUMN_DEFAULT'] == null) {
if (field['IS_NULLABLE'] === 'YES') {
deft = 'DEFAULT NULL';
}
} else if (field['COLUMN_DEFAULT'].length === 0) {
deft = "DEFAULT ''"
} else {
deft = 'DEFAULT ' + field['COLUMN_DEFAULT'];
}
tmp.push(deft);
//额外属性: AUTO_INCREMENT, ON UPDATE CURRENT_TIMESTAMP
let extra = field['EXTRA'].replace('DEFAULT_GENERATED','');
tmp.push(extra);
//注释
if(field['COLUMN_COMMENT'].length > 0) {
tmp.push(" COMMENT '"+ field['COLUMN_COMMENT']+"'");
}
fields.push(tmp.join(' ').trim());
}
//索引
for (let i = 0; i < index_list.length; i++) {
let index = index_list[i];
fields.push('KEY `'+ index['index_name'] + '` (' + index['index_fields'] +')');
}
//开始构建
let sql = [];
sql.push('CREATE TABLE '+ basic.table_name + '(');
sql.push(fields.join(',<br>'));
sql.push([
')',
basic.engine.length > 0 ? ' ENGINE='+basic.engine : '',
basic.charset.length > 0 ? ' DEFAULT CHARSET='+basic.charset : '',
basic.collate.length > 0 ? ' COLLATE='+ basic.collate : '',
basic.table_comment.length > 0 ? ' COMMENT="'+basic.table_comment+'"' : '',
';'
].join(''));
sql = sql.join('<br>');
document.getElementById('sql').innerHTML = sql;
return sql;
}
//根据表单数据生成SQL
function form_to_sql() {
//获取基本信息
let basic = et.getInputsArray('table_basic')[0];
basic = et.array_column(basic, 'value', 'name');
//获取字段信息
let field_list = et.getInputsArray('field_list');
for (let i=0; i<field_list.length; i++) {
field_list[i] = et.array_column(field_list[i], 'value', 'name');
}
//获取索引信息
let index_list = et.getInputsArray('index_list');
for (let i=0; i<index_list.length; i++) {
index_list[i] = et.array_column(index_list[i], 'value', 'name');
}
return json_to_sql(basic, field_list, index_list);
}
//显示空白表单
function show_empty_form() {
//表基本信息
let domTable = et.createEditTable({
id:'table_basic',
thead:{
values:['表名', '引擎', '默认编码', '字符集', '注释']
},
tbody:{
values:[['','InnoDB','utf8mb4','utf8mb4_0900_ai_ci', '']]
}
});
document.getElementById('basic_info').appendChild(domTable);
et.setInputAttributes('table_basic', [
{coordinate:'0,0', attrs:{name:'table_name'}},
{coordinate:'0,1', attrs:{name:'engine'}},
{coordinate:'0,2', attrs:{name:'charset'}},
{coordinate:'0,3', attrs:{name:'collate'}},
{coordinate:'0,4', attrs:{name:'table_comment'}},
]);
//表字段
let domFields = et.createResponseEditTable({
id:'field_list',
thead:{
values:['字段名','数据类型','是否主键','是否允许NULL','默认值','额外设置','注释']
},
tbody: {
default_row:1,
default_col:7,
values:[
['id', 'int', 'PRI', 'NO', '0', 'AUTO_INCREMENT', '自增ID'],
['code', 'varchar(20)', '', 'NO', '', '', '唯一编码,前台使用'],
['status', 'tinyint', '', 'NO', '0', '', '状态'],
['deleted', 'tinyint', '', 'NO', '0', '', '是否删除'],
['create_time', 'datetime', '', 'NO', 'CURRENT_TIMESTAMP', '', '创建时间'],
['update_time', 'datetime', '', 'NO', 'CURRENT_TIMESTAMP', 'ON UPDATE CURRENT_TIMESTAMP', '修改时间'],
]
}
});
document.getElementById('fields_info').appendChild(domFields);
et.setInputAttributes('field_list', [
{coordinate:',0', attrs:{name:'COLUMN_NAME'}}, //字段名
{coordinate:',1', attrs:{name:'COLUMN_TYPE'}}, //数据类型
{coordinate:',2', attrs:{name:'COLUMN_KEY'}}, //是否是主键
{coordinate:',3', attrs:{name:'IS_NULLABLE'}}, //是否可为NULL
{coordinate:',4', attrs:{name:'COLUMN_DEFAULT'}}, //默认值
{coordinate:',5', attrs:{name:'EXTRA'}}, //额外, 比如: 自增, 更新时自动更新
{coordinate:',6', attrs:{name:'COLUMN_COMMENT'}} //字段注释
]);
//索引
let domIndexs = et.createResponseEditTable({
id:'index_list',
thead:{
values:['索引名','字段(多个以逗号隔开)']
},
tbody: {
default_row:1,
default_col:2,
values:[
['code', 'code'],
]
}
});
document.getElementById('index_info').appendChild(domIndexs);
et.setInputAttributes('index_list', [
{coordinate:'0,0', attrs:{name:'index_name'}},
{coordinate:'0,1', attrs:{name:'index_fields'}},
]);
form_to_sql();
}
</script>
<script type="text/javascript">
//复制文本
function copyText(text, mode=0, gap=',') {
let textArea = document.createElement("textarea");
textArea.style.position = 'fixed';
textArea.style.top = '0';
textArea.style.left = '0';
textArea.style.width = '2em';
textArea.style.height = '2em';
textArea.style.padding = '0';
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
//https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
//navigator.clipboard.readText().then(clipText => document.querySelector(".editor").innerText += clipText);
document.execCommand('copy');
document.body.removeChild(textArea);
let clicked = document.getElementsByClassName('clicked');
if (mode === 1) {//替换
for (let i=0; i<clicked.length; i++) {
clicked[i].value = text;
}
} else if (mode === 2) {
//追加
for (let i=0; i<clicked.length; i++) {
if (clicked[i].value.length === 0) {
clicked[i].value = text;
} else {
clicked[i].value += gap+text;
}
}
}
}
</script>
<script type="text/javascript">
//显示默认表结构
show_empty_form();
//每5秒钟, 将表单中的数据组装成sql
//setInterval(form_to_sql,5000);
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。