从文件

时间:2016-02-26 09:59:35

标签: c# sql postgresql

我正在编写SQL执行模块,它是医疗应用程序的一部分。

模块

  1. 接受加密的.sql文件名作为输入。该文件将包含dml语句,如插入行/更新行,注释(下面的示例)
  2. 解密文件
  3. 准备SQL语句列表并执行,忽略注释行(以 - 开头的行)
  4. 出现错误时弹出一个亚麻布
  5. 采用的方法

    1. 加载sqlfile和descryption就可以了,完成了 使用简单的File.ReadAllText和预先构建的解密模块
    2. 准备列表是模块失败的地方。我用了这段代码:

      string[] dmllines = dml.Split(new string[] { ";\r\n", ";\n" }, StringSplitOptions.RemoveEmptyEntries);
      

      它会导致执行忽略评论后出现的SQL,因为它已被拆分。

    3. 无法仅从换行符拆分数据,因为insert语句的列值中存在换行符。分号也是如此

      • DB:Postgres9.0.4
      • 代码:.NET 4.0,C#,Npgsql

      欢迎任何有关解决方案的帮助

      由于

        

      EDIT1:我想补充一点,即使是postgres,也没有使用第三方库,实用工具的可能性。
        EDIT2:我正在研究使用正则表达式或只是在循环中使用char解析char的可能性

      以下SAMPLEDATA

        

      - 姓名:activitylog_recordid_seq;类型:SEQUENCE SET;架构:公共;所有者:postgres    - SELECT pg_catalog.setval(' activitylog_recordid_seq',1022,true); INSERT INTO已发布(refnum,vdate,contact,totalamount,bankname,   staffname,trnmode,trngroup,bookmark,patientid,postedon,   statusdate,status,ourbank,chequecarddetail,comment,createdon,   editedon,loginid,recordid,sourcetable,sourceid,tallyid,rounding,   放置)VALUES(NULL,' 2016-02-14 17:51:55',' AHLCON PARENTERALS   (INDIA)LTD',232.00,'','','支票',' PATIENT RECEIPTS',false,0 ,   NULL,NULL,'已清除','','','',' 2016-02-14 17 :52:03',NULL,   ' PPPP',59,NULL,0,63,NULL,NULL);   --Insert from DB:00319 INSERT INTO posted(refnum,vdate,contact,totalamount,bankname,staffname,trnmode,trngroup,   书签,patientid,postson,statusdate,status,ourbank,   chequecarddetail,comment,createdon,editedon,loginid,recordid,   sourcetable,sourceid,tallyid,rounding,placed)VALUES(NULL,   ' 2016-02-14 18:04:48',' AHLCON PARENTERALS(INDIA)LTD',400.00,'',   '',' Cash',' PATIENT RECEIPTS;',false,0,NULL,NULL,'已清除',' ;&#39 ;,   '','',' 2016-02-14 18:04:50',NULL,' admin',60,NULL ,0,64,NULL,   空值); INSERT INTO印刷品(donorname,referencenum,baggageid,   campname,receiptttype,qty,units,receiptdetail,storestaff,   验证,验证,不合理,收据,不适合评论,   评论,createdon,editedon,loginid,recordid,qtyissued,   qtybalance,expiry,条形码,donorref,barcodedonor,bloodadditives,   licenseref,source,attributes,category)VALUES('',NULL,   ' B31399040',' C131 BLUD',' Blood',1200.0000,' mg / Ml',' AB_Positive',   ' HELLOO'' PALS',' 2015-06-30 19:03:52',false,' 2015-06-29 19:03 :52&#39 ;,   '',NULL,' 2015-06-30 19:05:10',' 2015-07-03 12:15:33',&#39 ; PPPP',4,   200.0000,1000.0000,' 2019-06-30 19:03:52',NULL,' d753',NULL,'柠檬酸钠(二水合物).... 2.63g柠檬酸   (一水合物)... 0.299g葡萄糖(一水合物)....... 2.55g一元   二磷酸钠(一水合物).0.222g','',''',NULL,NULL);

4 个答案:

答案 0 :(得分:1)

您应该考虑从外部生成psql以从文件导入。您应该能够通过stdin将信息发送到psql,而不是写入磁盘上的实际文件 - 因为您提到输入数据已加密。

psql的输出可以被捕获并返回给用户。

解析SQL应该由专门的解析器完成。作为psql的替代方案,请尝试使用可以为您执行此操作的库,例如Entity Framework。 见Parsing SQL code in C#

答案 1 :(得分:1)

试试这个。如果您有一个或多个GO语句的查询,则必须拆分脚本以分隔所有查询并逐个执行

var fileContent = File.ReadAllText("query.sql");
var sqlqueries = fileContent.Split(new[] {" GO "}, StringSplitOptions.RemoveEmptyEntries);

var con = new SqlConnection("connstring");
var cmd = new SqlCommand("query", con);
con.Open();
foreach (var query in sqlqueries)
{
    cmd.CommandText = query;
    cmd.ExecuteNonQuery();
}
con.Close();

答案 2 :(得分:1)

这是一种破解,但对于简单的事情(选择/插入/删除/更新)可能有效:

string pattern = "(SELECT|INSERT|DELETE|UPDATE|--)"; //ADD HERE THE SQL VERBS YOU NEED
string[] result = Regex.Split(sqls, pattern).Where(s => s != String.Empty).ToArray<string>();
for (int i = 0; i < result.Count(); i += 2) 
{
     if (!result[i].StartsWith("--"))
     {
           Console.WriteLine(result[i] + result[i + 1]);
     }
}

我确信这可以改进,但你明白了。它适用于您的示例数据

答案 3 :(得分:0)

您可以尝试使用execute plpgsql命令执行脚本:

do $$
begin
  execute 'create table t (x int); insert into t values (1), (2), (3); drop table t;'; -- Change to your script here
end $$ language plpgsql;

或为其创建存储函数:

create or replace function execute_script(in p_script text) returns void as $$
begin
  execute p_script;
end $$ language plpgsql;