{"id":4627,"date":"2026-05-28T08:15:18","date_gmt":"2026-05-28T08:15:18","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=4627"},"modified":"2026-08-09T10:14:59","modified_gmt":"2026-08-09T10:14:59","slug":"csv-to-sql-query-converter","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/csv-to-sql-query-converter\/","title":{"rendered":"Free CSV to SQL Query Converter | 100% Offline Generator"},"content":{"rendered":"<div class=\"pth-hero-section\">\n<div class=\"pth-hero-content\">\n<h2><b data-path-to-node=\"1,1,0\" data-index-in-node=\"0\">Offline CSV to SQL Converter<\/b> | Instant Database Scripts, Completely Private &amp; Free<\/h2>\n<p>Convert CSV data to SQL INSERT queries instantly with our 100% offline, secure CSV to SQL Query Converter. Generate CREATE TABLE scripts locally in your browser.<\/p>\n<div id=\"pth-toc-placeholder\">\u00a0<\/div>\n<\/div>\n<div class=\"pth-hero-image\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/05\/CSV-to-SQL-query-converter-800x447.jpeg\" alt=\"CSV to SQL query converter\" width=\"450\" height=\"253\" data-no-lazy=\"1\" \/><\/div>\n<\/div>\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#\ud83d\udd34-what-it-converts-and-when-youd-reach-for-it\">\ud83d\udd34\u00a0What it converts, and when you&#8217;d reach for it<\/a><\/li><li><a href=\"#\ud83d\udfe1-from-spreadsheet-to-database-in-a-few-clicks\">\ud83d\udfe1\u00a0From spreadsheet to database in a few clicks<\/a><\/li><li><a href=\"#\ud83d\udfe2-getting-the-data-types-and-dialect-right\">\ud83d\udfe2\u00a0Getting the data types and dialect right<\/a><\/li><\/ul><\/nav><\/div>\n\n\n<!-- ================================================================\r\n  CSV <-> SQL DATA CONVERTER v6.0  (PrimeToolHub #60)\r\n  Slug: csv-to-sql-query-converter\r\n  100% offline, self-contained. Scoped to #pth-sqlcsv-wrap.\r\n  Woody HTML snippet - HTML + Vanilla JS (ES5) + scoped CSS.\r\n  JSON conversion intentionally excluded (that is JSON Studio Pro) - cross-linked (rule E5).\r\n================================================================= -->\r\n\r\n<style>\r\n#pth-sqlcsv-wrap *, #pth-sqlcsv-wrap *::before, #pth-sqlcsv-wrap *::after { box-sizing: border-box; min-width: 0; }\r\n#pth-sqlcsv-wrap { font-family: 'Inter', system-ui, -apple-system, \"Segoe UI\", sans-serif; color: #1e293b; font-weight: 500; line-height: 1.6; max-width: 1480px; margin: 0 auto; padding: 0 20px; }\r\n#pth-sqlcsv-wrap .pth-sc-topbar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 16px 22px; margin-bottom: 16px; }\r\n#pth-sqlcsv-wrap .pth-sc-brand { display: flex; align-items: center; gap: 14px; }\r\n#pth-sqlcsv-wrap .pth-sc-icon { width: 46px; height: 46px; border-radius: 11px; background: #4f46e5; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 22px; flex: 0 0 auto; }\r\n#pth-sqlcsv-wrap .pth-sc-title { font-size: 1.4rem; font-weight: 800; color: #0f172a; margin: 0; }\r\n#pth-sqlcsv-wrap .pth-sc-sub { font-size: 0.8rem; color: #334155; font-weight: 600; margin: 2px 0 0; }\r\n#pth-sqlcsv-wrap .pth-sc-badges { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }\r\n#pth-sqlcsv-wrap .pth-sc-badge { font-size: 0.72rem; font-weight: 800; padding: 5px 11px; border-radius: 20px; border: 1px solid #e2e8f0; color: #334155; background: #f8fafc; }\r\n#pth-sqlcsv-wrap .pth-sc-badge.off { color: #047857; border-color: #a7f3d0; background: #ecfdf5; }\r\n#pth-sqlcsv-wrap .pth-sc-badge.ver { color: #4338ca; border-color: #c7d2fe; background: #eef2ff; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-tabs { display: flex; gap: 6px; background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 12px; padding: 5px; margin-bottom: 18px; flex-wrap: wrap; }\r\n#pth-sqlcsv-wrap .pth-sc-tab { flex: 1 1 auto; min-width: 130px; padding: 11px 14px; border: none; cursor: pointer; border-radius: 8px; background: transparent; color: #334155; font-family: inherit; font-size: 0.9rem; font-weight: 700; }\r\n#pth-sqlcsv-wrap .pth-sc-tab:hover { color: #0f172a; }\r\n#pth-sqlcsv-wrap .pth-sc-tab.active { background: #4f46e5; color: #fff; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-panel { display: none; }\r\n#pth-sqlcsv-wrap .pth-sc-panel.active { display: block; }\r\n#pth-sqlcsv-wrap .pth-sc-io { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }\r\n#pth-sqlcsv-wrap.full .pth-sc-io { grid-template-columns: 1fr; }\r\n#pth-sqlcsv-wrap .pth-sc-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 18px; }\r\n#pth-sqlcsv-wrap .pth-sc-ctitle { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: #4338ca; margin: 0 0 12px; }\r\n\r\n#pth-sqlcsv-wrap textarea.pth-sc-ta { width: 100%; min-height: 240px; resize: vertical; border: 1.5px solid #e2e8f0; border-radius: 10px; padding: 12px 14px; font-family: 'JetBrains Mono', ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; font-size: 0.84rem; line-height: 1.6; color: #1e293b; background: #f8fafc; outline: none; white-space: pre; overflow: auto; }\r\n#pth-sqlcsv-wrap textarea.pth-sc-ta:focus { border-color: #4f46e5; background: #fff; }\r\n#pth-sqlcsv-wrap textarea.pth-sc-out { background: #0f172a; color: #e2e8f0; border-color: #1e293b; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin: 14px 0; }\r\n#pth-sqlcsv-wrap .pth-sc-fg { display: flex; flex-direction: column; gap: 5px; }\r\n#pth-sqlcsv-wrap .pth-sc-label { font-size: 0.7rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; color: #334155; }\r\n#pth-sqlcsv-wrap .pth-sc-input, #pth-sqlcsv-wrap .pth-sc-select { width: 100%; border: 1px solid #e2e8f0; border-radius: 8px; padding: 9px 11px; background: #f8fafc; font-family: inherit; font-size: 0.86rem; font-weight: 600; color: #1e293b; outline: none; }\r\n#pth-sqlcsv-wrap .pth-sc-input:focus, #pth-sqlcsv-wrap .pth-sc-select:focus { border-color: #4f46e5; background: #fff; }\r\n#pth-sqlcsv-wrap .pth-sc-checks { display: flex; gap: 14px; flex-wrap: wrap; margin: 6px 0 14px; }\r\n#pth-sqlcsv-wrap .pth-sc-chk { display: flex; align-items: center; gap: 6px; font-size: 0.82rem; font-weight: 600; color: #334155; }\r\n#pth-sqlcsv-wrap .pth-sc-chk input { width: 15px; height: 15px; accent-color: #4f46e5; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-btn { display: inline-flex; align-items: center; gap: 7px; padding: 10px 16px; border-radius: 8px; border: 1px solid transparent; font-family: inherit; font-size: 0.86rem; font-weight: 700; cursor: pointer; }\r\n#pth-sqlcsv-wrap .pth-sc-btn:disabled { opacity: 0.5; cursor: not-allowed; }\r\n#pth-sqlcsv-wrap .pth-sc-btn.sm { padding: 7px 12px; font-size: 0.8rem; }\r\n#pth-sqlcsv-wrap .pth-sc-primary { background: #4f46e5; color: #fff; }\r\n#pth-sqlcsv-wrap .pth-sc-primary:hover:not(:disabled) { background: #4338ca; }\r\n#pth-sqlcsv-wrap .pth-sc-ghost { background: #f8fafc; color: #334155; border-color: #e2e8f0; }\r\n#pth-sqlcsv-wrap .pth-sc-ghost:hover:not(:disabled) { background: #f1f5f9; color: #0f172a; }\r\n#pth-sqlcsv-wrap .pth-sc-danger { background: #fef2f2; color: #991b1b; border-color: #fecaca; }\r\n#pth-sqlcsv-wrap .pth-sc-danger:hover:not(:disabled) { background: #fee2e2; }\r\n#pth-sqlcsv-wrap .pth-sc-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }\r\n#pth-sqlcsv-wrap .pth-sc-outhead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-note { font-size: 0.82rem; color: #334155; background: #eef2ff; border: 1px solid #c7d2fe; border-radius: 8px; padding: 10px 12px; margin-top: 12px; }\r\n#pth-sqlcsv-wrap .pth-sc-note a { color: #4338ca; font-weight: 700; }\r\n#pth-sqlcsv-wrap .pth-sc-msg { font-size: 0.84rem; border-radius: 8px; padding: 10px 12px; margin-top: 10px; display: none; }\r\n#pth-sqlcsv-wrap .pth-sc-msg.ok { display: block; color: #047857; background: #ecfdf5; border: 1px solid #a7f3d0; }\r\n#pth-sqlcsv-wrap .pth-sc-msg.bad { display: block; color: #991b1b; background: #fef2f2; border: 1px solid #fecaca; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-preview { overflow: auto; border: 1px solid #e2e8f0; border-radius: 10px; }\r\n#pth-sqlcsv-wrap table.pth-sc-tbl { border-collapse: collapse; width: 100%; font-size: 0.84rem; }\r\n#pth-sqlcsv-wrap table.pth-sc-tbl th, #pth-sqlcsv-wrap table.pth-sc-tbl td { border: 1px solid #e2e8f0; padding: 7px 10px; text-align: left; white-space: nowrap; }\r\n#pth-sqlcsv-wrap table.pth-sc-tbl th { background: #eef2ff; color: #3730a3; font-weight: 800; }\r\n#pth-sqlcsv-wrap table.pth-sc-tbl tr:nth-child(even) td { background: #f8fafc; }\r\n#pth-sqlcsv-wrap .pth-sc-typerow { font-size: 0.74rem; color: #64748b; margin-top: 8px; }\r\n#pth-sqlcsv-wrap .pth-sc-typerow b { color: #4338ca; }\r\n\r\n#pth-sqlcsv-wrap .pth-sc-toast { position: fixed; bottom: 22px; right: 22px; z-index: 999999; display: none; padding: 13px 18px; border-radius: 10px; color: #fff; font-family: 'Inter', system-ui, sans-serif; font-size: 0.9rem; font-weight: 700; box-shadow: 0 8px 24px rgba(15,23,42,0.2); max-width: 320px; }\r\n#pth-sqlcsv-wrap .pth-sc-toast.show { display: block; }\r\n#pth-sqlcsv-wrap .pth-sc-hidden { display: none !important; }\r\n\r\n@media (max-width: 768px) {\r\n  #pth-sqlcsv-wrap { padding: 0 10px; }\r\n  #pth-sqlcsv-wrap .pth-sc-io { grid-template-columns: 1fr; }\r\n}\r\n<\/style>\r\n\r\n<div id=\"pth-sqlcsv-wrap\">\r\n\r\n  <div class=\"pth-sc-topbar\">\r\n    <div class=\"pth-sc-brand\">\r\n      <div class=\"pth-sc-icon\" aria-hidden=\"true\">&#128451;&#65039;<\/div>\r\n      <div>\r\n        <h2 class=\"pth-sc-title\">CSV &harr; SQL Data Converter<\/h2>\r\n        <p class=\"pth-sc-sub\">CSV to SQL, SQL to CSV, and table exports across 6 dialects &mdash; fully offline<\/p>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"pth-sc-badges\">\r\n      <span class=\"pth-sc-badge ver\">v6.1<\/span>\r\n      <span class=\"pth-sc-badge off\">&#128274; 100% Offline<\/span>\r\n      <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"sample\">&#128161; Sample<\/button>\r\n      <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"wide\">&#9906; Wide<\/button>\r\n      <button type=\"button\" class=\"pth-sc-btn pth-sc-danger sm\" data-action=\"clear\">&#128465;&#65039; Clear<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"pth-sc-tabs\" role=\"tablist\">\r\n    <button type=\"button\" class=\"pth-sc-tab active\" data-tab=\"c2s\" role=\"tab\">&#8594; CSV to SQL<\/button>\r\n    <button type=\"button\" class=\"pth-sc-tab\" data-tab=\"s2c\" role=\"tab\">&#8592; SQL to CSV<\/button>\r\n    <button type=\"button\" class=\"pth-sc-tab\" data-tab=\"tbl\" role=\"tab\">&#128203; CSV to Table<\/button>\r\n    <button type=\"button\" class=\"pth-sc-tab\" data-tab=\"prev\" role=\"tab\">&#128269; Preview &amp; Validate<\/button>\r\n  <\/div>\r\n\r\n  <!-- ===== CSV -> SQL ===== -->\r\n  <div class=\"pth-sc-panel active\" data-panel=\"c2s\">\r\n    <div class=\"pth-sc-card\" style=\"margin-bottom:16px;\">\r\n      <p class=\"pth-sc-ctitle\">Options<\/p>\r\n      <div class=\"pth-sc-opts\">\r\n        <div class=\"pth-sc-fg\"><label class=\"pth-sc-label\" for=\"sc-table\">Table name<\/label><input id=\"sc-table\" class=\"pth-sc-input\" type=\"text\" value=\"my_table\"><\/div>\r\n        <div class=\"pth-sc-fg\"><label class=\"pth-sc-label\" for=\"sc-dialect\">SQL dialect<\/label>\r\n          <select id=\"sc-dialect\" class=\"pth-sc-select\">\r\n            <option value=\"standard\">Standard SQL<\/option><option value=\"mysql\" selected>MySQL<\/option>\r\n            <option value=\"postgres\">PostgreSQL<\/option><option value=\"mssql\">SQL Server<\/option>\r\n            <option value=\"sqlite\">SQLite<\/option><option value=\"oracle\">Oracle<\/option>\r\n          <\/select><\/div>\r\n        <div class=\"pth-sc-fg\"><label class=\"pth-sc-label\" for=\"sc-stmt\">Statement<\/label>\r\n          <select id=\"sc-stmt\" class=\"pth-sc-select\">\r\n            <option value=\"insert\">INSERT<\/option><option value=\"create\">CREATE TABLE<\/option>\r\n            <option value=\"createinsert\">CREATE TABLE + INSERT<\/option><option value=\"update\">UPDATE<\/option>\r\n            <option value=\"delete\">DELETE<\/option><option value=\"upsert\">UPSERT \/ MERGE<\/option>\r\n          <\/select><\/div>\r\n        <div class=\"pth-sc-fg\"><label class=\"pth-sc-label\" for=\"sc-delim\">Delimiter<\/label>\r\n          <select id=\"sc-delim\" class=\"pth-sc-select\">\r\n            <option value=\",\">Comma (,)<\/option><option value=\";\">Semicolon (;)<\/option>\r\n            <option value=\"|\">Pipe (|)<\/option><option value=\"\\t\">Tab<\/option><\/select><\/div>\r\n        <div class=\"pth-sc-fg pth-sc-hidden\" id=\"sc-key-wrap\"><label class=\"pth-sc-label\" for=\"sc-key\">Key column<\/label>\r\n          <select id=\"sc-key\" class=\"pth-sc-select\"><\/select><\/div>\r\n        <div class=\"pth-sc-fg pth-sc-hidden\" id=\"sc-pk-wrap\"><label class=\"pth-sc-label\" for=\"sc-pk\">Primary key<\/label>\r\n          <select id=\"sc-pk\" class=\"pth-sc-select\"><\/select><\/div>\r\n      <\/div>\r\n      <div class=\"pth-sc-checks\">\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-header\" checked> First row is header<\/label>\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-types\" checked> Smart type inference<\/label>\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-null\" checked> Empty cells as NULL<\/label>\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-trim\" checked> Trim whitespace<\/label>\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-batch\" checked> Multi-row INSERT<\/label>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"pth-sc-io\">\r\n      <div class=\"pth-sc-card\">\r\n        <p class=\"pth-sc-ctitle\">CSV input<\/p>\r\n        <textarea id=\"sc-c2s-in\" class=\"pth-sc-ta\" aria-label=\"CSV input\" placeholder=\"id,name,price,in_stock&#10;1,Keyboard,29.99,true&#10;2,Mouse,15.50,false\"><\/textarea>\r\n        <div class=\"pth-sc-actions\">\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-primary\" data-action=\"c2s\">&#9889; Convert to SQL<\/button>\r\n        <\/div>\r\n        <div class=\"pth-sc-typerow\" id=\"sc-typeinfo\"><\/div>\r\n      <\/div>\r\n      <div class=\"pth-sc-card\">\r\n        <div class=\"pth-sc-outhead\"><p class=\"pth-sc-ctitle\" style=\"margin:0;\">SQL output<\/p><\/div>\r\n        <textarea id=\"sc-c2s-out\" class=\"pth-sc-ta pth-sc-out\" aria-label=\"SQL output\" readonly><\/textarea>\r\n        <div class=\"pth-sc-actions\">\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"copy\" data-src=\"sc-c2s-out\">&#128203; Copy<\/button>\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"download\" data-src=\"sc-c2s-out\" data-name=\"queries.sql\">&#8681; Download .sql<\/button>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"pth-sc-note\">Need JSON instead of SQL? Use <a href=\"https:\/\/schoolict.net\/tools\/free-jsonpath-evaluator-extractor\/\" target=\"_blank\" rel=\"noopener\">JSON Studio Pro<\/a> for CSV\/JSON conversion and querying.<\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== SQL -> CSV ===== -->\r\n  <div class=\"pth-sc-panel\" data-panel=\"s2c\">\r\n    <div class=\"pth-sc-io\">\r\n      <div class=\"pth-sc-card\">\r\n        <p class=\"pth-sc-ctitle\">SQL input (INSERT statements)<\/p>\r\n        <textarea id=\"sc-s2c-in\" class=\"pth-sc-ta\" aria-label=\"SQL input\" placeholder=\"INSERT INTO products (id, name, price) VALUES&#10;(1, 'Keyboard', 29.99),&#10;(2, 'Mouse', 15.50);\"><\/textarea>\r\n        <div class=\"pth-sc-actions\">\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-primary\" data-action=\"s2c\">&#9889; Convert to CSV<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"pth-sc-card\">\r\n        <p class=\"pth-sc-ctitle\">CSV output<\/p>\r\n        <textarea id=\"sc-s2c-out\" class=\"pth-sc-ta pth-sc-out\" aria-label=\"CSV output\" readonly><\/textarea>\r\n        <div class=\"pth-sc-actions\">\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"copy\" data-src=\"sc-s2c-out\">&#128203; Copy<\/button>\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"download\" data-src=\"sc-s2c-out\" data-name=\"data.csv\">&#8681; Download .csv<\/button>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== CSV -> TABLE ===== -->\r\n  <div class=\"pth-sc-panel\" data-panel=\"tbl\">\r\n    <div class=\"pth-sc-card\" style=\"margin-bottom:16px;\">\r\n      <div class=\"pth-sc-checks\">\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-tbl-header\" checked> First row is header<\/label>\r\n        <span class=\"pth-sc-fg\" style=\"max-width:200px;\"><select id=\"sc-tbl-fmt\" class=\"pth-sc-select\"><option value=\"md\">Markdown table<\/option><option value=\"html\">HTML table<\/option><\/select><\/span>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"pth-sc-io\">\r\n      <div class=\"pth-sc-card\">\r\n        <p class=\"pth-sc-ctitle\">CSV input<\/p>\r\n        <textarea id=\"sc-tbl-in\" class=\"pth-sc-ta\" aria-label=\"CSV input for table\" placeholder=\"Name,Role,City&#10;Ada,Engineer,London&#10;Alan,Analyst,Leeds\"><\/textarea>\r\n        <div class=\"pth-sc-actions\"><button type=\"button\" class=\"pth-sc-btn pth-sc-primary\" data-action=\"tbl\">&#9889; Convert to Table<\/button><\/div>\r\n      <\/div>\r\n      <div class=\"pth-sc-card\">\r\n        <p class=\"pth-sc-ctitle\">Table output<\/p>\r\n        <textarea id=\"sc-tbl-out\" class=\"pth-sc-ta pth-sc-out\" aria-label=\"Table output\" readonly><\/textarea>\r\n        <div class=\"pth-sc-actions\">\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"copy\" data-src=\"sc-tbl-out\">&#128203; Copy<\/button>\r\n          <button type=\"button\" class=\"pth-sc-btn pth-sc-ghost sm\" data-action=\"download\" data-src=\"sc-tbl-out\" data-name=\"table.txt\">&#8681; Download<\/button>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== PREVIEW & VALIDATE ===== -->\r\n  <div class=\"pth-sc-panel\" data-panel=\"prev\">\r\n    <div class=\"pth-sc-card\">\r\n      <p class=\"pth-sc-ctitle\">Paste CSV to validate and preview<\/p>\r\n      <textarea id=\"sc-prev-in\" class=\"pth-sc-ta\" aria-label=\"CSV to validate\" placeholder=\"Paste CSV here...\"><\/textarea>\r\n      <div class=\"pth-sc-checks\" style=\"margin-top:12px;\">\r\n        <label class=\"pth-sc-chk\"><input type=\"checkbox\" id=\"sc-prev-header\" checked> First row is header<\/label>\r\n      <\/div>\r\n      <div class=\"pth-sc-actions\">\r\n        <button type=\"button\" class=\"pth-sc-btn pth-sc-primary\" data-action=\"validate\">&#9989; Validate &amp; Preview<\/button>\r\n      <\/div>\r\n      <div class=\"pth-sc-msg\" id=\"sc-prev-msg\" role=\"status\"><\/div>\r\n      <div class=\"pth-sc-preview pth-sc-hidden\" id=\"sc-prev-tblwrap\" style=\"margin-top:14px;\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"pth-sc-toast\" class=\"pth-sc-toast\" role=\"status\" aria-live=\"polite\"><\/div>\r\n<\/div>\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n  if (window.pthSqlCsvApp) { return; }\r\n\r\n  \/* Angle-bracket + backtick helpers from char codes, so no raw tag substring,\r\n     bare angle-regex, or literal backtick sits in this inline script. WordPress\/\r\n     LiteSpeed mangles those inside inline scripts and kills the whole block\r\n     (every button dies). Runtime output is byte-identical. *\/\r\n  var LT = String.fromCharCode(60); \/* < *\/\r\n  var GT = String.fromCharCode(62); \/* > *\/\r\n  var BT = String.fromCharCode(96); \/* backtick *\/\r\n\r\n  var DIALECTS = {\r\n    standard: { open: '\"', close: '\"', t: { int: 'INTEGER', bigint: 'BIGINT', decimal: 'DECIMAL(18,4)', date: 'DATE', datetime: 'TIMESTAMP', bool: 'BOOLEAN', text: 'VARCHAR' }, boolLit: function (b) { return b ? 'TRUE' : 'FALSE'; } },\r\n    mysql: { open: BT, close: BT, t: { int: 'INT', bigint: 'BIGINT', decimal: 'DECIMAL(18,4)', date: 'DATE', datetime: 'DATETIME', bool: 'TINYINT(1)', text: 'VARCHAR' }, boolLit: function (b) { return b ? '1' : '0'; } },\r\n    postgres: { open: '\"', close: '\"', t: { int: 'INTEGER', bigint: 'BIGINT', decimal: 'NUMERIC(18,4)', date: 'DATE', datetime: 'TIMESTAMP', bool: 'BOOLEAN', text: 'VARCHAR' }, boolLit: function (b) { return b ? 'TRUE' : 'FALSE'; } },\r\n    mssql: { open: '[', close: ']', t: { int: 'INT', bigint: 'BIGINT', decimal: 'DECIMAL(18,4)', date: 'DATE', datetime: 'DATETIME', bool: 'BIT', text: 'VARCHAR' }, boolLit: function (b) { return b ? '1' : '0'; } },\r\n    sqlite: { open: '\"', close: '\"', t: { int: 'INTEGER', bigint: 'INTEGER', decimal: 'REAL', date: 'TEXT', datetime: 'TEXT', bool: 'INTEGER', text: 'TEXT' }, boolLit: function (b) { return b ? '1' : '0'; } },\r\n    oracle: { open: '\"', close: '\"', t: { int: 'NUMBER(10)', bigint: 'NUMBER(19)', decimal: 'NUMBER(18,4)', date: 'DATE', datetime: 'TIMESTAMP', bool: 'NUMBER(1)', text: 'VARCHAR2' }, boolLit: function (b) { return b ? '1' : '0'; } }\r\n  };\r\n\r\n  var App = {\r\n    initialized: false, root: null, lastTypes: null,\r\n\r\n    init: function () {\r\n      this.root = document.getElementById('pth-sqlcsv-wrap');\r\n      if (!this.root) { return; }\r\n      this.attach();\r\n    },\r\n\r\n    attach: function () {\r\n      var self = this;\r\n      this.root.addEventListener('click', function (e) {\r\n        var el = e.target;\r\n        while (el && el !== self.root && !el.getAttribute('data-action') && !el.getAttribute('data-tab')) { el = el.parentNode; }\r\n        if (!el || el === self.root) { return; }\r\n        if (el.getAttribute('data-tab')) { self.switchTab(el.getAttribute('data-tab')); return; }\r\n        var a = el.getAttribute('data-action');\r\n        if (!a) { return; }\r\n        try { self.handle(a, el); } catch (err) { self.toast('Something went wrong. Check your input.', 'error'); if (window.console) { console.error('[SqlCsv]', err); } }\r\n      });\r\n      this.root.addEventListener('change', function (e) {\r\n        if (e.target.id === 'sc-stmt') { self.syncStmtOptions(); }\r\n      });\r\n    },\r\n\r\n    handle: function (a, el) {\r\n      switch (a) {\r\n        case 'sample': this.loadSample(); break;\r\n        case 'wide': this.root.className = this.root.className.indexOf('full') > -1 ? '' : 'full'; break;\r\n        case 'clear': this.clearActive(); break;\r\n        case 'c2s': this.csvToSql(); break;\r\n        case 's2c': this.sqlToCsv(); break;\r\n        case 'tbl': this.csvToTable(); break;\r\n        case 'validate': this.validate(); break;\r\n        case 'copy': this.copy(el.getAttribute('data-src')); break;\r\n        case 'download': this.download(el.getAttribute('data-src'), el.getAttribute('data-name')); break;\r\n      }\r\n    },\r\n\r\n    switchTab: function (name) {\r\n      var tabs = this.root.querySelectorAll('.pth-sc-tab'), i;\r\n      for (i = 0; i < tabs.length; i++) { tabs[i].className = 'pth-sc-tab' + (tabs[i].getAttribute('data-tab') === name ? ' active' : ''); }\r\n      var panels = this.root.querySelectorAll('.pth-sc-panel');\r\n      for (i = 0; i < panels.length; i++) { panels[i].className = 'pth-sc-panel' + (panels[i].getAttribute('data-panel') === name ? ' active' : ''); }\r\n      this.currentTab = name;\r\n    },\r\n\r\n    val: function (id) { var e = document.getElementById(id); return e ? e.value : ''; },\r\n    chk: function (id) { var e = document.getElementById(id); return e ? e.checked : false; },\r\n    setOut: function (id, v) { var e = document.getElementById(id); if (e) { e.value = v; } },\r\n\r\n    delim: function () { var d = this.val('sc-delim'); return d === '\\\\t' ? '\\t' : d; },\r\n\r\n    \/* ---------- CSV parser (RFC 4180-ish) ---------- *\/\r\n    parseCSV: function (text, delim) {\r\n      var rows = [], row = [], field = '', i = 0, inq = false, c, n;\r\n      text = text.replace(\/\\r\\n\/g, '\\n').replace(\/\\r\/g, '\\n');\r\n      while (i < text.length) {\r\n        c = text.charAt(i);\r\n        if (inq) {\r\n          if (c === '\"') {\r\n            n = text.charAt(i + 1);\r\n            if (n === '\"') { field += '\"'; i += 2; continue; }\r\n            inq = false; i++; continue;\r\n          }\r\n          field += c; i++; continue;\r\n        }\r\n        if (c === '\"') { inq = true; i++; continue; }\r\n        if (c === delim) { row.push(field); field = ''; i++; continue; }\r\n        if (c === '\\n') { row.push(field); rows.push(row); row = []; field = ''; i++; continue; }\r\n        field += c; i++;\r\n      }\r\n      row.push(field); rows.push(row);\r\n      \/* drop a trailing empty row *\/\r\n      if (rows.length && rows[rows.length - 1].length === 1 && rows[rows.length - 1][0] === '') { rows.pop(); }\r\n      return rows;\r\n    },\r\n\r\n    getData: function (inId, headerId) {\r\n      var raw = this.val(inId);\r\n      if (!raw || !raw.replace(\/\\s\/g, '')) { return null; }\r\n      var rows = this.parseCSV(raw, this.delim());\r\n      if (!rows.length) { return null; }\r\n      var headers, dataRows;\r\n      if (this.chk(headerId)) { headers = rows[0]; dataRows = rows.slice(1); }\r\n      else { headers = []; for (var k = 0; k < rows[0].length; k++) { headers.push('column' + (k + 1)); } dataRows = rows; }\r\n      if (this.chk('sc-trim') && inId === 'sc-c2s-in') {\r\n        headers = this.trimArr(headers);\r\n        for (var r = 0; r < dataRows.length; r++) { dataRows[r] = this.trimArr(dataRows[r]); }\r\n      }\r\n      return { headers: headers, rows: dataRows };\r\n    },\r\n\r\n    trimArr: function (a) { var o = [], i; for (i = 0; i < a.length; i++) { o.push((a[i] || '').replace(\/^\\s+|\\s+$\/g, '')); } return o; },\r\n\r\n    \/* ---------- type inference ---------- *\/\r\n    inferColumn: function (values) {\r\n      var nonEmpty = [], i, nullable = false;\r\n      for (i = 0; i < values.length; i++) { if (values[i] === '' || values[i] === null || values[i] === undefined) { nullable = true; } else { nonEmpty.push(String(values[i])); } }\r\n      var maxLen = 1;\r\n      for (i = 0; i < nonEmpty.length; i++) { if (nonEmpty[i].length > maxLen) { maxLen = nonEmpty[i].length; } }\r\n      if (!nonEmpty.length) { return { type: 'text', len: maxLen, nullable: true }; }\r\n      var allInt = true, allNum = true, allDate = true, allDT = true, hasBoolWord = false, allBool = true, big = false;\r\n      var intRe = \/^-?\\d+$\/, numRe = \/^-?\\d+(\\.\\d+)?$\/, dateRe = \/^\\d{4}-\\d{2}-\\d{2}$\/, dtRe = \/^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}(:\\d{2})?$\/;\r\n      for (i = 0; i < nonEmpty.length; i++) {\r\n        var v = nonEmpty[i], lv = v.toLowerCase();\r\n        if (!intRe.test(v)) { allInt = false; } else if (Math.abs(parseFloat(v)) > 2147483647) { big = true; }\r\n        if (!numRe.test(v)) { allNum = false; }\r\n        if (!dateRe.test(v)) { allDate = false; }\r\n        if (!dtRe.test(v)) { allDT = false; }\r\n        if (lv === 'true' || lv === 'false' || lv === 'yes' || lv === 'no') { hasBoolWord = true; }\r\n        else if (v !== '0' && v !== '1') { allBool = false; }\r\n      }\r\n      if (allBool && hasBoolWord) { return { type: 'bool', len: maxLen, nullable: nullable }; }\r\n      if (allInt) { return { type: big ? 'bigint' : 'int', len: maxLen, nullable: nullable }; }\r\n      if (allNum) { return { type: 'decimal', len: maxLen, nullable: nullable }; }\r\n      if (allDate) { return { type: 'date', len: maxLen, nullable: nullable }; }\r\n      if (allDT) { return { type: 'datetime', len: maxLen, nullable: nullable }; }\r\n      return { type: 'text', len: maxLen, nullable: nullable };\r\n    },\r\n\r\n    inferAll: function (headers, rows) {\r\n      var cols = [], c;\r\n      for (c = 0; c < headers.length; c++) {\r\n        var vals = [], r;\r\n        for (r = 0; r < rows.length; r++) { vals.push(rows[r][c] === undefined ? '' : rows[r][c]); }\r\n        var info = this.inferColumn(vals);\r\n        cols.push(info);\r\n      }\r\n      return cols;\r\n    },\r\n\r\n    ident: function (name, d) { return d.open + String(name).replace(\/[\"\\x60\\]]\/g, '') + d.close; },\r\n\r\n    sqlType: function (info, d) {\r\n      if (info.type === 'text') {\r\n        if (d === DIALECTS.sqlite) { return 'TEXT'; }\r\n        var len = Math.max(1, Math.min(4000, Math.ceil(info.len * 1.3)));\r\n        return d.t.text + '(' + len + ')';\r\n      }\r\n      return d.t[info.type];\r\n    },\r\n\r\n    lit: function (raw, info, d) {\r\n      if (raw === '' || raw === null || raw === undefined) { return this.chk('sc-null') ? 'NULL' : \"''\"; }\r\n      var s = String(raw);\r\n      if (this.chk('sc-types')) {\r\n        if (info.type === 'int' || info.type === 'bigint' || info.type === 'decimal') { return s; }\r\n        if (info.type === 'bool') {\r\n          var lv = s.toLowerCase(); var truthy = (lv === 'true' || lv === 'yes' || lv === '1');\r\n          return d.boolLit(truthy);\r\n        }\r\n      }\r\n      return \"'\" + s.replace(\/'\/g, \"''\") + \"'\";\r\n    },\r\n\r\n    csvToSql: function () {\r\n      var data = this.getData('sc-c2s-in', 'sc-header');\r\n      if (!data) { this.toast('Paste some CSV first.', 'error'); return; }\r\n      var d = DIALECTS[this.val('sc-dialect')] || DIALECTS.mysql;\r\n      var table = (this.val('sc-table') || 'my_table').replace(\/[^A-Za-z0-9_]\/g, '') || 'my_table';\r\n      var stmt = this.val('sc-stmt');\r\n      var infos = this.chk('sc-types') ? this.inferAll(data.headers, data.rows) : this.plainInfos(data.headers.length);\r\n      this.lastTypes = infos;\r\n      this.showTypeInfo(data.headers, infos);\r\n      this.populateKeyPk(data.headers);\r\n\r\n      var out = '';\r\n      if (stmt === 'create' || stmt === 'createinsert') { out += this.genCreate(table, data.headers, infos, d) + '\\n\\n'; }\r\n      if (stmt === 'insert' || stmt === 'createinsert') { out += this.genInsert(table, data.headers, data.rows, infos, d); }\r\n      else if (stmt === 'update') { out += this.genUpdate(table, data.headers, data.rows, infos, d); }\r\n      else if (stmt === 'delete') { out += this.genDelete(table, data.headers, data.rows, infos, d); }\r\n      else if (stmt === 'upsert') { out += this.genUpsert(table, data.headers, data.rows, infos, d); }\r\n      this.setOut('sc-c2s-out', out.replace(\/\\s+$\/, ''));\r\n      this.toast('Generated ' + data.rows.length + ' row(s) of SQL.', 'success');\r\n    },\r\n\r\n    plainInfos: function (n) { var a = [], i; for (i = 0; i < n; i++) { a.push({ type: 'text', len: 255, nullable: true }); } return a; },\r\n\r\n    genCreate: function (table, headers, infos, d) {\r\n      var pk = this.val('sc-pk');\r\n      var lines = [], i;\r\n      for (i = 0; i < headers.length; i++) {\r\n        var line = '  ' + this.ident(headers[i], d) + ' ' + this.sqlType(infos[i], d);\r\n        if (!infos[i].nullable) { line += ' NOT NULL'; }\r\n        if (pk && headers[i] === pk) { line += ' PRIMARY KEY'; }\r\n        lines.push(line);\r\n      }\r\n      return 'CREATE TABLE ' + this.ident(table, d) + ' (\\n' + lines.join(',\\n') + '\\n);';\r\n    },\r\n\r\n    colList: function (headers, d) { var a = [], i; for (i = 0; i < headers.length; i++) { a.push(this.ident(headers[i], d)); } return a.join(', '); },\r\n\r\n    rowVals: function (row, infos, d) {\r\n      var a = [], i;\r\n      for (i = 0; i < infos.length; i++) { a.push(this.lit(row[i] === undefined ? '' : row[i], infos[i], d)); }\r\n      return '(' + a.join(', ') + ')';\r\n    },\r\n\r\n    genInsert: function (table, headers, rows, infos, d) {\r\n      if (!rows.length) { return ''; }\r\n      var head = 'INSERT INTO ' + this.ident(table, d) + ' (' + this.colList(headers, d) + ') VALUES';\r\n      var i, tuples = [];\r\n      for (i = 0; i < rows.length; i++) { tuples.push(this.rowVals(rows[i], infos, d)); }\r\n      if (this.chk('sc-batch')) { return head + '\\n' + tuples.join(',\\n') + ';'; }\r\n      var out = [];\r\n      for (i = 0; i < tuples.length; i++) { out.push(head + ' ' + tuples[i] + ';'); }\r\n      return out.join('\\n');\r\n    },\r\n\r\n    genUpdate: function (table, headers, rows, infos, d) {\r\n      var key = this.val('sc-key') || headers[0];\r\n      var ki = this.indexOf(headers, key);\r\n      var out = [], i, c;\r\n      for (i = 0; i < rows.length; i++) {\r\n        var sets = [];\r\n        for (c = 0; c < headers.length; c++) { if (headers[c] === key) { continue; } sets.push(this.ident(headers[c], d) + ' = ' + this.lit(rows[i][c], infos[c], d)); }\r\n        out.push('UPDATE ' + this.ident(table, d) + ' SET ' + sets.join(', ') + ' WHERE ' + this.ident(key, d) + ' = ' + this.lit(rows[i][ki], infos[ki], d) + ';');\r\n      }\r\n      return out.join('\\n');\r\n    },\r\n\r\n    genDelete: function (table, headers, rows, infos, d) {\r\n      var key = this.val('sc-key') || headers[0];\r\n      var ki = this.indexOf(headers, key);\r\n      var out = [], i;\r\n      for (i = 0; i < rows.length; i++) { out.push('DELETE FROM ' + this.ident(table, d) + ' WHERE ' + this.ident(key, d) + ' = ' + this.lit(rows[i][ki], infos[ki], d) + ';'); }\r\n      return out.join('\\n');\r\n    },\r\n\r\n    genUpsert: function (table, headers, rows, infos, d) {\r\n      var dialect = this.val('sc-dialect');\r\n      var key = this.val('sc-key') || headers[0];\r\n      var cols = this.colList(headers, d);\r\n      var i, out = [];\r\n      if (dialect === 'mysql') {\r\n        var head = 'INSERT INTO ' + this.ident(table, d) + ' (' + cols + ') VALUES';\r\n        var tuples = [], sets = [], c;\r\n        for (i = 0; i < rows.length; i++) { tuples.push(this.rowVals(rows[i], infos, d)); }\r\n        for (c = 0; c < headers.length; c++) { if (headers[c] === key) { continue; } sets.push(this.ident(headers[c], d) + ' = VALUES(' + this.ident(headers[c], d) + ')'); }\r\n        return head + '\\n' + tuples.join(',\\n') + '\\nON DUPLICATE KEY UPDATE ' + sets.join(', ') + ';';\r\n      }\r\n      if (dialect === 'postgres' || dialect === 'sqlite') {\r\n        var head2 = 'INSERT INTO ' + this.ident(table, d) + ' (' + cols + ') VALUES';\r\n        var tuples2 = [], sets2 = [], c2;\r\n        for (i = 0; i < rows.length; i++) { tuples2.push(this.rowVals(rows[i], infos, d)); }\r\n        for (c2 = 0; c2 < headers.length; c2++) { if (headers[c2] === key) { continue; } sets2.push(this.ident(headers[c2], d) + ' = EXCLUDED.' + this.ident(headers[c2], d)); }\r\n        return head2 + '\\n' + tuples2.join(',\\n') + '\\nON CONFLICT (' + this.ident(key, d) + ') DO UPDATE SET ' + sets2.join(', ') + ';';\r\n      }\r\n      \/* mssql \/ oracle \/ standard -> MERGE per row *\/\r\n      var ki = this.indexOf(headers, key), c3;\r\n      for (i = 0; i < rows.length; i++) {\r\n        var srcVals = [], onMatch = [], insCols = [], insVals = [];\r\n        for (c3 = 0; c3 < headers.length; c3++) {\r\n          var lit = this.lit(rows[i][c3], infos[c3], d);\r\n          srcVals.push(lit + ' AS ' + this.ident(headers[c3], d));\r\n          insCols.push(this.ident(headers[c3], d));\r\n          insVals.push('src.' + this.ident(headers[c3], d));\r\n          if (headers[c3] !== key) { onMatch.push('tgt.' + this.ident(headers[c3], d) + ' = src.' + this.ident(headers[c3], d)); }\r\n        }\r\n        out.push('MERGE INTO ' + this.ident(table, d) + ' tgt USING (SELECT ' + srcVals.join(', ') + (this.val('sc-dialect') === 'oracle' ? ' FROM dual' : '') + ') src ON (tgt.' + this.ident(key, d) + ' = src.' + this.ident(key, d) + ')\\nWHEN MATCHED THEN UPDATE SET ' + onMatch.join(', ') + '\\nWHEN NOT MATCHED THEN INSERT (' + insCols.join(', ') + ') VALUES (' + insVals.join(', ') + ');');\r\n      }\r\n      return out.join('\\n');\r\n    },\r\n\r\n    indexOf: function (arr, v) { for (var i = 0; i < arr.length; i++) { if (arr[i] === v) { return i; } } return 0; },\r\n\r\n    populateKeyPk: function (headers) {\r\n      var key = document.getElementById('sc-key'), pk = document.getElementById('sc-pk'), i;\r\n      if (key) { var kv = key.value; key.innerHTML = ''; for (i = 0; i < headers.length; i++) { var o = document.createElement('option'); o.value = headers[i]; o.textContent = headers[i]; key.appendChild(o); } if (kv) { key.value = kv; } }\r\n      if (pk) { var pv = pk.value; pk.innerHTML = ''; var none = document.createElement('option'); none.value = ''; none.textContent = '(none)'; pk.appendChild(none); for (i = 0; i < headers.length; i++) { var o2 = document.createElement('option'); o2.value = headers[i]; o2.textContent = headers[i]; pk.appendChild(o2); } if (pv) { pk.value = pv; } }\r\n    },\r\n\r\n    syncStmtOptions: function () {\r\n      var stmt = this.val('sc-stmt');\r\n      var keyWrap = document.getElementById('sc-key-wrap'), pkWrap = document.getElementById('sc-pk-wrap');\r\n      var needKey = (stmt === 'update' || stmt === 'delete' || stmt === 'upsert');\r\n      var needPk = (stmt === 'create' || stmt === 'createinsert');\r\n      if (keyWrap) { keyWrap.className = 'pth-sc-fg' + (needKey ? '' : ' pth-sc-hidden'); }\r\n      if (pkWrap) { pkWrap.className = 'pth-sc-fg' + (needPk ? '' : ' pth-sc-hidden'); }\r\n    },\r\n\r\n    showTypeInfo: function (headers, infos) {\r\n      var el = document.getElementById('sc-typeinfo');\r\n      if (!el) { return; }\r\n      if (!this.chk('sc-types')) { el.textContent = ''; return; }\r\n      var parts = [], i;\r\n      for (i = 0; i < headers.length; i++) { parts.push(headers[i] + ': ' + infos[i].type + (infos[i].nullable ? ' (null)' : '')); }\r\n      el.innerHTML = LT + 'b' + GT + 'Detected:' + LT + '\/b' + GT + ' ' + this.esc(parts.join('  |  '));\r\n    },\r\n\r\n    \/* ---------- SQL -> CSV ---------- *\/\r\n    sqlToCsv: function () {\r\n      var sql = this.val('sc-s2c-in');\r\n      if (!sql || !sql.replace(\/\\s\/g, '')) { this.toast('Paste some INSERT statements first.', 'error'); return; }\r\n      var cols = null, rows = [];\r\n      var colM = sql.match(\/INSERT\\s+INTO\\s+[\\x60\"\\[]?[\\w.]+[\\x60\"\\]]?\\s*\\(([^)]*)\\)\/i);\r\n      if (colM) { cols = this.splitTop(colM[1]).map(this.cleanIdent); }\r\n      var vidx = sql.search(\/\\bVALUES\\b\/i);\r\n      var body = vidx > -1 ? sql.slice(vidx + 6) : sql;\r\n      var tuples = this.extractTuples(body);\r\n      for (var i = 0; i < tuples.length; i++) { rows.push(this.splitTop(tuples[i]).map(this.cleanValue)); }\r\n      if (!rows.length) { this.toast('No VALUES rows found. Paste standard INSERT ... VALUES (...) statements.', 'error'); return; }\r\n      var delim = this.delim();\r\n      var out = [];\r\n      if (cols) { out.push(this.csvLine(cols, delim)); }\r\n      for (i = 0; i < rows.length; i++) { out.push(this.csvLine(rows[i], delim)); }\r\n      this.setOut('sc-s2c-out', out.join('\\n'));\r\n      this.toast('Extracted ' + rows.length + ' row(s).', 'success');\r\n    },\r\n\r\n    extractTuples: function (text) {\r\n      var tuples = [], depth = 0, cur = '', inq = false, i, c;\r\n      for (i = 0; i < text.length; i++) {\r\n        c = text.charAt(i);\r\n        if (inq) { cur += c; if (c === \"'\") { if (text.charAt(i + 1) === \"'\") { cur += \"'\"; i++; } else { inq = false; } } continue; }\r\n        if (c === \"'\") { inq = true; cur += c; continue; }\r\n        if (c === '(') { depth++; if (depth === 1) { cur = ''; continue; } }\r\n        if (c === ')') { depth--; if (depth === 0) { tuples.push(cur); cur = ''; continue; } }\r\n        if (depth >= 1) { cur += c; }\r\n      }\r\n      return tuples;\r\n    },\r\n\r\n    splitTop: function (text) {\r\n      var parts = [], cur = '', inq = false, depth = 0, i, c;\r\n      for (i = 0; i < text.length; i++) {\r\n        c = text.charAt(i);\r\n        if (inq) { cur += c; if (c === \"'\") { if (text.charAt(i + 1) === \"'\") { cur += \"'\"; i++; } else { inq = false; } } continue; }\r\n        if (c === \"'\") { inq = true; cur += c; continue; }\r\n        if (c === '(') { depth++; cur += c; continue; }\r\n        if (c === ')') { depth--; cur += c; continue; }\r\n        if (c === ',' && depth === 0) { parts.push(cur); cur = ''; continue; }\r\n        cur += c;\r\n      }\r\n      parts.push(cur);\r\n      return parts;\r\n    },\r\n\r\n    cleanIdent: function (s) { return s.replace(\/^\\s+|\\s+$\/g, '').replace(\/^[\\x60\"\\[]|[\\x60\"\\]]$\/g, ''); },\r\n\r\n    cleanValue: function (s) {\r\n      s = s.replace(\/^\\s+|\\s+$\/g, '');\r\n      if (\/^NULL$\/i.test(s)) { return ''; }\r\n      if (s.charAt(0) === \"'\" && s.charAt(s.length - 1) === \"'\") { return s.slice(1, -1).replace(\/''\/g, \"'\"); }\r\n      return s;\r\n    },\r\n\r\n    csvLine: function (arr, delim) {\r\n      var out = [], i;\r\n      for (i = 0; i < arr.length; i++) {\r\n        var v = arr[i] === null || arr[i] === undefined ? '' : String(arr[i]);\r\n        if (v.indexOf(delim) > -1 || v.indexOf('\"') > -1 || v.indexOf('\\n') > -1) { v = '\"' + v.replace(\/\"\/g, '\"\"') + '\"'; }\r\n        out.push(v);\r\n      }\r\n      return out.join(delim);\r\n    },\r\n\r\n    \/* ---------- CSV -> Table ---------- *\/\r\n    csvToTable: function () {\r\n      var raw = this.val('sc-tbl-in');\r\n      if (!raw || !raw.replace(\/\\s\/g, '')) { this.toast('Paste some CSV first.', 'error'); return; }\r\n      var rows = this.parseCSV(raw, this.delim());\r\n      if (!rows.length) { this.toast('No rows found.', 'error'); return; }\r\n      var header, body;\r\n      if (this.chk('sc-tbl-header')) { header = rows[0]; body = rows.slice(1); }\r\n      else { header = []; for (var k = 0; k < rows[0].length; k++) { header.push('Column ' + (k + 1)); } body = rows; }\r\n      var fmt = this.val('sc-tbl-fmt'), out;\r\n      if (fmt === 'html') { out = this.toHtmlTable(header, body); }\r\n      else { out = this.toMarkdown(header, body); }\r\n      this.setOut('sc-tbl-out', out);\r\n      this.toast('Table generated.', 'success');\r\n    },\r\n\r\n    toMarkdown: function (header, body) {\r\n      function cell(s) { return String(s === undefined ? '' : s).replace(\/\\|\/g, '\\\\|').replace(\/\\n\/g, ' '); }\r\n      var lines = [], i, r;\r\n      var hcells = []; for (i = 0; i < header.length; i++) { hcells.push(cell(header[i])); }\r\n      lines.push('| ' + hcells.join(' | ') + ' |');\r\n      var seps = []; for (i = 0; i < header.length; i++) { seps.push('---'); }\r\n      lines.push('| ' + seps.join(' | ') + ' |');\r\n      for (r = 0; r < body.length; r++) {\r\n        var cells = []; for (i = 0; i < header.length; i++) { cells.push(cell(body[r][i])); }\r\n        lines.push('| ' + cells.join(' | ') + ' |');\r\n      }\r\n      return lines.join('\\n');\r\n    },\r\n\r\n    toHtmlTable: function (header, body) {\r\n      var i, r;\r\n      var s = LT + 'table' + GT + '\\n' + LT + 'thead' + GT + LT + 'tr' + GT;\r\n      for (i = 0; i < header.length; i++) { s += LT + 'th' + GT + this.esc(header[i]) + LT + '\/th' + GT; }\r\n      s += LT + '\/tr' + GT + LT + '\/thead' + GT + '\\n' + LT + 'tbody' + GT + '\\n';\r\n      for (r = 0; r < body.length; r++) {\r\n        s += LT + 'tr' + GT;\r\n        for (i = 0; i < header.length; i++) { s += LT + 'td' + GT + this.esc(body[r][i] === undefined ? '' : body[r][i]) + LT + '\/td' + GT; }\r\n        s += LT + '\/tr' + GT + '\\n';\r\n      }\r\n      s += LT + '\/tbody' + GT + '\\n' + LT + '\/table' + GT;\r\n      return s;\r\n    },\r\n\r\n    esc: function (s) { return String(s === undefined || s === null ? '' : s).replace(\/&\/g, '&amp;').replace(new RegExp(LT, 'g'), '&lt;').replace(new RegExp(GT, 'g'), '&gt;'); },\r\n\r\n    \/* ---------- validate & preview ---------- *\/\r\n    validate: function () {\r\n      var raw = this.val('sc-prev-in');\r\n      var msg = document.getElementById('sc-prev-msg');\r\n      var wrap = document.getElementById('sc-prev-tblwrap');\r\n      wrap.className = 'pth-sc-preview pth-sc-hidden';\r\n      if (!raw || !raw.replace(\/\\s\/g, '')) { msg.className = 'pth-sc-msg bad'; msg.textContent = 'Paste some CSV to validate.'; return; }\r\n      var rows = this.parseCSV(raw, this.delim());\r\n      var header = this.chk('sc-prev-header') ? rows[0] : null;\r\n      var body = this.chk('sc-prev-header') ? rows.slice(1) : rows;\r\n      var expected = (header || rows[0]).length, issues = [], i;\r\n      for (i = 0; i < body.length; i++) {\r\n        if (body[i].length !== expected) { issues.push('Row ' + (i + 1) + ' has ' + body[i].length + ' fields (expected ' + expected + ')'); }\r\n      }\r\n      if (issues.length) { msg.className = 'pth-sc-msg bad'; msg.textContent = 'Found ' + issues.length + ' issue(s): ' + issues.slice(0, 5).join('; ') + (issues.length > 5 ? '...' : ''); }\r\n      else { msg.className = 'pth-sc-msg ok'; msg.textContent = 'Valid CSV: ' + body.length + ' row(s), ' + expected + ' column(s), all rows consistent.'; }\r\n      this.renderPreview(wrap, header, body.slice(0, 100));\r\n    },\r\n\r\n    renderPreview: function (wrap, header, body) {\r\n      wrap.innerHTML = '';\r\n      var table = document.createElement('table'); table.className = 'pth-sc-tbl';\r\n      if (header) {\r\n        var thead = document.createElement('thead'), htr = document.createElement('tr');\r\n        for (var i = 0; i < header.length; i++) { var th = document.createElement('th'); th.textContent = header[i]; htr.appendChild(th); }\r\n        thead.appendChild(htr); table.appendChild(thead);\r\n      }\r\n      var tbody = document.createElement('tbody');\r\n      for (var r = 0; r < body.length; r++) {\r\n        var tr = document.createElement('tr');\r\n        for (var c = 0; c < body[r].length; c++) { var td = document.createElement('td'); td.textContent = body[r][c]; tr.appendChild(td); }\r\n        tbody.appendChild(tr);\r\n      }\r\n      table.appendChild(tbody); wrap.appendChild(table);\r\n      wrap.className = 'pth-sc-preview';\r\n    },\r\n\r\n    \/* ---------- shared ---------- *\/\r\n    copy: function (id) {\r\n      var el = document.getElementById(id), self = this;\r\n      if (!el || !el.value) { this.toast('Nothing to copy.', 'error'); return; }\r\n      if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(el.value).then(function () { self.toast('Copied.', 'success'); })['catch'](function () { self.toast('Copy blocked.', 'error'); }); }\r\n      else { el.focus(); el.select(); this.toast('Press Ctrl+C to copy.', 'info'); }\r\n    },\r\n\r\n    download: function (id, name) {\r\n      var el = document.getElementById(id);\r\n      if (!el || !el.value) { this.toast('Nothing to download.', 'error'); return; }\r\n      var blob = new Blob([el.value], { type: 'text\/plain' }), url = URL.createObjectURL(blob);\r\n      var a = document.createElement('a'); a.href = url; a.download = name || 'output.txt';\r\n      document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n      setTimeout(function () { URL.revokeObjectURL(url); }, 1500);\r\n      this.toast('Downloaded.', 'success');\r\n    },\r\n\r\n    clearActive: function () {\r\n      var t = this.currentTab || 'c2s';\r\n      var map = { c2s: ['sc-c2s-in', 'sc-c2s-out'], s2c: ['sc-s2c-in', 'sc-s2c-out'], tbl: ['sc-tbl-in', 'sc-tbl-out'], prev: ['sc-prev-in'] };\r\n      var ids = map[t] || [];\r\n      for (var i = 0; i < ids.length; i++) { this.setOut(ids[i], ''); }\r\n      var tinfo = document.getElementById('sc-typeinfo'); if (tinfo) { tinfo.textContent = ''; }\r\n      var msg = document.getElementById('sc-prev-msg'); if (msg) { msg.className = 'pth-sc-msg'; }\r\n      var wrap = document.getElementById('sc-prev-tblwrap'); if (wrap) { wrap.className = 'pth-sc-preview pth-sc-hidden'; }\r\n      this.toast('Cleared.', 'info');\r\n    },\r\n\r\n    loadSample: function () {\r\n      var t = this.currentTab || 'c2s';\r\n      if (t === 's2c') {\r\n        this.setOut('sc-s2c-in', \"INSERT INTO products (id, name, price, in_stock) VALUES\\n(1, 'Wireless Keyboard', 29.99, 1),\\n(2, 'USB-C Hub, 6-port', 45.00, 0),\\n(3, 'Monitor Stand', 19.95, 1);\");\r\n      } else {\r\n        var csv = 'id,name,price,in_stock,added\\n1,Wireless Keyboard,29.99,true,2026-01-15\\n2,\"USB-C Hub, 6-port\",45.00,false,2026-02-03\\n3,Monitor Stand,19.95,true,2026-02-20';\r\n        if (t === 'tbl') { this.setOut('sc-tbl-in', csv); }\r\n        else if (t === 'prev') { this.setOut('sc-prev-in', csv); }\r\n        else { this.setOut('sc-c2s-in', csv); }\r\n      }\r\n      this.toast('Sample loaded.', 'info');\r\n    },\r\n\r\n    toast: function (msg, type) {\r\n      var t = document.getElementById('pth-sc-toast'); if (!t) { return; }\r\n      var colors = { success: '#059669', error: '#dc2626', info: '#4f46e5' };\r\n      t.style.background = colors[type] || colors.info; t.textContent = msg; t.className = 'pth-sc-toast show';\r\n      if (this._tt) { clearTimeout(this._tt); }\r\n      this._tt = setTimeout(function () { t.className = 'pth-sc-toast'; }, 3000);\r\n    }\r\n  };\r\n\r\n  window.pthSqlCsvApp = App;\r\n\r\n  function runInit() {\r\n    if (!window.pthSqlCsvApp.initialized && document.getElementById('pth-sqlcsv-wrap')) {\r\n      window.pthSqlCsvApp.initialized = true;\r\n      window.pthSqlCsvApp.init();\r\n    }\r\n  }\r\n  runInit();\r\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); }\r\n  window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n  if (!window.pthSqlCsvApp.initialized && typeof MutationObserver !== 'undefined') {\r\n    var obs = new MutationObserver(function () { if (document.getElementById('pth-sqlcsv-wrap')) { obs.disconnect(); runInit(); } });\r\n    obs.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { obs.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\n\n\n\n<style>\n.pth-container{max-width:1480px;margin:0 auto;padding:0 20px;box-sizing:border-box}\n.pth-feature-wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-bottom:40px}\n.pth-feat-box{border:1px solid #e2e8f0;background:#fff;padding:24px;border-radius:12px;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02)}\n.pth-feat-title{font-size:1.05rem;font-weight:800;color:#0f172a;margin:0 0 10px;display:flex;align-items:center;gap:10px}\n.pth-feat-text{font-size:.9rem;color:#1e293b;line-height:1.6;margin:0;font-weight:500}\n.pth-steps-wrap{border:1px solid #e2e8f0;background:#fff;padding:40px 30px;border-radius:16px;text-align:center;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);margin-bottom:40px;width:100%;box-sizing:border-box}\n.pth-steps-title{font-size:1.2rem;font-weight:800;color:#0f172a;text-transform:uppercase;margin:0 0 35px;letter-spacing:1px}\n.pth-steps-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:30px}\n.pth-step-item{display:flex;flex-direction:column;align-items:center}\n.pth-step-num{width:45px;height:45px;background:#4f46e5;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.2rem;margin-bottom:15px;box-shadow:0 4px 10px rgba(79,70,229,.3)}\n.pth-step-name{font-weight:800;color:#0f172a;margin:0 0 8px;font-size:1rem}\n.pth-step-desc{font-size:.9rem;color:#1e293b;line-height:1.5;margin:0;font-weight:500}\n<\/style>\n<div class=\"pth-container\">\n  <div class=\"pth-feature-wrap\">\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#128451;&#65039;<\/span> 6 Dialects, 6 Statements<\/p>\n      <p class=\"pth-feat-text\">Generate INSERT, CREATE TABLE, UPDATE, DELETE, and UPSERT for MySQL, PostgreSQL, SQL Server, SQLite, Oracle, or Standard SQL &mdash; each with the right identifier quoting and syntax for that database.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#129504;<\/span> Smart Type Inference<\/p>\n      <p class=\"pth-feat-text\">It reads each column and picks a sensible type &mdash; integer, decimal, date, boolean, or a sized VARCHAR &mdash; and flags which columns can be null, so your CREATE TABLE is ready to run, not just a wall of text fields.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#128260;<\/span> Two-Way &amp; Table Export<\/p>\n      <p class=\"pth-feat-text\">Go the other way and turn INSERT statements back into CSV, or export any CSV as a clean Markdown or HTML table. A preview tab validates your columns before you convert.<\/p>\n    <\/div>\n  <\/div>\n  <div class=\"pth-steps-wrap\">\n    <p class=\"pth-steps-title\">How to Use the CSV to SQL Converter<\/p>\n    <div class=\"pth-steps-grid\">\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">1<\/div>\n        <p class=\"pth-step-name\">Paste your CSV<\/p>\n        <p class=\"pth-step-desc\">Drop your spreadsheet data in, or press Sample to see the expected format.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">2<\/div>\n        <p class=\"pth-step-name\">Set the options<\/p>\n        <p class=\"pth-step-desc\">Pick your table name, dialect, and statement type, and toggle type inference or cleaning.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">3<\/div>\n        <p class=\"pth-step-name\">Convert<\/p>\n        <p class=\"pth-step-desc\">Press Convert to SQL and read the generated queries in the output panel.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">4<\/div>\n        <p class=\"pth-step-name\">Copy or download<\/p>\n        <p class=\"pth-step-desc\">Copy the SQL or download a .sql file, ready to run in your database.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Last updated: August 2026<\/p>\n\n\n\n<h2 id=\"\ud83d\udd34-what-it-converts-and-when-youd-reach-for-it\" class=\"wp-block-heading\">\ud83d\udd34&nbsp;<strong>What it converts, and when you&#8217;d reach for it<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Getting data out of a spreadsheet and into a database is a chore every developer meets sooner or later. You export a CSV, and now you need it as rows in a table. This csv to sql converter does that in one step: paste the CSV, and it writes the INSERT statements, or a full CREATE TABLE, for the database you actually use. It runs entirely in your browser, so a customer list or a private dataset never gets uploaded to a server to be processed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">People reach for it to seed a new table from sample data, migrate a small dataset between systems, generate test fixtures, or turn a client&#8217;s spreadsheet into a real schema. Because it handles six dialects, the output is not generic SQL you have to hand-fix \u2014 it matches MySQL, PostgreSQL, SQL Server, SQLite, Oracle, or the Standard.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe1-from-spreadsheet-to-database-in-a-few-clicks\" class=\"wp-block-heading\">\ud83d\udfe1&nbsp;<strong>From spreadsheet to database in a few clicks<\/strong><\/h2>\n\n\n<figure class=\"pth-article-figure pth-img-left\" style=\"float:left; width:700px; max-width:100%; margin:4px 28px 16px 0; clear:left;\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/08\/CSV_grid_converting_to_SQL-800x447.jpeg\" alt=\"CSV_grid_converting_to_SQL\" width=\"700\" height=\"394\" loading=\"lazy\" data-no-lazy=\"1\" class=\"pth-article-img\" style=\"width:100%;height:auto;display:block;border-radius:10px;border:1px solid #e2e8f0;\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Start by pasting your CSV and choosing whether the first row is a header. Pick a table name and a dialect, then choose what you want: plain INSERTs, a CREATE TABLE, both together, or an UPDATE, DELETE, or UPSERT keyed on a column you select. The cleaning toggles trim stray spaces, turn empty cells into proper NULLs, and pack rows into a single multi-row INSERT for speed. The converter reads quoted fields correctly, so a value like a product name with a comma in it stays in one column instead of splitting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tool works both directions. Paste existing INSERT statements into the SQL-to-CSV tab and it pulls the rows back out as CSV. If what you actually want is a formatted table for documentation or a README, the CSV-to-Table tab produces a Markdown or HTML table instead. For converting the same data to or from JSON, that job belongs to&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/free-jsonpath-evaluator-extractor\/\">JSON Studio Pro<\/a>, and for cleaning messy source text first, the&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/advanced-text-regex-tester-debugger\/\">regex tester<\/a>&nbsp;is handy.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe2-getting-the-data-types-and-dialect-right\" class=\"wp-block-heading\">\ud83d\udfe2&nbsp;<strong>Getting the data types and dialect right<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The part that saves the most time is type inference. With it on, the tool scans each column and chooses a type: a column of whole numbers becomes an integer, one with decimals becomes a numeric type, dates and true\/false columns are detected, and everything else becomes a VARCHAR sized to the longest value. It also marks a column nullable if any cell is empty. You can switch inference off to treat every value as text when you would rather be safe, and you can name a primary key so the CREATE TABLE is complete. Databases vary in how strictly they enforce these types \u2014 SQLite, for one, is famously flexible, as its&nbsp;<a href=\"https:\/\/www.sqlite.org\/datatype3.html\" target=\"_blank\" rel=\"noreferrer noopener\">datatype documentation<\/a>&nbsp;explains.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One safety note worth understanding: the converter escapes single quotes in your values so the SQL stays valid, but generated INSERTs are meant for trusted data you are loading yourself, not for building queries from untrusted user input \u2014 for that you always use parameterised queries. Keeping this kind of work on your own machine is the same privacy logic covered in&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/securing-api-keys-client-side-data-processing\/\">this guide on client-side data processing<\/a>. If you want the full picture of how the conversion works under the hood, the companion article on&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/how-to-convert-csv-to-sql\/\">how to convert CSV to SQL<\/a>&nbsp;walks through it.<\/p>\n\n\n\n<style>\n.pth-faq-wrap{max-width:1480px;margin:0 auto;padding:0 20px;box-sizing:border-box}\n.pth-faq-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}\n.pth-faq-card{border:1px solid #e2e8f0;background:#fff;border-radius:12px;padding:18px}\n.pth-faq-q{font-weight:800;color:#0f172a;margin:0 0 8px;font-size:1rem}\n.pth-faq-a{color:#1e293b;font-weight:500;line-height:1.6;margin:0;font-size:.92rem}\n@media(max-width:1024px){.pth-faq-grid{grid-template-columns:repeat(2,1fr)}}\n@media(max-width:640px){.pth-faq-grid{grid-template-columns:1fr}}\n<\/style>\n<div class=\"pth-faq-wrap\">\n  <div class=\"pth-faq-grid\">\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Is it free, offline, and private?<\/p>\n      <p class=\"pth-faq-a\">Yes. The conversion runs in your browser, so your data never leaves your device. There is no account, no upload, and it keeps working without a connection after the page loads.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Which SQL dialects are supported?<\/p>\n      <p class=\"pth-faq-a\">Standard SQL, MySQL, PostgreSQL, SQL Server, SQLite, and Oracle. Each gets the correct identifier quoting and data types, so the output runs without hand-editing.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What statement types can it generate?<\/p>\n      <p class=\"pth-faq-a\">INSERT, CREATE TABLE, both together, UPDATE, DELETE, and UPSERT. For UPDATE, DELETE, and UPSERT you pick the key column the statements match on.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What does type inference do, and can I turn it off?<\/p>\n      <p class=\"pth-faq-a\">It reads each column and picks a suitable SQL type instead of making everything text. You can switch it off to treat every value as a string when you prefer full control.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Does it handle commas inside quoted fields?<\/p>\n      <p class=\"pth-faq-a\">Yes. It follows standard CSV quoting rules, so a quoted value containing a comma or a line break stays in a single column rather than splitting incorrectly.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can it convert SQL back to CSV?<\/p>\n      <p class=\"pth-faq-a\">Yes. The SQL-to-CSV tab parses INSERT statements and pulls the rows back out as CSV, quoting any values that contain the delimiter.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can I get a Markdown or HTML table instead?<\/p>\n      <p class=\"pth-faq-a\">Yes. The CSV-to-Table tab turns your data into a Markdown table for docs or an HTML table for a web page, ready to copy or download.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Is the generated SQL safe from injection?<\/p>\n      <p class=\"pth-faq-a\">It escapes quotes so your own data loads cleanly. For queries built from untrusted user input, always use parameterised statements rather than generated string SQL.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Does it work on large files or a phone?<\/p>\n      <p class=\"pth-faq-a\">It handles typical datasets comfortably and stacks into a single column on phones. Very large files are better split, since everything is processed in memory.<\/p>\n    <\/div>\n  <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Offline CSV to SQL Converter | Instant Database Scripts, Completely Private &amp; Free Convert CSV data to SQL INSERT queries instantly with our 100% offline, secure CSV to SQL Query Converter. Generate CREATE TABLE scripts locally in your browser. \u00a0 &#128451;&#65039; 6 Dialects, 6 Statements Generate INSERT, CREATE TABLE, UPDATE, DELETE, and UPSERT for MySQL, &#8230; <a title=\"Free CSV to SQL Query Converter | 100% Offline Generator\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/csv-to-sql-query-converter\/\" aria-label=\"Read more about Free CSV to SQL Query Converter | 100% Offline Generator\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":4628,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4627","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/comments?post=4627"}],"version-history":[{"count":3,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4627\/revisions"}],"predecessor-version":[{"id":7038,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4627\/revisions\/7038"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/4628"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=4627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}