CSV para SQL
Gere comandos SQL INSERT a partir de dados CSV
Entrada CSV
Saída SQL
O que é a Conversão de CSV para SQL?
A conversão de CSV para SQL transforma valores separados por vírgula em comandos Structured Query Language que um banco de dados relacional pode executar. O resultado mais comum é um par: um comando CREATE TABLE que define as colunas, e um ou mais comandos INSERT INTO que populam essas colunas com as linhas do arquivo CSV.
Arquivos CSV seguem a especificação RFC 4180. Cada linha é um registro, os campos são separados por um delimitador (geralmente uma vírgula), e campos que contêm o delimitador ou quebras de linha são envolvidos por aspas duplas. SQL, por sua vez, é a linguagem padrão para gerenciar dados em sistemas como PostgreSQL, MySQL, SQLite e SQL Server. A conversão entre esses dois formatos é uma das tarefas de importação de dados mais frequentes no desenvolvimento de software.
Um conversor de CSV para SQL adequado trata as aspas, escapa aspas simples dentro dos valores (duplicando-as para '' conforme o padrão SQL), mapeia os cabeçalhos das colunas para identificadores SQL válidos e pode opcionalmente inferir tipos de dados. Além do escape básico, um bom conversor normaliza os nomes dos cabeçalhos (substituindo espaços e hífens por underscores) e envolve o resultado em um bloco de transação, para que uma falha na importação desfaça tudo de forma limpa em vez de deixar dados parciais na tabela. Sem um conversor, escrever manualmente comandos INSERT para algumas centenas de linhas é lento e sujeito a erros.
Por que usar um Conversor de CSV para SQL?
Escrever comandos SQL INSERT à mão a partir de dados de planilha é tedioso e propenso a erros de sintaxe. Um conversor automatiza as partes repetitivas para que você possa se concentrar no design do esquema e na validação dos dados.
Casos de Uso do CSV para SQL
Referência de Tipos de Dados SQL
Ao converter CSV para SQL, cada coluna é definida como TEXT por padrão porque o CSV não possui metadados de tipo. Se você souber os tipos das colunas, pode substituir TEXT no resultado do CREATE TABLE. Esta tabela mostra os tipos SQL mais comuns e quando usar cada um.
| Tipo | Usado Para | Observações |
|---|---|---|
| TEXT / VARCHAR | Strings, mixed content | Default safe choice; works in every SQL dialect |
| INTEGER / INT | Whole numbers (age, count, ID) | Use when column contains only digits with no decimals |
| REAL / FLOAT | Decimal numbers (price, rate) | Needed for columns with dots like 19.99 or 3.14 |
| DATE | ISO 8601 dates (2024-01-15) | Requires consistent formatting; varies by database |
| BOOLEAN | true/false, 1/0, yes/no | MySQL uses TINYINT(1); PostgreSQL has native BOOL |
| NUMERIC / DECIMAL | Exact precision (currency) | Specify scale: DECIMAL(10,2) for money columns |
| BLOB / BYTEA | Binary data | Rarely needed in CSV imports; use for hex-encoded fields |
Comparação de Dialetos SQL
A sintaxe SQL varia entre os mecanismos de banco de dados. Os comandos INSERT gerados usam SQL padrão que funciona na maioria dos sistemas, mas certos recursos diferem. Esta tabela resume as diferenças mais relevantes ao importar dados CSV.
| Recurso | PostgreSQL | MySQL | SQLite | SQL Server |
|---|---|---|---|---|
| Identifier quoting | "col" | `col` | "col" | [col] |
| String escape | '' | '' or \' | '' | '' |
| INSERT syntax | INSERT INTO | INSERT INTO | INSERT INTO | INSERT INTO |
| Batch INSERT | VALUES (),()… | VALUES (),()… | VALUES (),()… | max 1000 rows |
| Auto-increment | SERIAL | AUTO_INCREMENT | AUTOINCREMENT | IDENTITY(1,1) |
| Upsert / merge | ON CONFLICT | ON DUPLICATE KEY | ON CONFLICT | MERGE |
| NULL handling | IS NULL | IS NULL / <=> | IS NULL | IS NULL |
| COPY from CSV | COPY … FROM | LOAD DATA INFILE | .import | BULK INSERT |
INSERT vs COPY: Escolhendo um Método de Importação
Para conjuntos de dados pequenos a médios (menos de 10.000 linhas), os comandos INSERT funcionam bem e são portáveis em qualquer banco de dados SQL. Para importações grandes, os bancos de dados fornecem comandos de carregamento em massa que ignoram completamente o parser SQL.
Exemplos de Código
Estes exemplos mostram como converter CSV em comandos SQL INSERT em diferentes linguagens. Cada um trata o escape de aspas simples e a sanitização dos nomes das colunas.
// CSV → SQL INSERT statements
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`
function csvToSql(csv, table = 'data') {
const rows = csv.trim().split('\n').map(r => r.split(','))
const [headers, ...data] = rows
const cols = headers.map(h => h.trim().toLowerCase().replace(/\s+/g, '_'))
const values = data.map(row =>
' (' + row.map(v => `'${v.replace(/'/g, "''").trim()}'`).join(', ') + ')'
)
return `INSERT INTO ${table} (${cols.join(', ')}) VALUES
${values.join(',\n')};`
}
console.log(csvToSql(csv, 'users'))
// → INSERT INTO users (name, age, city) VALUES
// ('Alice', '30', 'Berlin'),
// ('Bob', '25', 'Tokyo');import csv
import io
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""
reader = csv.reader(io.StringIO(csv_string))
headers = [h.strip().lower().replace(' ', '_') for h in next(reader)]
table = 'users'
rows = list(reader)
# CREATE TABLE
col_defs = ', '.join(f'{h} TEXT' for h in headers)
print(f'CREATE TABLE {table} ({col_defs});')
# → CREATE TABLE users (name TEXT, age TEXT, city TEXT);
# INSERT statements
for row in rows:
vals = ', '.join(f"'{v.replace(chr(39), chr(39)*2)}'" for v in row)
print(f"INSERT INTO {table} ({', '.join(headers)}) VALUES ({vals});")
# → INSERT INTO users (name, age, city) VALUES ('Alice', '30', 'Berlin');
# → INSERT INTO users (name, age, city) VALUES ('Bob', '25', 'Tokyo');package main
import (
"encoding/csv"
"fmt"
"strings"
)
func csvToSQL(data, table string) string {
r := csv.NewReader(strings.NewReader(data))
records, _ := r.ReadAll()
if len(records) < 2 {
return ""
}
headers := records[0]
var vals []string
for _, row := range records[1:] {
escaped := make([]string, len(row))
for i, v := range row {
escaped[i] = "'" + strings.ReplaceAll(v, "'", "''") + "'"
}
vals = append(vals, " ("+strings.Join(escaped, ", ")+")")
}
return fmt.Sprintf("INSERT INTO %s (%s) VALUES\n%s;",
table, strings.Join(headers, ", "), strings.Join(vals, ",\n"))
}
func main() {
csv := "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo"
fmt.Println(csvToSQL(csv, "users"))
// → INSERT INTO users (name, age, city) VALUES
// ('Alice', '30', 'Berlin'),
// ('Bob', '25', 'Tokyo');
}# SQLite: import CSV directly into a table sqlite3 mydb.db <<EOF .mode csv .import data.csv users SELECT * FROM users LIMIT 5; EOF # PostgreSQL: COPY from CSV file (server-side) psql -c "COPY users FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true);" # PostgreSQL: \copy from CSV (client-side, no superuser needed) psql -c "\copy users FROM 'data.csv' WITH (FORMAT csv, HEADER true);" # MySQL: LOAD DATA from CSV mysql -e "LOAD DATA INFILE '/path/to/data.csv' INTO TABLE users FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;"