一.C#写SQL SERVER(CLR)实现文件操作

标量函数: 文件移动 ,复制,检测文件存在,写入新文件文本,读取文本,创建目录,删除目录,检测目录是否存在

        /// <summary>
/// 将现有文件复制到新文件。允许覆盖同名的文件。
/// </summary>
/// <param name="sourceFileName">要复制的文件</param>
/// <param name="destFileName">目标文件的名称。不能是目录。</param>
/// <param name="overwrite">如果可以覆盖目标文件,则为 true;否则为 false。</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean FileCopy (string sourceFileName, string destFileName, bool overwrite) {
try { File.Copy (sourceFileName, destFileName, overwrite);
return File.Exists (destFileName);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 将指定文件移到新位置,并提供指定新文件名的选项。
/// </summary>
/// <param name="sourceFileName">要复制的文件</param>
/// <param name="destFileName">目标文件的名称。不能是目录。</param>
/// <param name="overwrite">如果可以覆盖目标文件,则为 true;否则为 false。</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean FileMove (string sourceFileName, string destFileName, bool overwrite) {
try {
bool isExists = File.Exists (destFileName);
if (isExists && overwrite)
File.Delete (destFileName);
if (isExists && !overwrite)
return false;
File.Move (sourceFileName, destFileName);
return File.Exists (destFileName);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 确定指定的文件是否存在。
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean FileExists (string FilePath) {
try { return File.Exists (FilePath);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 创建一个新文件,在其中写入指定的字符串,然后关闭文件。如果目标文件已存在,则覆盖该文件。
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static bool FileWriteText (string FilePath, string Contents) {
try {
File.WriteAllText (FilePath, Contents);
return File.Exists (FilePath);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 读取文本
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static string FileReadText (string FilePath) {
try {
return File.ReadAllText (FilePath);
} catch (Exception) {
return "";
}
return "";
}
/// <summary>
/// 创建目录
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static bool DirectoryCreateDirectory (string DirPath) {
try {
Directory.CreateDirectory (DirPath);
return Directory.Exists (DirPath);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 删除目录
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <param name="recursive">是否删除所有子目录与文件</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static bool DirectoryDelete (string DirPath, bool recursive) {
try {
Directory.Delete (DirPath, recursive);
return !Directory.Exists (DirPath);
} catch (Exception) {
return false;
}
return false;
}
/// <summary>
/// 目录是否存在
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static bool DirectoryExists (string DirPath) {
try {
return Directory.Exists (DirPath);
} catch (Exception) {
return false;
}
return false;
}

表值函数:读取文本,获取文件信息,获取子目录清单

    /// <summary>
/// 表值函数
///--属性 --说明
///--DataAccess --指示该函数是否涉及访问存储在SQL Server的数据
///--FillRowMethodName --在同一个类的方法的名称作为表值函数(TVF),这个参数在表值函数中才会用到,用于指定表值函数的数据填充方法
///--IsDeterministic --指示用户定义的函数是否是确定性的
///--IsPrecise --指示函数是否涉及不精确计算,如浮点运算
///--Name --函数在SQL Server中注册时使用的函数的名称
///--SystemDataAccess --指示该函数是否需要访问存储在系统目录或SQL Server虚拟系统表中的数据
///--TableDefinition --如果方法作为表值函数(TVF),则为一个字符串,该字符串表示表结构的定义
/// </summary>
public partial class SQLfunction
{
/// <summary>
/// SQL Server 读取文本转为表
/// </summary>
/// <param name="separator"></param>
/// <param name="pendingString"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(
DataAccess = DataAccessKind.Read,
IsDeterministic = true,
Name = "FileReadText2Table",
FillRowMethodName = "SqlSplit_FillRow",
TableDefinition = "SerialNumber int,StringValue nvarchar(1024)")]
public static IEnumerable FileReadText2Table(string path)
{
string[] strs = { };
strs = File.ReadAllLines(path);
List<ResultData> resultDataList = new List<ResultData>();
for (int i = ; i < strs.Length; i++)
{
resultDataList.Add(new ResultData(i + , strs[i]));
}
return resultDataList;
} /// <summary>
/// SQL Server 文件信息获取
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(
DataAccess = DataAccessKind.Read,
IsDeterministic = true,
Name = "FileInfo2Table",
FillRowMethodName = "SqlKeyValue_FillRow",
TableDefinition = "SerialNumber int,StringKey nvarchar(1024),StringValue nvarchar(1024)")]
public static IEnumerable FileInfo2Table(string path)
{
List<ResultKeyValueData> resultDataList = new List<ResultKeyValueData>();
FileInfo fileInfo = new FileInfo(path);
resultDataList.Add(new ResultKeyValueData(, "FullName", fileInfo.FullName));
resultDataList.Add(new ResultKeyValueData(, "DirectoryName", fileInfo.DirectoryName));
resultDataList.Add(new ResultKeyValueData(, "Name", Path.GetFileNameWithoutExtension(fileInfo.FullName)));
resultDataList.Add(new ResultKeyValueData(, "Extension", fileInfo.Extension));
resultDataList.Add(new ResultKeyValueData(, "IsReadOnly", fileInfo.IsReadOnly.ToString()));
resultDataList.Add(new ResultKeyValueData(, "CreationTime", fileInfo.CreationTime.ToString()));
resultDataList.Add(new ResultKeyValueData(, "LastAccessTime", fileInfo.LastAccessTime.ToString()));
resultDataList.Add(new ResultKeyValueData(, "LastWriteTime", fileInfo.LastWriteTime.ToString()));
resultDataList.Add(new ResultKeyValueData(, "Length", fileInfo.Length.ToString()));
resultDataList.Add(new ResultKeyValueData(, "Attributes", fileInfo.Attributes.ToString()));
return resultDataList;
} /// <summary>
/// SQL Server 获取目录--子目录清单
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(
DataAccess = DataAccessKind.Read,
IsDeterministic = true,
Name = "DirectoryGetFiles",
FillRowMethodName = "SqlSplit_FillRow",
TableDefinition = "SerialNumber int,StringValue nvarchar(1024)")]
public static IEnumerable DirectoryGetFiles(string path)
{
string[] strs = { };
strs = Directory.GetFiles(path);
List<ResultData> resultDataList = new List<ResultData>();
for (int i = ; i < strs.Length; i++)
{
resultDataList.Add(new ResultData(i + , strs[i]));
}
return resultDataList;
} /// <summary>
/// SQL Server 获取目录--文件清单
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(
DataAccess = DataAccessKind.Read,
IsDeterministic = true,
Name = "DirectoryGetDirectories",
FillRowMethodName = "SqlSplit_FillRow",
TableDefinition = "SerialNumber int,StringValue nvarchar(1024)")]
public static IEnumerable DirectoryGetDirectories(string path)
{
string[] strs = { };
IntPtr admin_token = IntPtr.Zero;
if (WinLogonHelper.LogonUser(ref admin_token) != )
{
using (WindowsIdentity wid_admin = new WindowsIdentity(admin_token))
{
using (WindowsImpersonationContext wic = wid_admin.Impersonate())
{
strs = Directory.GetDirectories(path);
}
}
}
List<ResultData> resultDataList = new List<ResultData>();
for (int i = ; i < strs.Length; i++)
{
resultDataList.Add(new ResultData(i + , strs[i]));
}
return resultDataList;
} } /// <summary>
/// 表值函数
///--属性 --说明
///--DataAccess --指示该函数是否涉及访问存储在SQL Server的数据
///--FillRowMethodName --在同一个类的方法的名称作为表值函数(TVF),这个参数在表值函数中才会用到,用于指定表值函数的数据填充方法
///--IsDeterministic --指示用户定义的函数是否是确定性的
///--IsPrecise --指示函数是否涉及不精确计算,如浮点运算
///--Name --函数在SQL Server中注册时使用的函数的名称
///--SystemDataAccess --指示该函数是否需要访问存储在系统目录或SQL Server虚拟系统表中的数据
///--TableDefinition --如果方法作为表值函数(TVF),则为一个字符串,该字符串表示表结构的定义
/// </summary>
public partial class SQLfunction
{
/// <summary>
/// SQL Server 字符串分割方法
/// </summary>
/// <param name="separator"></param>
/// <param name="pendingString"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(
DataAccess = DataAccessKind.Read,
IsDeterministic = true,
Name = "SqlSplit",
FillRowMethodName = "SqlSplit_FillRow",
TableDefinition = "SerialNumber int,StringValue nvarchar(1024)")]
public static IEnumerable SqlSplit(SqlString separator, SqlString pendingString)
{
string _separator = string.Empty;
string _pendingString = string.Empty;
if (pendingString.IsNull) return null;
_pendingString = pendingString.ToString();
if (string.IsNullOrEmpty(_pendingString)) return null;
_separator = separator.IsNull ? "," : separator.ToString();
_separator = string.IsNullOrEmpty(_separator) ? "," : _separator;
string[] strs = _pendingString.Split(new string[] { _separator }, StringSplitOptions.RemoveEmptyEntries);
List<ResultData> resultDataList = new List<ResultData>();
for (int i = ; i < strs.Length; i++)
{
resultDataList.Add(new ResultData(i + , strs[i]));
}
return resultDataList;
} #region 表值变量 Id,Value
/// <summary>
/// 填充数据方法
/// </summary>
/// <param name="obj"></param>
/// <param name="serialNumber"></param>
/// <param name="stringValue"></param>
public static void SqlSplit_FillRow(Object obj, out SqlInt32 SerialNumber, out SqlString StringValue)
{
ResultData resultData = (ResultData)obj;
SerialNumber = resultData.SerialNumber;
StringValue = resultData.StringValue;
} /// <summary>
/// 定义返回类型
/// </summary>
public class ResultData
{
/// <summary>
/// 序号,即行号
/// </summary>
public SqlInt32 SerialNumber { get; set; } /// <summary>
/// 分割后的每个子字符串
/// </summary>
public SqlString StringValue { get; set; } public ResultData(SqlInt32 serialNumber, SqlString stringValue)
{
SerialNumber = serialNumber;
StringValue = stringValue;
}
} #endregion #region 表值变量 ID,Key,Value
/// <summary>
/// 填充数据方法
/// </summary>
/// <param name="obj"></param>
/// <param name="serialNumber"></param>
/// <param name="stringValue"></param>
public static void SqlKeyValue_FillRow(Object obj, out SqlInt32 SerialNumber, out SqlString StringKey, out SqlString StringValue)
{
ResultKeyValueData resultData = (ResultKeyValueData)obj;
SerialNumber = resultData.SerialNumber;
StringKey = resultData.StringKey;
StringValue = resultData.StringValue;
} /// <summary>
/// 定义返回类型
/// </summary>
public class ResultKeyValueData
{
/// <summary>
/// 序号,即行号
/// </summary>
public SqlInt32 SerialNumber { get; set; }
/// <summary>
/// 键
/// </summary>
public SqlString StringKey { get; set; }
/// <summary>
/// 值
/// </summary>
public SqlString StringValue { get; set; } public ResultKeyValueData(SqlInt32 serialNumber, SqlString stringKey, SqlString stringValue)
{
SerialNumber = serialNumber;
StringKey = stringKey;
StringValue = stringValue;
}
} #endregion }

二.SQL服务器CLR配置(允许SQL调用.net程序)

    sp_configure 'show advanced options', 1;
RECONFIGURE WITH override
GO
sp_configure 'clr enabled', 1;
RECONFIGURE WITH override
GO
Sp_changedbowner 'sa',true --sa改为当前登入用户名
alter database [dbname] set trustworthy on --bbname 改为自己的库名

三.注册 CLR 程序集

   create  ASSEMBLY SQLfunctionAssembly
FROM 'D:\SQLClr.dll' --改为自己C#写的dll路径填写
WITH PERMISSION_SET = UNSAFE;

创建的.net程序集数据会写入下表:

  select * from sys.assemblies
select * from sys.assembly_files

四.创建标量函数与表值函数(分别2类函数举例)

1.标量函数----文件复制

CREATE FUNCTION [dbo].[FileCopy](@sourceFileName [nvarchar](max), @destFileName [nvarchar](max), @overwrite [bit])
RETURNS [bit] WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLfunctionAssembly].[SQLClr.SQLfunction].[FileCopy]

2.表值函数----获取文件信息

CREATE FUNCTION [dbo].[FileInfo2Table](@path [nvarchar](max))
RETURNS TABLE (
[SerialNumber] [int] NULL,
[StringKey] [nvarchar](max) NULL,
[StringValue] [nvarchar](max) NULL
) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLfunctionAssembly].[SQLClr.SQLfunction].[FileInfo2Table]

