Postgresql 使用批处理文件将csv的第一行解析为sql表
我有一些csv文件,我需要打开csv文件,读取csv的第一行并将其转换为临时sql表,然后将数据加载到sql表中,如下所示: 阅读CSV的行,每行:Postgresql 使用批处理文件将csv的第一行解析为sql表,postgresql,csv,batch-file,Postgresql,Csv,Batch File,我有一些csv文件,我需要打开csv文件,读取csv的第一行并将其转换为临时sql表,然后将数据加载到sql表中,如下所示: 阅读CSV的行,每行: 将其拆分为字段创建一个临时sql表 将这些字段插入数据库表的一行中 我试过这样的东西 这个脚本现在分为4个部分,文件初始化;文件创建、处理和复制数据, 一切正常,除了在fil.sql上,我得到的输出是 CREATE TEMP TABLE temtab( f
将其拆分为字段创建一个临时sql表 将这些字段插入数据库表的一行中 我试过这样的东西 这个脚本现在分为4个部分,文件初始化;文件创建、处理和复制数据, 一切正常,除了在fil.sql上,我得到的输出是
CREATE TEMP TABLE temtab(
firstcolumn character varying (255),
secondcolumn character varying (255),
lastcolumn character varying (255),
);
\COPY temtab from bio.csv WITH DELIMITER ; csv HEADER
而我希望最后一列没有逗号
CREATE TEMP TABLE temtab (
firstcolumn character varying (255),
secondcolumn character varying (255),
lastcolumn character varying (255)
);
\COPY temtab from bio.csv WITH DELIMITER ; csv HEADER
@echo off
::setlocal enabledelayedexpansion
REM Assiging dir to current directory
SET dir=%CD%
REM Defining database name
SET dbname=****
REM Defining Host name
SET host=****
REM Defining user
SET user=****
REM Defining Port
SET port=****
REM SQL file where query is to be executed
SET sqfile=fil.sql
SET fi=bio.csv
call:fileinitialization
call:filecreation
call:proces
call:copydata
goto:eof
:fileinitialization
REM Assigning name of temporary table
SET tabnam=temtab
REM Setting delimiter to variable delim
SET delim=;
REM Declaring variable numfields to store index of variable names array
set numFields=0
echo para setted
set fi=bio.csv
SET tex=text
SET com=,
GOTO:EOF
:filecreation
REM Setting create temporary table command with table name tabnam
SET creat=CREATE TEMP TABLE %tabnam%
echo %creat%
GOTO:EOF
:proces
REM Executing loop for each file in current directory
echo %creat%>fil.sql
REM Read the lines of the CSV file
For /F "eol==" %%A in (bio.csv) Do ( set "line=%%A"
REM check if index of array is 0
if !numFields! equ 0 (
REM Fisrt line, Store in array name
for %%B in (!line: ^=!) do (
echo %%B character varying (255^),>>fil.sql
set /A numFields+=1
set name[!numFields!]=%%B
) ) )
GOTO:EOF
:copydata
echo \COPY %tabnam% from %fi% WITH DELIMITER %delim% csv HEADER
echo \COPY %tabnam% from %fi% WITH DELIMITER %delim% csv HEADER;>>fil.sql
GOTO:EOF
::endlocal
Pause
虽然我不知道SQL表的格式,但我可以向您展示如何读取CSV文件。下面的批处理文件读取文件中的所有行;它首先从第一行(CSV头)获取字段名,并创建一个变量名数组(消除字段名中可能的空格);然后读取其余的行,并将每个字段值分配给相应的批处理变量 ProcessCSV.BAT:
@echo off
rem General-purpose CSV file reader program
rem Antonio Perez Ayala
setlocal EnableDelayedExpansion
set numFields=0
rem Read the lines of the CSV file
for /F "delims=" %%a in (CSVfile.csv) do (
set "line=%%a"
if !numFields! equ 0 (
rem It is the first line: break it into an array of field names (removing spaces)
for %%b in (!line: ^=!) do (
set /A numFields+=1
set name[!numFields!]=%%b
)
) else (
rem Replace spaces by Ascii-128 (to avoid split values that may have spaces)
set "line=!line: =Ç!"
rem Insert any char. at beginning of each field, and separate fields with spaces
set i=0
for %%b in (X!line:^,^= X!) do (
set "field=%%b"
rem Recover spaces in this field, if any
set "field=!field:Ç= !"
rem And assign it to corresponding variable (removing first character)
set /A i+=1
for %%i in (!i!) do set "!name[%%i]!=!field:~1!"
)
rem At this point all variables have the values of current record.
rem They may be accessed explicitly (ie, from example CSVfile.csv):
echo/
echo Record of !FirstName! !LastName!
rem ... or implicilty via the NAME array:
for /L %%i in (3,1,!numFields!) do (
for %%b in (!name[%%i]!) do echo %%b: !%%b!
)
)
)
CSVfile.csv:
First Name,Last Name,Address,Postal Code,Company,Departament,Floor,Phone,Mobile
John,Smith,123 Fake Street,45612,SomeCo,Accounting,4,123-555-5555,123-555-5556
Jane,Doe,123 Fake Street,,SomeCo,,4,123-555-5555,123-555-5556
输出:
Record of John Smith
Address: 123 Fake Street
PostalCode: 45612
Company: SomeCo
Departament: Accounting
Floor: 4
Phone: 123-555-5555
Mobile: 123-555-5556
Record of Jane Doe
Address: 123 Fake Street
PostalCode:
Company: SomeCo
Departament:
Floor: 4
Phone: 123-555-5555
Mobile: 123-555-5556
请注意,该程序使用了几种先进的批处理技术。我建议您就您不完全理解的每个命令(即:SET/?)获取帮助,并仔细阅读。如果在此过程之后,您对本程序有进一步的问题,请在原始问题中将其作为编辑发布
该程序最复杂的部分是在相应字段为空时(两个逗号并排)将空字符串分配给变量;如果文件没有空字段,程序可能会更简单一些。此外,如果文件中出现某些特殊的批处理字符(如!),此程序(与大多数批处理解决方案一样)可能会给出错误的结果!。如果需要,可以通过程序中的某些修改来管理这些字符中的大多数
编辑:不存在空字段时修改的版本
请注意,FOR集合中的标准分隔符除空格外,还有逗号、分号和等号:
for %a in (one two,three;four=five) do echo %a
以前的程序将空格替换为另一个字符,并使用逗号分隔字段。但是,如果该行可能包含分号或等号,则字段将在该点拆分,因此在这种情况下,必须在for之前将这些字符更改为另一个字符,然后以相同的空格方式恢复
编辑:新请求的修改(删除最后一个逗号)
消除最后一个逗号不是一件小事,尽管也不太复杂。我希望我的方法容易理解;它基于显示文本(输入提示)的SET/P命令行为,末尾没有新行;请注意,格式为SET/P=text>>outfil.sql
REM读取CSV文件的行
对于(bio.csv)Do(
设置“行=%%A”
REM检查数组的索引是否为0
if!numFields!eq 0(
REM第一行,存储在数组名称中
对于(!行:^=!)中的%%B,请执行以下操作(
REM注意到我更改了ECHO命令的位置
set/A numFields+=1
集合名称[!numFields!]=%%B
如果!numFields!相等于1(
REM第一个字段:不使用逗号和新行显示
set/P=%%B(文本^)>>%sqfile%>%sqfile%
REM…并显示此字段,无逗号,无新行(再次)
set/P=%%B(文本^)>>%sqfile%>%sqfile%
)
)
::*)*
后藤:EOF
:copydata
我强烈建议您保留我以前的格式:在括号内的每个代码块中保留4个对正列,并将结束括号放在打开命令的同一列中(FOR或IF)。此格式将帮助您轻松查找大型程序中由不匹配括号引起的错误
Antonio虽然我不知道SQL表的格式,但我可以向您展示如何读取CSV文件。下面的批处理文件读取文件中的所有行;它首先从第一行(CSV头)获取字段名,并创建变量名数组(消除字段名中可能的空格);然后读取其余行,并将每个字段值分配给相应的批处理变量 ProcessCSV.BAT:
@echo off
rem General-purpose CSV file reader program
rem Antonio Perez Ayala
setlocal EnableDelayedExpansion
set numFields=0
rem Read the lines of the CSV file
for /F "delims=" %%a in (CSVfile.csv) do (
set "line=%%a"
if !numFields! equ 0 (
rem It is the first line: break it into an array of field names (removing spaces)
for %%b in (!line: ^=!) do (
set /A numFields+=1
set name[!numFields!]=%%b
)
) else (
rem Replace spaces by Ascii-128 (to avoid split values that may have spaces)
set "line=!line: =Ç!"
rem Insert any char. at beginning of each field, and separate fields with spaces
set i=0
for %%b in (X!line:^,^= X!) do (
set "field=%%b"
rem Recover spaces in this field, if any
set "field=!field:Ç= !"
rem And assign it to corresponding variable (removing first character)
set /A i+=1
for %%i in (!i!) do set "!name[%%i]!=!field:~1!"
)
rem At this point all variables have the values of current record.
rem They may be accessed explicitly (ie, from example CSVfile.csv):
echo/
echo Record of !FirstName! !LastName!
rem ... or implicilty via the NAME array:
for /L %%i in (3,1,!numFields!) do (
for %%b in (!name[%%i]!) do echo %%b: !%%b!
)
)
)
CSVfile.csv:
First Name,Last Name,Address,Postal Code,Company,Departament,Floor,Phone,Mobile
John,Smith,123 Fake Street,45612,SomeCo,Accounting,4,123-555-5555,123-555-5556
Jane,Doe,123 Fake Street,,SomeCo,,4,123-555-5555,123-555-5556
输出:
Record of John Smith
Address: 123 Fake Street
PostalCode: 45612
Company: SomeCo
Departament: Accounting
Floor: 4
Phone: 123-555-5555
Mobile: 123-555-5556
Record of Jane Doe
Address: 123 Fake Street
PostalCode:
Company: SomeCo
Departament:
Floor: 4
Phone: 123-555-5555
Mobile: 123-555-5556
请注意,此程序使用了几种高级批处理技术。我建议您获取有关您不完全理解的每个命令的帮助(即:SET/?),并仔细阅读。如果在此过程后您对此程序有进一步的问题,请在原始问题中以编辑的形式发布
该程序最复杂的部分是在相应字段为空时(并排两个逗号)将空字符串分配给变量;如果文件没有空字段,则该程序可能会更简单。此外,该程序(作为大多数批处理解决方案)如果文件中出现某些特殊的批处理字符,可能会给出错误的结果,例如!。如果需要,可以通过程序中的某些修改来管理这些字符中的大多数
编辑:不存在空字段时修改的版本
请注意,FOR集合中的标准分隔符除空格外,还有逗号、分号和等号:
for %a in (one two,three;four=five) do echo %a
以前的程序将空格替换为另一个字符,并使用逗号分隔字段。但是,如果该行可能包含分号或等号,则字段将在该点拆分,因此在这种情况下,必须在for之前将这些字符更改为另一个字符,然后以空格相同的方式恢复
编辑:新请求的修改(删除最后一个逗号)
消除最后一个逗号并非易事,尽管也不太复杂。我希望我的方法易于理解;它基于显示文本(输入提示)的SET/p命令行为,末尾没有新行;请注意格式是SET/p=text>>outfil.sql
REM读取CSV文件的行
对于/F“eol==”%%A