The ALTER TABLE command is used to:
➕ Add new columns
✏️ Modify existing columns
❌ Drop columns
🔐 Add / remove constraints
📌 Base Setup (Only ONE code block)
We will use this same table for ALL examples below:
-- Base Table
CREATE TABLE students (
id INT IDENTITY(1,1) PRIMARY KEY,
name VARCHAR(50),
grade VARCHAR(2)
);
-- Sample Data
INSERT INTO students (name, grade) VALUES
('Raj', 'B'),
('Tina', 'B'),
('Anya', 'A'),
('Sara', 'A');➡️ All ALTER operations below will be performed on this same students table.
➕ Add a New Column
ALTER TABLE students
ADD email VARCHAR(100);✔️ Adds a new column named email
✏️ Modify Column Data Type
ALTER TABLE students
ALTER COLUMN grade VARCHAR(5);✔️ Expands grade column size from VARCHAR(2) to VARCHAR(5)
❌ Drop a Column
ALTER TABLE students
DROP COLUMN email;✔️ Removes the email column completely
🔐 Add PRIMARY KEY (example on same table structure idea)
If primary key DID NOT exist before
ALTER TABLE students
ADD CONSTRAINT pk_students PRIMARY KEY (id);✔️ Makes id primary key
🔗 Add FOREIGN KEY
Assume we create another table:
ALTER TABLE students
ADD age INT;Now add a foreign key to another table:
ALTER TABLE enrollments
ADD CONSTRAINT fk_student
FOREIGN KEY (student_id) REFERENCES students(id);✔️ Ensures student_id must exist in students table first
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ALTER TABLE — Try It Yourself</title>
<style>
.infographic-alterrunner {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #16a34a;
--good-soft: #dcfce7;
--bad: #dc2626;
--bad-soft: #fee2e2;
--on-accent: #ffffff;
--display-font: Georgia, 'Iowan Old Style', serif;
--body-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono-font: 'SF Mono', Consolas, monospace;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 780px;
margin: 0 auto;
box-sizing: border-box;
overflow-x: hidden;
}
.infographic-alterrunner[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4ade80;
--good-soft: #123420;
--bad: #f87171;
--bad-soft: #3a1414;
--on-accent: #101418;
}
.infographic-alterrunner * { box-sizing: border-box; }
.at-topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; gap: 0.5rem; flex-wrap: wrap; }
.at-progress { font-size: 0.78rem; color: var(--ink-soft); }
.at-showfull-btn {
font: inherit; font-size: 0.78rem; background: none; border: 1px solid var(--line);
border-radius: 999px; padding: 0.35rem 0.8rem; cursor: pointer; color: var(--ink-soft);
}
.at-showfull-btn:hover { border-color: var(--accent); color: var(--accent); }
.at-showfull-btn.is-on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.at-fullcode-panel { display: none; margin-bottom: 1.25rem; }
.at-fullcode-panel.is-visible { display: block; }
.at-fullcode-scroll { overflow-x: auto; }
.at-fullcode {
background: var(--ink); color: #d4e2ff; border-radius: 8px; padding: 1rem 1.2rem;
font-family: var(--mono-font); font-size: 0.72rem; line-height: 1.7; white-space: pre; opacity: 0.85;
display: inline-block;
min-width: 100%;
}
.infographic-alterrunner[data-theme="dark"] .at-fullcode { background: #05070a; }
.at-frame { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 10px; padding: 1.25rem; }
.at-kw { color: #9cc5ff; } .at-str { color: #f8d980; } .at-num { color: #4ade80; } .at-cm { color: #7c8aa8; }
.at-step { display: none; margin-bottom: 1rem; }
.at-step.is-revealed { display: block; animation: at-step-in 0.4s ease; }
@keyframes at-step-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.at-step.is-done .at-step-code-full { display: none; }
.at-step.is-done .at-step-done-pill { display: flex; }
.at-step-done-pill {
display: none; align-items: center; gap: 0.5rem; background: var(--good-soft); color: var(--good);
border-radius: 7px; padding: 0.55rem 0.85rem; font-family: var(--mono-font); font-size: 0.78rem; cursor: pointer;
}
.at-step-done-pill .chevron { margin-left: auto; font-size: 0.7rem; opacity: 0.7; }
.at-step.is-expanded-done .at-step-code-full { display: block; }
.at-step.is-expanded-done .at-step-done-pill { background: var(--accent-soft); color: var(--accent); }
.at-step-label { font-family: var(--display-font); font-size: 1.02rem; margin: 0 0 0.5rem; }
.at-step-desc { font-size: 0.82rem; color: var(--ink-soft); margin: 0 0 0.7rem; line-height: 1.45; }
.at-code-scroll { overflow-x: auto; }
.at-code {
background: var(--ink); color: #d4e2ff; border-radius: 8px; padding: 0.85rem 1.05rem;
font-family: var(--mono-font); font-size: 0.8rem; line-height: 1.6; white-space: pre;
display: inline-block;
min-width: 100%;
}
.infographic-alterrunner[data-theme="dark"] .at-code { background: #05070a; }
.at-run-row { display: flex; justify-content: center; gap: 0.5rem; margin-top: 0.85rem; flex-wrap: wrap; }
.at-run-btn {
font: inherit; font-size: 0.83rem; background: var(--accent); color: var(--on-accent);
border: none; border-radius: 7px; padding: 0.55rem 1rem; cursor: pointer;
}
.at-run-btn:hover { opacity: 0.9; }
.at-run-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.at-run-btn.is-danger { background: var(--bad); }
.at-run-btn.is-secondary { background: var(--paper); color: var(--ink); border: 1px solid var(--line); }
.at-run-btn.at-next-btn { background: var(--good); display: none; }
.at-mini-msg {
margin-top: 0.7rem; padding: 0.55rem 0.75rem; border-radius: 7px; font-size: 0.8rem; line-height: 1.5; display: none;
}
.at-mini-msg.is-visible { display: block; }
.at-mini-msg.st-good { background: var(--good-soft); color: var(--good); }
.at-mini-msg.st-bad { background: var(--bad-soft); color: var(--bad); }
.at-output-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft); margin: 1.1rem 0 0.6rem; }
.at-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; }
table.at-table {
width: 100%; min-width: 260px; border-collapse: collapse; background: var(--paper);
border-radius: 8px; font-size: 0.85rem;
}
table.at-table th, table.at-table td {
border: 1px solid var(--line); padding: 0.5rem 0.65rem; text-align: left; white-space: nowrap;
transition: background 0.3s, color 0.3s;
}
table.at-table th { background: var(--accent); color: var(--on-accent); font-weight: 700; font-size: 0.72rem; }
table.at-table th.is-new-col, table.at-table td.is-new-col { animation: at-col-in 1.1s ease; }
@keyframes at-col-in { 0%,35% { background: var(--good-soft); } 100% { background: transparent; } }
table.at-table td.is-null { color: var(--ink-soft); font-style: italic; }
.at-mini-table-scroll { overflow-x: auto; margin-top: 0.7rem; }
table.at-mini-table {
width: 100%; min-width: 160px; border-collapse: collapse; background: var(--paper);
border-radius: 7px; font-size: 0.82rem;
}
table.at-mini-table th, table.at-mini-table td {
border: 1px solid var(--line); padding: 0.4rem 0.6rem; text-align: left; white-space: nowrap;
}
table.at-mini-table th { background: var(--accent); color: var(--on-accent); font-weight: 700; font-size: 0.7rem; }
table.at-mini-table tr.is-new td { animation: at-row-in 0.5s ease; }
@keyframes at-row-in { from { background: var(--good-soft); } to { background: transparent; } }
.at-reset-row { display: flex; justify-content: center; margin-top: 1.25rem; }
@media (prefers-reduced-motion: reduce) {
.infographic-alterrunner *, .infographic-alterrunner *::before, .infographic-alterrunner *::after {
transition-duration: 0.001ms !important; animation-duration: 0.001ms !important;
}
}
</style>
</head>
<body>
<div class="infographic-alterrunner" id="alterrunner">
<div class="at-topbar">
<span class="at-progress" id="atProgress"></span>
<button class="at-showfull-btn" id="atShowFullBtn" type="button">👁️ Show full SQL script</button>
</div>
<div class="at-fullcode-panel" id="atFullCodePanel">
<div class="at-fullcode-scroll">
<div class="at-fullcode" id="atFullCodeContent"></div>
</div>
</div>
<div class="at-frame">
<div id="atSteps"></div>
<p class="at-output-label">Table: students</p>
<div class="at-table-scroll">
<table class="at-table" id="atTable">
<thead id="atThead"><tr><th>id</th><th>name</th><th>grade</th></tr></thead>
<tbody id="atTbody"></tbody>
</table>
</div>
<div class="at-reset-row">
<button class="at-run-btn is-secondary" id="atReset" type="button">↺ Reset all</button>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('alterrunner');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
function kw(s) { return '<span class="at-kw">' + s + '</span>'; }
function str(s) { return '<span class="at-str">' + s + '</span>'; }
function cm(s) { return '<span class="at-cm">' + s + '</span>'; }
const baseRows = [
[1, 'Raj', 'B'],
[2, 'Tina', 'B'],
[3, 'Anya', 'A'],
[4, 'Sara', 'A']
];
const setupCode =
cm('-- Base Table') + '\n' +
kw('CREATE TABLE') + ' students (\n' +
' id ' + kw('INT IDENTITY') + '(1,1),\n' +
' name ' + kw('VARCHAR') + '(50),\n' +
' grade ' + kw('VARCHAR') + '(2)\n' +
');\n\n' +
cm('-- Sample Data') + '\n' +
kw('INSERT INTO') + ' students (name, grade) ' + kw('VALUES') + '\n' +
"(" + str("'Raj'") + ', ' + str("'B'") + '),\n' +
"(" + str("'Tina'") + ', ' + str("'B'") + '),\n' +
"(" + str("'Anya'") + ', ' + str("'A'") + '),\n' +
"(" + str("'Sara'") + ', ' + str("'A'") + ');';
const addEmailCode = kw('ALTER TABLE') + ' students\n' + kw('ADD') + ' email ' + kw('VARCHAR') + '(100);';
const modifyGradeCode = kw('ALTER TABLE') + ' students\n' + kw('ALTER COLUMN') + ' grade ' + kw('VARCHAR') + '(5);\n\n' +
cm('-- Now a longer value fits') + '\n' +
kw('INSERT INTO') + ' students (name, grade) ' + kw('VALUES') + '\n(' + str("'Ishaan'") + ', ' + str("'FAIL'") + ');';
const dropEmailCode = kw('ALTER TABLE') + ' students\n' + kw('DROP COLUMN') + ' email;';
const addPkCode = kw('ALTER TABLE') + ' students\n' + kw('ADD CONSTRAINT') + ' pk_students ' + kw('PRIMARY KEY') + ' (id);';
const addAgeCode = kw('ALTER TABLE') + ' students\n' + kw('ADD') + ' age ' + kw('INT') + ';';
const addFkCode = kw('ALTER TABLE') + ' enrollments\n' + kw('ADD CONSTRAINT') + ' fk_student\n' + kw('FOREIGN KEY') + ' (student_id) ' + kw('REFERENCES') + ' students(id);';
const table = document.getElementById('atTable');
const thead = document.getElementById('atThead');
const tbody = document.getElementById('atTbody');
const stepsContainer = document.getElementById('atSteps');
const progress = document.getElementById('atProgress');
const fullCodeContent = document.getElementById('atFullCodeContent');
function renderBaseRows() {
tbody.innerHTML = baseRows.map(r =>
'<tr data-id="' + r[0] + '"><td>' + r[0] + '</td><td>' + r[1] + '</td><td>' + r[2] + '</td></tr>'
).join('');
}
function addColumn(name) {
const th = document.createElement('th');
th.textContent = name;
th.className = 'is-new-col';
thead.querySelector('tr').appendChild(th);
tbody.querySelectorAll('tr').forEach(tr => {
const td = document.createElement('td');
td.className = 'is-null is-new-col';
td.textContent = 'NULL';
tr.appendChild(td);
});
}
function dropColumn(name) {
const headerCells = Array.from(thead.querySelectorAll('th'));
const idx = headerCells.findIndex(th => th.textContent === name);
if (idx === -1) return;
headerCells[idx].remove();
tbody.querySelectorAll('tr').forEach(tr => {
tr.children[idx].remove();
});
}
const steps = [
{ key: 'setup', title: '📌 Base Setup', desc: 'Every ALTER operation below acts on this same students table.',
code: setupCode, type: 'setup' },
{ key: 'addEmail', title: '➕ Add a New Column', desc: 'Adds a column named email — existing rows get NULL since no value was given for them.',
code: addEmailCode, type: 'addcol', colName: 'email' },
{ key: 'modifyGrade', title: '✏️ Modify Column Data Type', desc: 'Expands the grade column from VARCHAR(2) to VARCHAR(5), then inserts a student whose grade needs that extra room.',
code: modifyGradeCode, type: 'modifygrade' },
{ key: 'dropEmail', title: '❌ Drop a Column', desc: 'Removes the email column completely — structure and any data in it are both gone.',
code: dropEmailCode, type: 'dropcol', colName: 'email' },
{ key: 'addPk', title: '🔐 Add PRIMARY KEY', desc: 'Adds a PRIMARY KEY constraint to id — from now on, id must be unique and can never be NULL.',
code: addPkCode, type: 'addpk' },
{ key: 'addAge', title: '➕ Add age Column', desc: 'A second ADD COLUMN, this time to prepare for a related table.',
code: addAgeCode, type: 'addcol', colName: 'age' },
{ key: 'addFk', title: '🔗 Add FOREIGN KEY (on enrollments)', desc: 'A separate enrollments table gets a foreign key pointing back to students(id).',
code: addFkCode, type: 'fk' }
];
fullCodeContent.innerHTML = steps.map(s => s.code).join('\n\n');
steps.forEach((s, i) => {
const stepEl = document.createElement('div');
stepEl.className = 'at-step' + (i === 0 ? ' is-revealed' : '');
stepEl.id = 'step-' + s.key;
let extra = '';
if (s.type === 'fk') {
extra =
'<div class="at-mini-table-scroll"><p class="at-step-desc" style="margin-bottom:0.3rem;">enrollments</p>' +
'<table class="at-mini-table" id="fkTable"><thead><tr><th>student_id</th></tr></thead><tbody id="fkTbody"></tbody></table>' +
'</div>' +
'<div class="at-run-row">' +
'<button class="at-run-btn" id="btn-addFk" type="button">▶ Run ADD CONSTRAINT</button>' +
'<button class="at-run-btn" id="btn-fkValid" type="button" disabled>✔️ Insert student_id = 1</button>' +
'<button class="at-run-btn is-danger" id="btn-fkInvalid" type="button" disabled>❌ Insert student_id = 99</button>' +
'</div>';
} else if (s.type === 'addpk') {
extra =
'<div class="at-run-row">' +
'<button class="at-run-btn" id="btn-addPk" type="button">▶ Run ADD CONSTRAINT</button>' +
'<button class="at-run-btn is-danger" id="btn-pkDup" type="button" disabled>❌ Insert id = 1 (duplicate)</button>' +
'<button class="at-run-btn" id="btn-pkNew" type="button" disabled>✔️ Insert id = 6 (new)</button>' +
'</div>';
} else {
const label = s.type === 'setup' ? 'Setup' : (s.type === 'modifygrade' ? 'ALTER + INSERT' : 'ALTER');
extra = '<div class="at-run-row"><button class="at-run-btn" id="btn-' + s.key + '" type="button">▶ Run ' + label + '</button></div>';
}
stepEl.innerHTML =
'<div class="at-step-done-pill"><span>✓ ' + s.title + '</span><span class="chevron">\u25be view code</span></div>' +
'<div class="at-step-code-full">' +
'<p class="at-step-label">' + s.title + '</p>' +
'<p class="at-step-desc">' + s.desc + '</p>' +
'<div class="at-code-scroll"><div class="at-code">' + s.code + '</div></div>' +
extra +
'<p class="at-mini-msg" id="msg-' + s.key + '"></p>' +
(i < steps.length - 1 ? '<div class="at-run-row"><button class="at-run-btn at-next-btn" id="nextstep-' + s.key + '" type="button">Next operation →</button></div>' : '') +
'</div>';
stepsContainer.appendChild(stepEl);
});
function updateProgress(doneCount) {
progress.textContent = doneCount + ' / ' + steps.length + ' operations run';
}
updateProgress(0);
function showMsg(key, text, kind) {
const el = document.getElementById('msg-' + key);
el.textContent = text;
el.className = 'at-mini-msg is-visible st-' + kind;
}
function unlockNext(key) {
const btn = document.getElementById('nextstep-' + key);
if (btn) btn.style.display = 'inline-block';
}
function finishStep(key) {
const el = document.getElementById('step-' + key);
if (!el.dataset.counted) {
el.dataset.counted = '1';
doneCount++;
updateProgress(doneCount);
}
}
let doneCount = 0;
function goToNext(key) {
document.getElementById('step-' + key).classList.add('is-done');
doneCount++;
updateProgress(doneCount);
const idx = steps.findIndex(s => s.key === key);
const next = steps[idx + 1];
if (next) {
const nextEl = document.getElementById('step-' + next.key);
nextEl.classList.add('is-revealed');
nextEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
steps.forEach(s => {
if (s.type === 'setup') {
document.getElementById('btn-setup').addEventListener('click', () => {
document.getElementById('btn-setup').disabled = true;
renderBaseRows();
showMsg(s.key, 'Table created, ' + baseRows.length + ' rows inserted.', 'good');
unlockNext(s.key);
});
} else if (s.type === 'addcol') {
document.getElementById('btn-' + s.key).addEventListener('click', () => {
document.getElementById('btn-' + s.key).disabled = true;
addColumn(s.colName);
showMsg(s.key, 'Column "' + s.colName + '" added — existing rows get NULL.', 'good');
unlockNext(s.key);
});
} else if (s.type === 'modifygrade') {
document.getElementById('btn-' + s.key).addEventListener('click', () => {
document.getElementById('btn-' + s.key).disabled = true;
const nextId = baseRows.length > 0 ? Math.max(...Array.from(tbody.querySelectorAll('tr')).map(tr => Number(tr.dataset.id))) + 1 : 1;
const colCount = thead.querySelectorAll('th').length;
const tr = document.createElement('tr');
tr.className = 'is-new';
tr.dataset.id = nextId;
let cells = '<td>' + nextId + '</td><td>Ishaan</td><td>FAIL</td>';
for (let c = 3; c < colCount; c++) cells += '<td class="is-null">NULL</td>';
tr.innerHTML = cells;
tbody.appendChild(tr);
showMsg(s.key, 'grade widened to VARCHAR(5), then Ishaan inserted with grade "FAIL" — that would have been rejected before.', 'good');
unlockNext(s.key);
});
} else if (s.type === 'addpk') {
let pkCompleted = 0;
document.getElementById('btn-addPk').addEventListener('click', () => {
document.getElementById('btn-addPk').disabled = true;
showMsg(s.key, 'Constraint added — id must now be unique and non-null.', 'good');
document.getElementById('btn-pkDup').disabled = false;
document.getElementById('btn-pkNew').disabled = false;
});
document.getElementById('btn-pkDup').addEventListener('click', () => {
document.getElementById('btn-pkDup').disabled = true;
showMsg(s.key, "Blocked — Duplicate entry '1' for key PRIMARY. id must be unique.", 'bad');
pkCompleted++;
if (pkCompleted === 2) unlockNext(s.key);
});
document.getElementById('btn-pkNew').addEventListener('click', () => {
document.getElementById('btn-pkNew').disabled = true;
const colCount = thead.querySelectorAll('th').length;
const tr = document.createElement('tr');
tr.className = 'is-new';
tr.dataset.id = 6;
let cells = '<td>6</td><td>Kabir</td><td>B</td>';
for (let c = 3; c < colCount; c++) cells += '<td class="is-null">NULL</td>';
tr.innerHTML = cells;
tbody.appendChild(tr);
showMsg(s.key, 'Row inserted — id 6 is new and unique.', 'good');
pkCompleted++;
if (pkCompleted === 2) unlockNext(s.key);
});
} else if (s.type === 'metaonly') {
document.getElementById('btn-' + s.key).addEventListener('click', () => {
document.getElementById('btn-' + s.key).disabled = true;
showMsg(s.key, s.msg, 'good');
unlockNext(s.key);
});
} else if (s.type === 'dropcol') {
document.getElementById('btn-' + s.key).addEventListener('click', () => {
document.getElementById('btn-' + s.key).disabled = true;
dropColumn(s.colName);
showMsg(s.key, 'Column "' + s.colName + '" removed — structure and data both gone.', 'bad');
unlockNext(s.key);
});
} else if (s.type === 'fk') {
const fkTbody = document.getElementById('fkTbody');
document.getElementById('btn-addFk').addEventListener('click', () => {
document.getElementById('btn-addFk').disabled = true;
showMsg(s.key, 'Constraint added — enrollments.student_id must now exist in students.id.', 'good');
document.getElementById('btn-fkValid').disabled = false;
document.getElementById('btn-fkInvalid').disabled = false;
});
document.getElementById('btn-fkValid').addEventListener('click', () => {
document.getElementById('btn-fkValid').disabled = true;
const tr = document.createElement('tr');
tr.className = 'is-new';
tr.innerHTML = '<td>1</td>';
fkTbody.appendChild(tr);
showMsg(s.key, 'Row inserted — student_id 1 exists in students. ✅ All ALTER operations complete!', 'good');
finishStep(s.key);
});
document.getElementById('btn-fkInvalid').addEventListener('click', () => {
document.getElementById('btn-fkInvalid').disabled = true;
showMsg(s.key, 'Blocked — Key (student_id)=(99) is not present in table "students". ✅ All ALTER operations complete!', 'bad');
finishStep(s.key);
});
}
const nextBtn = document.getElementById('nextstep-' + s.key);
if (nextBtn) nextBtn.addEventListener('click', () => goToNext(s.key));
});
document.getElementById('atShowFullBtn').addEventListener('click', function () {
const panel = document.getElementById('atFullCodePanel');
const on = panel.classList.toggle('is-visible');
this.classList.toggle('is-on', on);
this.textContent = on ? '👁️ Hide full SQL script' : '👁️ Show full SQL script';
});
document.querySelectorAll('.at-step-done-pill').forEach(pill => {
pill.addEventListener('click', () => {
const step = pill.closest('.at-step');
step.classList.toggle('is-expanded-done');
pill.querySelector('.chevron').textContent = step.classList.contains('is-expanded-done') ? '\u25b4 hide code' : '\u25be view code';
});
});
document.getElementById('atReset').addEventListener('click', () => {
doneCount = 0;
updateProgress(0);
thead.innerHTML = '<tr><th>id</th><th>name</th><th>grade</th></tr>';
tbody.innerHTML = '';
steps.forEach((s, i) => {
const el = document.getElementById('step-' + s.key);
el.classList.remove('is-done', 'is-expanded-done');
el.classList.toggle('is-revealed', i === 0);
delete el.dataset.counted;
document.getElementById('msg-' + s.key).classList.remove('is-visible');
const nextBtn = document.getElementById('nextstep-' + s.key);
if (nextBtn) nextBtn.style.display = 'none';
if (s.type === 'fk') {
document.getElementById('btn-addFk').disabled = false;
document.getElementById('btn-fkValid').disabled = true;
document.getElementById('btn-fkInvalid').disabled = true;
document.getElementById('fkTbody').innerHTML = '';
} else if (s.type === 'addpk') {
document.getElementById('btn-addPk').disabled = false;
document.getElementById('btn-pkDup').disabled = true;
document.getElementById('btn-pkNew').disabled = true;
} else {
const btn = document.getElementById('btn-' + s.key);
if (btn) btn.disabled = false;
}
});
});
})();
</script>
</body>
</html>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});📘 Summary Table
Operation | Example |
|---|---|
Add Column |
|
Modify Column |
|
Drop Column |
|
Add PK |
|
Add FK |
|