TheChewingTurkey Ответов: 3

Скрипт C# форматирует CSV в инструкцию SQL insert


Привет,

Я хотел бы взять файл .CSV, который в настоящее время отформатирован как:

2018-08-16 06:06:40,35.938
2018-08-16 06:09:14,35.938
2018-08-16 06:24:14,34.862
2018-08-16 06:39:14,34.862
2018-08-16 06:54:14,35.399

и иметь такой выход, как этот:

("2018-08-16 06:06:40","35.938")
("2018-08-16 06:09:14","35.938")
("2018-08-16 06:24:14","34.862")
("2018-08-16 06:39:14","34.862")
("2018-08-16 06:54:14","35.399")

Я также хотел бы, чтобы CSV переместился из каталога C:\home\Script чтобы C:\home\Script\processed

Что я уже пробовал:

Я искал повсюду любую статью, относящуюся к такой теме, как эта. Я довольно новичок в C#, поэтому любые предложения будут очень полезны.

Я ценю ваше время,

3 Ответов

Рейтинг:
27

OriginalGriff

Используйте строку.Разделить, чтобы разбить каждую строку ввода на две части:

string[] parts = input.Split(',');

Затем используйте строку.Формат, чтобы снова "скрепить их болтами" :
if (parts.Length == 2)
   {
   string output = string.Format("\"{0}\",\"{1}\"", parts[0], parts[1]);
   ...
Или даже вот так:
if (parts.Length == 2)
   {
   string output = string.Format("(\"{0}\",\"{1}\")", parts[0], parts[1]);
   ...



[редактировать]
Никогда не объединяйте строки для построения команды SQL. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.
Когда вы читаете данные из вашего CSV и просто обрабатываете их в "SQL-совместимую" команду, вы подвергаете себя точно такому же риску.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?
[/редактировать]


TheChewingTurkey

Это прекрасно! Я ценю, что вы нашли время, чтобы предоставить мне это.

У вас случайно нет каких-нибудь предложений о том, как переместить файл в том же скрипте на следующий уровень папки вниз? например: C:\Docs\Scripts чтобы C:\Docs\Scripts\Processed-что?

OriginalGriff

Файл.Переместить? Или вы пишете файл для вывода - и в этом случае у вас, вероятно, уже есть путь?

Рейтинг:
2

Wendelius

Судя по названию вопроса это звучит так как будто вы пытаетесь построить INSERT операторы с литеральными значениями, основанными на данных в CSV-файле.

Если это так, то я бы посоветовал не использовать данные из CSV как есть, так как это оставит вас открытыми для SQL-инъекций. Одним из очень простых способов вставки данных было бы использование Класс SqlBulkCopy (System.Data.SqlClient) | Microsoft Docs[^]

Для примера чтения CSV и вставки его в таблицу посмотрите на c# - импорт CSV-файла в SQL Server с помощью SqlBulkCopy - переполнение стека[^]


TheChewingTurkey

Спасибо, что нашли время убедиться, что я не подвергаю себя большой угрозе безопасности. Однако это больше для синхронизированного скрипта python, который я просто лениво форматирую в SQL doc.

Хорошего вам дня,

OriginalGriff

Нет, он говорит, что если вы используете этот текст непосредственно как часть SQL-оператора, то вы рискуете получить SQL-инъекцию: смотрите, что я добавил к своему ответу.

Wendelius

Я не уверен, правильно ли я вас понял, но суть в том, что вы всегда должны использовать параметризованные значения при выполнении инструкций SQL. Один из сценариев таков SQL-инъекция - Википедия[^] но не использование параметров также легко приводит к синтаксическим ошибкам, проблемам преобразования с датами и числами и т. д.

Рейтинг:
2

TheChewingTurkey

Привет,

OriginalGriff заставил меня понять, что я делаю вещи более сложными, чем мне нужно. То, что я в конечном итоге сделал, это исправил скрипт python, генерирующий csv-файл:

from gpiozero import CPUTemperature
cpu = CPUTemperature()
from time import sleep, strftime, time

with open("/home/pi/cpu_temp_4.csv", "a") as log:
    while True:
        temp = cpu.temperature
        log.write("(\'{0}\',\'{1}\'),\n".format(strftime("%Y-%m-%d %H:%M:%S"),str(temp)))
        sleep(900)


Теперь без какого-либо подключения к SQL или какой-либо информации об экземпляре/базе данных/таблице я получаю это по электронной почте скрипта от моего Pi:

('2018-12-17 18:55:25','43.47'),
('2018-12-17 18:56:25','41.856'),
('2018-12-17 18:57:25','41.856'),
('2018-12-17 18:58:25','41.856'),
('2018-12-17 18:59:25','42.394'),
('2018-12-17 19:00:25','41.856'),


Я беру этот файл и копирую в SQL-запрос после того, как заполню остальную необходимую информацию, для удобства ввода данных.

Я ценю ваше время и советы.