Sql server 2008 将批量CSV文件插入到一个SQL表中[SQL Server 2008]
我有多个文件夹(六个左右),其中包含多个.CSV文件。CSV文件的格式都相同:Sql server 2008 将批量CSV文件插入到一个SQL表中[SQL Server 2008],sql-server-2008,csv,bulkinsert,Sql Server 2008,Csv,Bulkinsert,我有多个文件夹(六个左右),其中包含多个.CSV文件。CSV文件的格式都相同: Heading1,Heading2,Heading3 1,Monday,2.45 2,Monday,3.765... 每个.CSV都有相同的标题名称[不同月份的相同数据源]。将这些CSV导入SQL Server 2008的最佳方法是什么?服务器没有配置xpShell[出于安全原因,我无法修改],因此任何使用该配置的方法(我最初尝试过)都无法工作 编辑 CSV文件的最大大小为2mb,不包含任何逗号(分隔符所需的逗号除
Heading1,Heading2,Heading3
1,Monday,2.45
2,Monday,3.765...
每个.CSV都有相同的标题名称[不同月份的相同数据源]。将这些CSV导入SQL Server 2008的最佳方法是什么?服务器没有配置xpShell[出于安全原因,我无法修改],因此任何使用该配置的方法(我最初尝试过)都无法工作
编辑
CSV文件的最大大小为2mb,不包含任何逗号(分隔符所需的逗号除外)
有什么想法吗?F.e.您在
D:\
驱动器上获得了CSV文件名sample.CSV
,其中包括:
Heading1,Heading2,Heading3
1,Monday,2.45
2,Monday,3.765
然后可以使用此查询:
DECLARE @str nvarchar(max),
@x xml,
@head xml,
@sql nvarchar(max),
@params nvarchar(max) = '@x xml'
SELECT @str = BulkColumn
FROM OPENROWSET (BULK N'D:\sample.csv', SINGLE_CLOB) AS a
SELECT @head = CAST('<row><s>'+REPLACE(SUBSTRING(@str,1,CHARINDEX(CHAR(13)+CHAR(10),@str)-1),',','</s><s>')+'</s></row>' as xml)
SELECT @x = CAST('<row><s>'+REPLACE(REPLACE(SUBSTRING(@str,CHARINDEX(CHAR(10),@str)+1,LEN(@str)),CHAR(13)+CHAR(10),'</s></row><row><s>'),',','</s><s>')+'</s></row>' as xml)
SELECT @sql = N'
SELECT t.c.value(''s[1]'',''int'') '+QUOTENAME(t.c.value('s[1]','nvarchar(max)'))+',
t.c.value(''s[2]'',''nvarchar(max)'') '+QUOTENAME(t.c.value('s[2]','nvarchar(max)'))+',
t.c.value(''s[3]'',''decimal(15,7)'') '+QUOTENAME(t.c.value('s[3]','nvarchar(max)'))+'
FROM @x.nodes(''/row'') as t(c)'
FROM @head.nodes('/row') as t(c)
首先,借助于,我们将数据作为SINGLE\u CLOB
然后我们把所有的变量都放入@str
变量中。从开始到开始的部分\r\n
我们放在@head
中,另一部分放在@x
中,并转换为XML。结构:
<row>
<s>Heading1</s>
<s>Heading2</s>
<s>Heading3</s>
</row>
<row>
<s>1</s>
<s>Monday</s>
<s>2.45</s>
</row>
<row>
<s>2</s>
<s>Monday</s>
<s>3.765</s>
</row>
并执行它。变量@x
作为参数传递
希望这对您有所帮助。F.e.您在
D:\
驱动器上获得了CSV文件名sample.CSV
,其中包含:
Heading1,Heading2,Heading3
1,Monday,2.45
2,Monday,3.765
然后可以使用此查询:
DECLARE @str nvarchar(max),
@x xml,
@head xml,
@sql nvarchar(max),
@params nvarchar(max) = '@x xml'
SELECT @str = BulkColumn
FROM OPENROWSET (BULK N'D:\sample.csv', SINGLE_CLOB) AS a
SELECT @head = CAST('<row><s>'+REPLACE(SUBSTRING(@str,1,CHARINDEX(CHAR(13)+CHAR(10),@str)-1),',','</s><s>')+'</s></row>' as xml)
SELECT @x = CAST('<row><s>'+REPLACE(REPLACE(SUBSTRING(@str,CHARINDEX(CHAR(10),@str)+1,LEN(@str)),CHAR(13)+CHAR(10),'</s></row><row><s>'),',','</s><s>')+'</s></row>' as xml)
SELECT @sql = N'
SELECT t.c.value(''s[1]'',''int'') '+QUOTENAME(t.c.value('s[1]','nvarchar(max)'))+',
t.c.value(''s[2]'',''nvarchar(max)'') '+QUOTENAME(t.c.value('s[2]','nvarchar(max)'))+',
t.c.value(''s[3]'',''decimal(15,7)'') '+QUOTENAME(t.c.value('s[3]','nvarchar(max)'))+'
FROM @x.nodes(''/row'') as t(c)'
FROM @head.nodes('/row') as t(c)
首先,借助于,我们将数据作为SINGLE\u CLOB
然后我们把所有的变量都放入@str
变量中。从开始到开始的部分\r\n
我们放在@head
中,另一部分放在@x
中,并转换为XML。结构:
<row>
<s>Heading1</s>
<s>Heading2</s>
<s>Heading3</s>
</row>
<row>
<s>1</s>
<s>Monday</s>
<s>2.45</s>
</row>
<row>
<s>2</s>
<s>Monday</s>
<s>3.765</s>
</row>
并执行它。变量@x
作为参数传递
希望这对您有所帮助。我最终使用非SQL答案解决了我的问题。感谢每一位为我们做出贡献的人。我很抱歉使用PHP给出了一个完全脱离现场的答案。以下是我为解决此问题而创建的:
<?php
//////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Date: 21/10/2016. //
// Description: Insert CSV rows into pre-created SQL table with same column structure. //
// Notes: - PHP script needs server to execute. //
// - Can run line by line ('INSERT') or bulk ('BULK INSERT'). //
// - 'Bulk Insert' needs bulk insert user permissions. //
// //
// Currently only works under the following file structure: //
// | ROOT FOLDER //
// | FOLDER 1 //
// | CSV 1 //
// | CSV 2... //
// | FOLDER 2 //
// | CSV 1 //
// | CSV 2... //
// | FOLDER 3... //
// | CSV 1 //
// | CSV 2... //
// //
//////////////////////////////////////////////////////////////////////////////////////////////////
//Error log - must have folder pre-created to work
ini_set("error_log", "phplog/bulkinsertCSV.php.log");
//Set the name of the root directory here (Where the folder's of CSVs are)
$rootPath = '\\\networkserver\folder\rootfolderwithCSVs';
//Get an array with the folder names located at the root directory location
// The '0' is alphabetical ascending, '1' is descending.
$rootArray = scandir($rootPath, 0);
//Set Database Connection Details
$myServer = "SERVER";
$myUser = "USER";
$myPass = "PASSWORD";
$myDB = "DATABASE";
//Create connection to the database
$connection = odbc_connect("Driver={SQL Server};Server=$myServer;Database=$myDB;", $myUser, $myPass) or die("Couldn't connect to SQL Server on $myServer");
//Extend Database Connection timeout
set_time_limit(10000);
//Set to true for bulk insert, set to false for line by line insert
// [If set to TRUE] - MUST HAVE BULK INSERT PERMISSIONS TO WORK
$bulkinsert = true;
//For loop that goes through the folders and finds CSV files
loopThroughAllCSVs($rootArray, $rootPath);
//Once procedure finishes, close the connection
odbc_close($connection);
function loopThroughAllCSVs($folderArray, $root){
$fileFormat = '.csv';
for($x = 2; $x < sizeof($folderArray); $x++){
$eachFileinFolder = scandir($root."\\".$folderArray[$x]);
for($y = 0; $y < sizeof($eachFileinFolder); $y++){
$fullCSV_path = $root."\\".$folderArray[$x]."\\".$eachFileinFolder[$y];
if(substr_compare($fullCSV_path, $fileFormat, strlen($fullCSV_path)-strlen($fileFormat), strlen($fileFormat)) === 0){
parseCSV($fullCSV_path);
}
}
}
}
function parseCSV($path){
print_r($path);
print("<br>");
if($GLOBALS['bulkinsert'] === false){
$csv = array_map('str_getcsv', file($path));
array_shift($csv); //Remove Headers
foreach ($csv as $line){
writeLinetoDB($line);
}
}
else{
bulkInserttoDB($path);
}
}
function writeLinetoDB($line){
$tablename = "[DATABASE].[dbo].[TABLE]";
$insert = "INSERT INTO ".$tablename." (Column1,Column2,Column3,Column4,Column5,Column6,Column7)
VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."','".$line[6]."')";
$result = odbc_prepare($GLOBALS['connection'], $insert);
odbc_execute($result)or die(odbc_error($connection));
}
function bulkInserttoDB($csvPath){
$tablename = "[DATABASE].[dbo].[TABLE]";
$insert = "BULK
INSERT ".$tablename."
FROM '".$csvPath."'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\\n')";
print_r($insert);
print_r("<br>");
$result = odbc_prepare($GLOBALS['connection'], $insert);
odbc_execute($result)or die(odbc_error($connection));
}
?>
我最终使用上面的脚本逐行写入数据库。。。这需要几个小时。我修改了脚本以使用批量插入,不幸的是,我们没有使用“权限”。一旦我“获得”了权限,批量插入方法就发挥了作用。我最终用非SQL的答案解决了问题。感谢每一位为我们做出贡献的人。我很抱歉使用PHP给出了一个完全脱离现场的答案。以下是我为解决此问题而创建的:
<?php
//////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Date: 21/10/2016. //
// Description: Insert CSV rows into pre-created SQL table with same column structure. //
// Notes: - PHP script needs server to execute. //
// - Can run line by line ('INSERT') or bulk ('BULK INSERT'). //
// - 'Bulk Insert' needs bulk insert user permissions. //
// //
// Currently only works under the following file structure: //
// | ROOT FOLDER //
// | FOLDER 1 //
// | CSV 1 //
// | CSV 2... //
// | FOLDER 2 //
// | CSV 1 //
// | CSV 2... //
// | FOLDER 3... //
// | CSV 1 //
// | CSV 2... //
// //
//////////////////////////////////////////////////////////////////////////////////////////////////
//Error log - must have folder pre-created to work
ini_set("error_log", "phplog/bulkinsertCSV.php.log");
//Set the name of the root directory here (Where the folder's of CSVs are)
$rootPath = '\\\networkserver\folder\rootfolderwithCSVs';
//Get an array with the folder names located at the root directory location
// The '0' is alphabetical ascending, '1' is descending.
$rootArray = scandir($rootPath, 0);
//Set Database Connection Details
$myServer = "SERVER";
$myUser = "USER";
$myPass = "PASSWORD";
$myDB = "DATABASE";
//Create connection to the database
$connection = odbc_connect("Driver={SQL Server};Server=$myServer;Database=$myDB;", $myUser, $myPass) or die("Couldn't connect to SQL Server on $myServer");
//Extend Database Connection timeout
set_time_limit(10000);
//Set to true for bulk insert, set to false for line by line insert
// [If set to TRUE] - MUST HAVE BULK INSERT PERMISSIONS TO WORK
$bulkinsert = true;
//For loop that goes through the folders and finds CSV files
loopThroughAllCSVs($rootArray, $rootPath);
//Once procedure finishes, close the connection
odbc_close($connection);
function loopThroughAllCSVs($folderArray, $root){
$fileFormat = '.csv';
for($x = 2; $x < sizeof($folderArray); $x++){
$eachFileinFolder = scandir($root."\\".$folderArray[$x]);
for($y = 0; $y < sizeof($eachFileinFolder); $y++){
$fullCSV_path = $root."\\".$folderArray[$x]."\\".$eachFileinFolder[$y];
if(substr_compare($fullCSV_path, $fileFormat, strlen($fullCSV_path)-strlen($fileFormat), strlen($fileFormat)) === 0){
parseCSV($fullCSV_path);
}
}
}
}
function parseCSV($path){
print_r($path);
print("<br>");
if($GLOBALS['bulkinsert'] === false){
$csv = array_map('str_getcsv', file($path));
array_shift($csv); //Remove Headers
foreach ($csv as $line){
writeLinetoDB($line);
}
}
else{
bulkInserttoDB($path);
}
}
function writeLinetoDB($line){
$tablename = "[DATABASE].[dbo].[TABLE]";
$insert = "INSERT INTO ".$tablename." (Column1,Column2,Column3,Column4,Column5,Column6,Column7)
VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."','".$line[6]."')";
$result = odbc_prepare($GLOBALS['connection'], $insert);
odbc_execute($result)or die(odbc_error($connection));
}
function bulkInserttoDB($csvPath){
$tablename = "[DATABASE].[dbo].[TABLE]";
$insert = "BULK
INSERT ".$tablename."
FROM '".$csvPath."'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\\n')";
print_r($insert);
print_r("<br>");
$result = odbc_prepare($GLOBALS['connection'], $insert);
odbc_execute($result)or die(odbc_error($connection));
}
?>
我最终使用上面的脚本逐行写入数据库。。。这需要几个小时。我修改了脚本以使用批量插入,不幸的是,我们没有使用“权限”。一旦我“获得”了权限,批量插入方法就发挥了作用。CSV文件有多大?如果需要,您可以假设使用Excel。请注意,
BULK INSERT
不提供真正的CSV解析器:它不支持转义引号,甚至不支持引号中的逗号()。最大的CSV文件大小约为2mb。数据不包含任何逗号或转义引号。基本上有三个选项-首先看看大容量插入是否能按建议用于文件。如果没有,您可能需要使用SSI,或者可以使用外部进程(如powershell脚本)将数据推入。CSV文件有多大?如果需要,您可以假设使用Excel。请注意,BULK INSERT
不提供真正的CSV解析器:它不支持转义引号,甚至不支持引号中的逗号()。最大的CSV文件大小约为2mb。数据不包含任何逗号或转义引号。基本上有三个选项-首先看看大容量插入是否能按建议用于文件。如果没有,您可能需要使用SSI,或者可以使用外部进程(如powershell脚本)将数据推入。