gpt4 book ai didi

postgresql - 使用批处理文件将 csv 的第一行解析为 sql 表

转载 作者:行者123 更新时间:2023-11-29 13:35:32 26 4
gpt4 key购买 nike

我有一些csv文件,我需要打开csv文件,读取csv的第一行并将其转换为临时sql表,然后将数据加载到sql表中,如下所示:

读取 CSV 的行,对于每一行:
把它分解成字段创建一个临时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 标题)获取字段名称并创建一个变量名称的数组(消除字段名称中可能的空格);然后它读取其余行并将每个字段值分配给其相应的 Batch 变量。

处理CSV.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!
)
)
)

CSV文件.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/?)寻求帮助并仔细阅读。如果在这个过程之后您对这个程序还有其他问题,只需将它们作为编辑发布到您的原始问题中。

这个程序最复杂的部分是负责在相应字段为空时(两个逗号并排)将空字符串赋值给变量;如果文件没有空字段,程序可能会更简单一些。此外,如果文件中出现某些特殊的 Batch 字符,如 !,此程序(与大多数 Batch 解决方案一样)可能会给出错误的结果。如果需要,可以通过程序中的某些修改来管理这些字符中的大多数。

编辑: 不存在空字段时的修改版本

@echo off
rem CSV file reader program when no empty fields exist
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 Separate fields (using comma as standard Batch separator)
set i=0
for %%b in (!line!) do (
set "field=%%b"
rem Assign this field to corresponding variable, recovering spaces
set /A i+=1
for %%i in (!i!) do set "!name[%%i]!=!field:Ç= !"
)
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!
)
)
)

请注意,除了空格之外,FOR 集合中的标准分隔符是逗号、分号和等号:

for %a in (one two,three;four=five) do echo %a

以前的程序用另一个字符替换空格并使用逗号分隔字段。但是,如果该行可能包含分号或等号,则字段将在该点被拆分,因此在这种情况下,必须在 FOR 之前将这些字符更改为另一个字符,然后以与空格相同的方式恢复。

编辑: 新请求的修改(删除最后一个逗号)

消除最后一个逗号并不简单,但也不是太复杂。我希望我的方法容易理解;它基于显示文本(输入提示)的 SET/P 命令行为,末尾没有新行;请注意,格式为 SET /P =text>>out<NUL<NUL 部分是必需的,因此 SET/P 不会等待输入;不要在 < 前留空格(与 >> 相同)。但是,我认为这种行为在 Windows Vista 更高版本中不起作用。如果该方法对您不起作用,则必须再次修改...

我也继续前进,包括一些关于您的代码中仍然缺少的部分(我认为)的评论,即几个文件的处理。

:proces
REM Executing loop for each file in current directory
REM *This may be done with a FOR loop:*
::*for %%F in (*.csv) do (*
REM *The file name is given by %%F. In this case, the fileinitialization part*
REM *must be done here, for example:*
set numFields=0
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 First line, Store in array name
for %%B in (!line: ^=!) do (
REM Note that I changed the place of the ECHO command
set /A numFields+=1
set name[!numFields!]=%%B
if !numFields! equ 1 (
REM First field: show it with NO comma and NO NEW LINE
set /P =%%B (text^)>>%sqfile%<NUL
) else (
REM Next fields: complete the comma of previous field, WITH NEW LINE
echo ,>>%sqfile%
REM ... and show this field with NO comma and NO NEW LINE (again)
set /P =%%B (text^)>>%sqfile%<NUL
)
)
REM Insert the new line of last field (that have NOT comma :-)
echo/>>%sqfile%
)
)
::*)*
GOTO:EOF

:copydata

我强烈建议您保留我以前的格式:每个代码块内有 4 个对齐列,用括号括起来,并将右括号放在开始命令 FOR 或 IF 的同一列中。这种格式将帮助您轻松定位大型程序中因括号不匹配而导致的错误。

安东尼奥

关于postgresql - 使用批处理文件将 csv 的第一行解析为 sql 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13402832/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com