Это вложение не представляется возможным в bash, но оно работает в zsh:
progname=${${0%.*}##*/}
Вы «можете» попробовать следующее.
Создайте промежуточную таблицу с 1 столбцом для хранения данных. VARCHAR (MAX) + 1 столбец для хранения имени файла
. Затем настройте SSIS для загрузки каждой строки в этот столбец (без разделителя столбцов). Вам, вероятно, потребуется загрузить заголовок как строку данных, чтобы получить имена col.
Затем вы можете добавить цикл ForEach в эту таблицу.
Наконец, вы должны написать сохраненный процесс, который анализирует разделенные запятыми имена столбцов и динамически создает таблицы назначения, а также анализирует значения и загружает их.
Не самый эффективный способ загрузки данных, но если у вас небольшой размер файла, с вами все будет в порядке ...
Это можно сделать с помощью задачи «Сценарий» в цикле Foreach типа перечислителя файлов. Обратите внимание, что этот пример предназначен для отправки данных в промежуточные таблицы, так как каждый столбец определяется как VARCHAR(250)
. Возможно, вам придется отрегулировать длину, 250 использовался только для тестирования. Созданные таблицы названы в честь файлов, из которых поступают данные, и вы должны быть уверены, что таблицы с этими именами уже не существуют, иначе они будут удалены. Если вы хотите, чтобы это не сработало, когда таблица с таким именем уже существует, удалите первый вызов SqlCommand.ExecuteNonQuery()
, который выполняет этот шаг. В цикле Foreach добавьте переменную с индексом 0 для хранения имени файла, затем добавьте эту переменную в поле ReadOnlyVariables
задачи «Сценарий». Эта переменная равна VariableWithFilePath
в приведенном ниже примере.
using System.Data.SqlClient;
using System.IO;
using System.Collections.Generic;
using System.Linq;
string connstr = @"Data Source=YourServer;Initial Catalog=YourDatabase;Integrated Security=SSPI;";
//get file path
string fullFileName = Dts.Variables["User::VariableWithFilePath"].Value.ToString();
//get only file name to be used when creating table
string fileName = Path.GetFileNameWithoutExtension(fullFileName);
DataTable dt = new DataTable();
using (StreamReader sr = new StreamReader(fullFileName))
{
List<string> colNames = new List<string>();
string firstLine = sr.ReadLine();
string[] headers = firstLine.Split(',');
foreach (string h in headers)
{
dt.Columns.Add(h);
colNames.Add(h);
}
int columnCount = headers.Count();
string line = sr.ReadLine();
while (line != null)
{
string[] fields = line.Split(',');
int currentLength = fields.Count();
if (currentLength < columnCount)
{
//make sure fields from each row are kept together
while (currentLength < columnCount)
{
line += sr.ReadLine();
currentLength = line.Split(',').Count();
}
fields = line.Split(',');
}
//load data table
dt.Rows.Add(fields);
line = sr.ReadLine();
}
string columns = string.Join(" VARCHAR(250), ", colNames);
//command to drop table if it already exist
string dropDDL = "IF (OBJECT_ID(N'DBO." + fileName + "') IS NOT NULL) DROP TABLE DBO." + fileName;
//command to create new with same name as file
string createDDL = "CREATE TABLE DBO." + fileName + " ( " + columns + " VARCHAR(250) )";
using (SqlConnection conn = new SqlConnection(connstr))
{
SqlCommand sql = new SqlCommand();
sql.Connection = conn;
sql.CommandText = dropDDL;
//drop table if exists
conn.Open();
sql.ExecuteNonQuery();
//create table
sql.CommandText = createDDL;
sql.ExecuteNonQuery();
//load SQL Server table from data table
using (SqlBulkCopy blkCpy = new SqlBulkCopy(conn))
{
blkCpy.DestinationTableName = fileName;
blkCpy.WriteToServer(dt);
}
}
}