|
@@ -5,6 +5,8 @@ using System.Data.SqlClient;
|
|
|
using Vit.Extensions;
|
|
|
using Vit.Core.Module.Log;
|
|
|
using Vit.Orm.Dapper;
|
|
|
+using SqlConnection = System.Data.SqlClient.SqlConnection;
|
|
|
+using System.IO;
|
|
|
|
|
|
namespace Vit.Db.DbMng.Extendsions
|
|
|
{
|
|
@@ -37,24 +39,88 @@ if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuf
|
|
|
|
|
|
*/
|
|
|
|
|
|
- #region MsSql_ReadFileFromDisk
|
|
|
+ #region MsSql_ReadFileFromDisk
|
|
|
+
|
|
|
/// <summary>
|
|
|
- /// 从磁盘读取文件内容
|
|
|
+ /// 读取SqlServer所在服务器中的文件内容,存储到本地。
|
|
|
+ /// 若服务器中不存在指定的文件则抛异常。
|
|
|
+ /// (文件内容直接存储到文件,可读取超大文件)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="conn"></param>
|
|
|
+ /// <param name="serverFilePath"></param>
|
|
|
+ /// <param name="localFilePath"></param>
|
|
|
+ /// <returns>读取的文件大小。单位:byte</returns>
|
|
|
+ public static int ReadFileFromDisk(this SqlConnection conn, string serverFilePath, string localFilePath)
|
|
|
+ {
|
|
|
+ // Sql DataReader中读取大字段到文件的方法
|
|
|
+ // https://www.cnblogs.com/sundongxiang/archive/2009/09/14/1566443.html
|
|
|
+
|
|
|
+ // select BulkColumn from OPENROWSET(BULK N'T:\机电合并.zip', SINGLE_BLOB) as content;
|
|
|
+
|
|
|
+ return conn.MsSql_RunUseMaster((c) =>
|
|
|
+ {
|
|
|
+ return c.MakeSureOpen((_) =>
|
|
|
+ {
|
|
|
+ var sql = " select BulkColumn from OPENROWSET(BULK N'" + serverFilePath + "', SINGLE_BLOB) as content";
|
|
|
+
|
|
|
+ int readedCount = 0;
|
|
|
+ using (var cmd = new SqlCommand())
|
|
|
+ {
|
|
|
+ cmd.Connection = conn;
|
|
|
+ cmd.CommandText = sql;
|
|
|
+
|
|
|
+ if (DapperConfig.CommandTimeout.HasValue)
|
|
|
+ cmd.CommandTimeout = DapperConfig.CommandTimeout.Value;
|
|
|
+
|
|
|
+ using (var dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
|
|
|
+ {
|
|
|
+ if (dr.Read())
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(Path.GetDirectoryName(localFilePath));
|
|
|
+
|
|
|
+ using (var output = new FileStream(localFilePath, FileMode.Create))
|
|
|
+ {
|
|
|
+ int bufferSize = 100 * 1024;
|
|
|
+ byte[] buff = new byte[bufferSize];
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ int buffCount = (int)dr.GetBytes(0, readedCount, buff, 0, bufferSize);
|
|
|
+
|
|
|
+ output.Write(buff, 0, buffCount);
|
|
|
+ readedCount += buffCount;
|
|
|
+
|
|
|
+ if (buffCount < bufferSize) break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return readedCount;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 从磁盘读取文件内容(文件内容会先缓存到内存,若读取超大文件,请使用ReadFileFromDisk代替)
|
|
|
/// </summary>
|
|
|
/// <param name="conn"></param>
|
|
|
/// <param name="filePath"></param>
|
|
|
- /// <returns></returns>
|
|
|
+ /// <returns>读取的文件的内容</returns>
|
|
|
public static byte[] MsSql_ReadFileFromDisk(this IDbConnection conn, string filePath)
|
|
|
{
|
|
|
- /* select BulkColumn from OPENROWSET(BULK N'T:\机电合并.zip', SINGLE_BLOB) as content;
|
|
|
- */
|
|
|
+ // select BulkColumn from OPENROWSET(BULK N'T:\机电合并.zip', SINGLE_BLOB) as content;
|
|
|
+
|
|
|
return conn.MsSql_RunUseMaster((c) =>
|
|
|
{
|
|
|
return conn.ExecuteScalar<byte[]>(
|
|
|
- " select BulkColumn from OPENROWSET(BULK N'"+ filePath + "', SINGLE_BLOB) as content"
|
|
|
- ,commandTimeout: DapperConfig.CommandTimeout);
|
|
|
+ " select BulkColumn from OPENROWSET(BULK N'" + filePath + "', SINGLE_BLOB) as content"
|
|
|
+ , commandTimeout: DapperConfig.CommandTimeout);
|
|
|
});
|
|
|
}
|
|
|
+ //*/
|
|
|
+
|
|
|
#endregion
|
|
|
|
|
|
|
|
@@ -66,8 +132,8 @@ if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuf
|
|
|
/// <param name="filePath"></param>
|
|
|
/// <returns></returns>
|
|
|
public static void MsSql_DeleteFileFromDisk(this IDbConnection conn, string filePath)
|
|
|
- {
|
|
|
- conn.MsSql_Cmdshell("del \""+ filePath + "\"");
|
|
|
+ {
|
|
|
+ conn.MsSql_Cmdshell("del \"" + filePath + "\"");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
@@ -80,29 +146,30 @@ if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuf
|
|
|
/// <param name="conn"></param>
|
|
|
/// <param name="filePath"></param>
|
|
|
/// <param name="fileContent"></param>
|
|
|
- public static void MsSql_WriteFileToDisk(this IDbConnection conn, string filePath,byte[]fileContent)
|
|
|
+ public static void MsSql_WriteFileToDisk(this IDbConnection conn, string filePath, byte[] fileContent)
|
|
|
{
|
|
|
string fmtFilePath = filePath + ".sqler.temp.fmt";
|
|
|
|
|
|
- conn.MsSql_Cmdshell(runCmd => {
|
|
|
+ conn.MsSql_Cmdshell(runCmd =>
|
|
|
+ {
|
|
|
|
|
|
#region (x.1)把文件内容写入到临时表
|
|
|
conn.Execute(@"
|
|
|
if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuffer') and xtype='U')
|
|
|
drop table sqler_temp_filebuffer;
|
|
|
select @fileContent as fileContent into sqler_temp_filebuffer;
|
|
|
-",new { fileContent }, commandTimeout: DapperConfig.CommandTimeout);
|
|
|
+", new { fileContent }, commandTimeout: DapperConfig.CommandTimeout);
|
|
|
#endregion
|
|
|
|
|
|
try
|
|
|
{
|
|
|
|
|
|
#region (x.2)写入二进制文件到磁盘
|
|
|
- var log1 = runCmd("bcp \"select null union all select '0' union all select '0' union all select null union all select 'n' union all select null \" queryout \""+ fmtFilePath + "\" /T /c");
|
|
|
- Logger.Info("[sqler]-MsSqlMng 写入文件到磁盘. 创建fmt文件,outlog: " + log1.Serialize());
|
|
|
+ var log1 = runCmd("bcp \"select null union all select '0' union all select '0' union all select null union all select 'n' union all select null \" queryout \"" + fmtFilePath + "\" /T /c");
|
|
|
+ Logger.Info("[sqler]-MsDbMng 写入文件到磁盘. 创建fmt文件,outlog: " + log1.Serialize());
|
|
|
|
|
|
var log2 = runCmd("BCP \"SELECT fileContent FROM sqler_temp_filebuffer\" queryout \"" + filePath + "\" -T -i \"" + fmtFilePath + "\"");
|
|
|
- Logger.Info("[sqler]-MsSqlMng 写入文件到磁盘.创建文件,outlog: " + log2.Serialize());
|
|
|
+ Logger.Info("[sqler]-MsDbMng 写入文件到磁盘.创建文件,outlog: " + log2.Serialize());
|
|
|
|
|
|
#endregion
|
|
|
|
|
@@ -159,13 +226,14 @@ if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuf
|
|
|
public static DataTable MsSql_Cmdshell(this IDbConnection conn, string cmd)
|
|
|
{
|
|
|
DataTable dt = null;
|
|
|
- conn.MsSql_Cmdshell( runCmd=> dt = runCmd(cmd) );
|
|
|
+ conn.MsSql_Cmdshell(runCmd => dt = runCmd(cmd));
|
|
|
return dt;
|
|
|
}
|
|
|
|
|
|
- public static void MsSql_Cmdshell(this IDbConnection conn, Action<Func<string,DataTable>> handleToRun)
|
|
|
- {
|
|
|
- conn.MsSql_RunUseMaster((c)=> {
|
|
|
+ public static void MsSql_Cmdshell(this IDbConnection conn, Action<Func<string, DataTable>> handleToRun)
|
|
|
+ {
|
|
|
+ conn.MsSql_RunUseMaster((c) =>
|
|
|
+ {
|
|
|
|
|
|
bool advancedOptionsIsOpened = false;
|
|
|
try
|
|
@@ -182,9 +250,9 @@ if Exists(select top 1 * from sysObjects where Id=OBJECT_ID(N'sqler_temp_filebuf
|
|
|
cmdshellIsOpened = c.ExecuteDataTable("EXEC SP_CONFIGURE 'xp_cmdshell'").Rows[0]["config_value"]?.Convert<string>() != "0";
|
|
|
}
|
|
|
catch (Exception)
|
|
|
- {
|
|
|
+ {
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
try
|
|
|
{
|
|
@@ -206,8 +274,8 @@ RECONFIGURE;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
- if(!cmdshellIsOpened)
|
|
|
- c.Execute(@"
|
|
|
+ if (!cmdshellIsOpened)
|
|
|
+ c.Execute(@"
|
|
|
--关闭执行CMD命令
|
|
|
EXEC SP_CONFIGURE 'xp_cmdshell', 0;
|
|
|
RECONFIGURE;
|
|
@@ -221,9 +289,9 @@ RECONFIGURE;
|
|
|
", commandTimeout: Orm.Dapper.DapperConfig.CommandTimeout);
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
#endregion
|
|
|
|