AntJob/AntJob.Extensions/SqlSection.cs

166 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using NewLife;
using NewLife.Data;
using NewLife.Model;
using NewLife.Reflection;
using XCode.DataAccessLayer;
namespace AntJob.Extensions
{
/// <summary>Sql操作</summary>
public enum SqlActions
{
/// <summary>查询。返回数据集</summary>
Query,
/// <summary>执行Sql或存储过程。返回影响行数</summary>
Execute,
/// <summary>插入。批量插入数据,需要传入数据集</summary>
Insert,
}
/// <summary>Sql片段。解析sql语句集合</summary>
public class SqlSection
{
#region
/// <summary>连接名</summary>
public String ConnName { get; set; }
/// <summary>操作。添删改查等</summary>
public SqlActions Action { get; set; }
/// <summary>Sql语句</summary>
public String Sql { get; set; }
#endregion
#region
/// <summary>分析sql语句集合得到片段集合以双换行分隔</summary>
/// <param name="sqls"></param>
/// <returns></returns>
public static SqlSection[] ParseAll(String sqls)
{
var list = new List<SqlSection>();
if (sqls.IsNullOrEmpty()) return list.ToArray();
// 两个换行隔开片段
var ss = sqls.Split(new[] { "\r\n\r", "\r\r", "\n\n" }, StringSplitOptions.RemoveEmptyEntries);
var connName = "";
foreach (var item in ss)
{
var section = new SqlSection();
section.Parse(item);
// 如果当前片段未指定连接名,则使用上一个
if (section.ConnName.IsNullOrEmpty())
section.ConnName = connName;
else
connName = section.ConnName;
if (section.ConnName.IsNullOrEmpty()) throw new Exception("未指定连接名!");
list.Add(section);
}
return list.ToArray();
}
/// <summary>分析sql语句到片段</summary>
/// <param name="sql"></param>
public void Parse(String sql)
{
// 解析出来连接名
var str = sql.Substring("/*", "*/")?.Trim();
if (!str.IsNullOrEmpty()) ConnName = str.Substring("use ")?.Trim();
// 剩下的Sql
sql = sql.Substring("*/")?.Trim()?.Trim(';')?.Trim();
Sql = sql;
// 猜测操作
if (sql.StartsWithIgnoreCase("select "))
Action = SqlActions.Query;
else if (sql.StartsWithIgnoreCase("insert into ", "update ", "delete "))
Action = SqlActions.Execute;
// 批量插入
else if (sql.StartsWithIgnoreCase("insert "))
Action = SqlActions.Insert;
// 默认执行,可能是存储过程
else
Action = SqlActions.Execute;
}
#endregion
#region
/// <summary>查询数据集</summary>
/// <returns></returns>
public DbTable Query() => DAL.Create(ConnName).Query(Sql);
/// <summary>执行</summary>
/// <returns></returns>
public Int32 Execute()
{
var dal = DAL.Create(ConnName);
// 解析数据表,如果目标表不存在,则返回
var tableName = "";
if (Sql.StartsWithIgnoreCase("delete "))
tableName = Sql.Substring(" from ", " ")?.Trim();
else if (Sql.StartsWithIgnoreCase("udpate "))
tableName = Sql.Substring("udpate ", " ")?.Trim();
if (!tableName.IsNullOrEmpty())
{
var table = dal.Tables?.FirstOrDefault(e => e.TableName.EqualIgnoreCase(tableName));
if (table == null) return -1;
}
return dal.Execute(Sql);
}
/// <summary>批量插入</summary>
/// <param name="dt"></param>
/// <returns></returns>
public Int32 BatchInsert(DbTable dt)
{
var tableName = Sql.Substring(" ")?.Trim(';');
var dal = DAL.Create(ConnName);
// 执行反向工程,该建表就建表
//dal.CheckDatabase();
var table = dal.Tables?.FirstOrDefault(e => e.TableName.EqualIgnoreCase(tableName));
//if (table == null) throw new Exception($"在连接[{ConnName}]中无法找到数据表[{tableName}]");
if (table == null)
{
var ioc = ObjectContainer.Current;
table = ioc.Resolve<IDataTable>();
table.TableName = tableName;
for (var i = 0; i < dt.Columns.Length; i++)
{
var dc = table.CreateColumn();
dc.ColumnName = dt.Columns[i];
dc.DataType = dt.Types[i];
table.Columns.Add(dc);
}
dal.SetTables(table);
}
// 选取目标表和数据集共有的字段
tableName = dal.Db.FormatName(table);
var columns = new List<IDataColumn>();
foreach (var dc in table.Columns)
{
if (dc.ColumnName.EqualIgnoreCase(dt.Columns)) columns.Add(dc);
}
return dal.Session.Insert(table, columns.ToArray(), dt.Cast<IModel>());
}
#endregion
}
}