五.测试文件操作函数

测试3个函数

说明一下:D:\features文件是指服务器上的D盘features文件,而不是客户端的文件哦.

DECLARE @file  VARCHAR(MAX)
SET @file = 'D:\features'
--1.读取文件属性到Table
select * from dbo.FileInfo2Table(@file)
--2.读取文本到Table
select * from dbo.FileReadText2Table(@file)
-- 3.读取文本
select dbo.FileReadText(@file)

测试结果:

六.SQL SERVER访问共享目录方法

采用SQL SERVER操作文件是不允许操作局域网中的共享文件的,若想实现的话需Windows模拟域帐号登入,另一篇文章有讲到的。PCB 工程系统 模拟windows域帐号登入

以文件复制为例代码如下:

        /// <summary>
/// 读取文本
/// </summary>
/// <param name="FilePath">文件路径</param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction]
public static string FileReadText (string FilePath) {
try {
IntPtr admin_token = IntPtr.Zero;
if (WinLogonHelper.LogonUser (ref admin_token) != ) {
using (WindowsIdentity wid_admin = new WindowsIdentity (admin_token)) {
using (WindowsImpersonationContext wic = wid_admin.Impersonate ()) {
return File.ReadAllText (FilePath);
}
}
}
} catch (Exception) {
return "";
}
return "";
} public class WinLogonHelper {
/// <summary>
/// 模拟windows登录域
/// </summary>
[DllImport ("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser (string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
public static int LogonUser (ref IntPtr phToken) {
return WinLogonHelper.LogonUser ("用户名", "域名", "密码", , , ref phToken);
}
}

PCB MS SQL 标量函数与表值函数(CLR) 实现文件与目录操作的更多相关文章

  1. PCB MS SQL 标量函数(CLR) 实现DataTable转HTML的方法

    一.准备需转为HMLT字符串的DataTable数据 在数据库中执行一段SQL返回的数据 需转换后的HTML的文本 <html ><head></head>< ...

  2. PCB MS SQL 标量函数(CLR) 实现Socket发送消息

    在PCB业务系统中,数据库中的数据总是被应用端主动连接数据库并操作数据,是否想过可以让数据库主动的将数据推送出去呢! 答应其实是可以的.比如有这样的应用场景! 当SQL SERVER数据库满足某个条件 ...

  3. PCB MS SQL 标量函数(CLR) 实现DataTable转Json方法

    一.准备需转为json字符串的DataTable数据 在数据库中执行一段SQL返回的数据 需转换后的JSON字符串的效果 [{"TechName":"开料",& ...

  4. PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)

    将字符串分割为表表经常用到,这里 SQL表值函数与CLR  表值函数,两种实现方法例出来如下: SELECT * FROM FP_EMSDB_PUB.dbo.SqlSplit('/','1oz/1.5 ...

  5. 转载——CLR标量函数、表值函数和聚合函数(UDA)

    本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...

  6. MS SQL Server2012中的EOMONTH函数

    MS SQL Server2012中的EOMONTH函数   这个函数是获取一个指定日期所在月份最后一天的日期.可以得到某一个月月份的最后一天 如: declare @orderdate date=' ...

  7. sqlserver自定义函数(标量值函数,表值函数)

    用户自定义的函数有两类:表值函数.标量值函数. 表值函数:返回值是数据表的函数 调用方式 select  b.*  from tableA a accross apply Fun_BiaoZhiFun ...

  8. 关于T-SQL重编译那点事,内联函数和表值函数在编译生成执行计划的区别

    本文出处:http://www.cnblogs.com/wy123/p/6266724.html 最近在学习 WITH RECOMPILE和OPTION(RECOMPILE)在重编译上的区别的时候,无 ...

  9. PCB MS SQL 排序应用---SQL相邻数据区间值求解

    其中一篇 博文中有写<PCB MS SQL 排序应用---相邻数据且相同合并处理>此篇有也应相用也同的技巧,实现相邻数据区间值求解 示例: 原数据:处理前 求出区间值:处理后 SQL 代码 ...

随机推荐

  1. idea安装及使用

    使用:https://blog.csdn.net/qq_42303709/article/details/81983208 安装教程:https://blog.csdn.net/yl171272518 ...

  2. Android studio升级后原有项目无法正常编译运行问题

    Android studio工具升级后Gradle版本问题 背景 升级AndroidStudio到最新版本后,原来可正常编译输出AndroidTest的项目无法正常编译通过. 原因 升级后的Andro ...

  3. 洛谷——P1073 最优贸易

    P1073 最优贸易 n 个城市间以 m 条有向道路连接, 小 T 从 1 号城市出发, 将要去往 n 号城市.小 T 观察到一款商品 Z 在不同的城市的价格可能不尽相同,小 T 想要在旅行中的某一个 ...

  4. java.lang unsupported classversion解决方法

    设置编译的jdk和运行的jdk环境版本是否一致.一般都是jdk导致的.刚开始用jdk1.6编译运行,死活不行,换成jdk1.7运行也是1.7,ok

  5. sql常用的命令

    SELECT NAME, database_id,create_date 创建时间,is_auto_shrink_on 自动收缩,state_desc 状态,recovery_model_desc 恢 ...

  6. 个人 NABCD

    失物招领APP个人NABCD Need: 在朋友圈中,QQZone中我们长仓可以看到失物招领这方面的信息,又没有学校中专门使用的失物招领平台,所以根据这个信息,决定开发一款解决这方面问题的APP来满足 ...

  7. Django-REST-Framework JWT 实现SSO认证(上)

    一.什么是Django-REST-Framework? Django-REST-framework 是基于Django框架的一个web RESTful风格开发的框架,它可以实现API接口的快速开发,但 ...

  8. [bzoj1507][Usaco2009 Hol]Transmission Delay 传输谍延时_动态规划

    Transmission Delay 传输谍延时 bzoj-1581 Usaco-2009 Hol 题目大意:题目链接. 注释:略. 想法: 动态规划. 首先我们考虑从后往前dp.(最近好多题都是从后 ...

  9. [bzoj1878][SDOI2009]HH的项链_莫队

    HH 的项链 bzoj-1878 SDOI-2009 题目大意:给定一个n个数的序列.m次询问,每次询问一段区间内数的种类数. 注释:$1\le n\le 5\cdot 10^4$,$1\le m\l ...

  10. linux 创建 bootable iso 文件

    windows制作iso文件通过ultraiso可以实现. linux下用mkisofs这个命令就可以 最简单的用法 mkisofs -o target.iso source 要制作可以启动的iso文 ...