一.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. linux cmp-比较两个文件是否有差异

    推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 cmp命令用来比较两个文件是否有差异.当相互比较的两个文件完全一样时,则该指令不会显示任何信息.若发现有差异,预设会标示出第一个不通 ...

  2. CCF201609-1 最大波动 java (100分)

    试题编号: 201609-1 试题名称: 最大波动 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 小明正在利用股票的波动程度来研究股票.小明拿到了一只股票每天收盘时的价格,他 ...

  3. 1.Ubuntu查看Python版本

    1.输入命令:ls -l /usr/bin/python*

  4. BZOJ 2274 [Usaco2011 Feb]Generic Cow Protests

    [题解] 很容易可以写出朴素DP方程f[i]=sigma f[j] (sum[i]>=sum[j],1<=j<=i).  于是我们用权值树状数组优化即可. #include<c ...

  5. 学习MongoDB--(5-2):索引(查看索引的使用,管理索引)

    前一篇简单介绍了索引,并给出了基本的索引使用,这一次,我们进一步说一下MongoDB中的索引,包括如何查看查询是否走索引,如何管理索引和地理空间索引等. [使用explain和hint] 前面讲高级查 ...

  6. noip模拟赛 洗衣

    分析:好神的一道题啊.对每棵树建个图跑一下floyd可以有40分,想要打出正解就得对树有比较深的认识了. 每次新生成一棵树都是由两棵树i,j拼成的,答案为原来两棵树的答案和+i中每个点到j中每个点的距 ...

  7. jconsole远程连接 jmx配置注意事项

    由于在测试程序时需要收集程序运行时的内存,CPU等消耗情况.选择了jconsole这个jdk自带工具来观察.为了不影响程序运行状态,用远程连接的方式来具体观察. 首先,程序是放在ubutun系统服务器 ...

  8. xtrabackup 恢复单表步骤

    1.apply-log应用redo日志,并导出表的数据字典innobackupex --apply-log --export  备份集 2.建表 如果知道表结构,则重建删除的表 create tabl ...

  9. 一个性能较好的jvm參数配置以及jvm的简单介绍

    一个性能较好的webserverjvm參数配置: -server //服务器模式 -Xmx2g //JVM最大同意分配的堆内存,按需分配 -Xms2g //JVM初始分配的堆内存.一般和Xmx配置成一 ...

  10. HDU 5100 Chessboard 用 k &#215; 1 的矩形覆盖 n &#215; n 的正方形棋盘

    pid=5100">点击打开链接 Chessboard Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...