如何从T-SQL、SQL Server调用C#代码



有一点上下文,我需要一种方法,在不使用参数的情况下,将单精度和双精度浮点无损地插入/选择/比较到SQL Server数据库中,我认为我会很聪明,并将DLL作为超快速函数调用。

我编写并测试了这个C#类(,我已经很好地测试了(:

using System;
using System.Linq;
using System.Reflection;
namespace SqlServerCast
{
public class SqlServerCast
{
static public char ByteOrder;
public enum ByteOrderEnum {
BigEndian = 1,     /*  The most significant byte (highest address) is stored first. */
LittleEndian = 0   /*  The least significant byte (lowest address) is stored first. */}
public static void Main()
{
Assembly assem = typeof(SqlServerCast).Assembly;
Object o = assem.CreateInstance("SqlServerCast", false,
BindingFlags.ExactBinding,
null, new Object[] { 2 }, null, null); 
}
public SqlServerCast(char val)    //  constructor
{
if (val != 0) ByteOrder = (char) ByteOrderEnum.BigEndian;
else ByteOrder = (char) ByteOrderEnum.LittleEndian;
}
public static double CastToDBL(string str) {return BitConverter.ToDouble(StringToByteArray(str), 0);}
public static float CastToSGL(string str)  {return BitConverter.ToSingle(StringToByteArray(str), 0);}
private static string Dash = "-", NullStr = null;
public static string CastFromDBL(double dbl) {
switch (ByteOrder)
{
case (char)ByteOrderEnum.BigEndian:   //  actually, network byte order, big endian
byte[] bytes = BitConverter.GetBytes(dbl);
return BitConverter.ToString(bytes.Reverse().ToArray()).Replace(Dash, NullStr);
case (char)ByteOrderEnum.LittleEndian:
return BitConverter.ToString(BitConverter.GetBytes(dbl)).Replace(Dash, NullStr);
default:
return null;
}
}
public static string CastFromSGL(float sgl)
{
switch (ByteOrder)
{
case (char)ByteOrderEnum.BigEndian:   //  actually, network byte order, big endian
byte[] bytes = BitConverter.GetBytes(sgl);
return BitConverter.ToString(bytes.Reverse().ToArray()).Replace(Dash, NullStr);
case (char)ByteOrderEnum.LittleEndian:
return BitConverter.ToString(BitConverter.GetBytes(sgl)).Replace(Dash, NullStr);
default:
return null;
}
}
private static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
switch (ByteOrder) {
case (char) ByteOrderEnum.BigEndian:   //  actually, network byte order, big endian
return bytes.Reverse().ToArray();
case (char) ByteOrderEnum.LittleEndian:
return bytes;
default:
return null;
}
}
}
}

试图遵循SO和MSDN上关于T-SQL可调用DLL的规定,到目前为止我得到了以下错误:

消息6544,级别16,状态1,第1行
程序集"SqlServerCast"的CREATE ASSEMBLY失败,因为程序集"SQL ServerCast"格式错误或不是纯.NET程序集
不可验证的PE头/本机存根。

有人能给我一个循序渐进的成功之路吗?我被卡住了。。。

BTW:我知道创建哈希,我认为这还不是问题所在。

这些说明适用于Microsoft SQL Server Management Studio 2014。

导入程序集

首先,您需要导航到"新建程序集"对话框窗口,将该程序集导入SQL Server Management Studio中的数据库:

DatabaseName -> Programmability -> Assemblies -> (Right Click) 'New Assembly...'

在"新建程序集"对话框窗口中,在"Path to assembly"字段下选择"Browse",然后选择要导入的程序集。调整权限并单击"确定"。

SQL函数中的包装汇编方法

接下来,您需要创建sql函数来包装您的汇编方法,如下所示:

CREATE FUNCTION [dbo].[fn_funcName](@str [varchar](max))
RETURNS 
varchar(max) 
WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [YourSqlAssemblyName].[YourAssemblyName.Class1].[GetName]

若要从函数返回表,请阅读.NET.中的SqlFunctionAttribute

创建Sql server数据库项目并编译要在Sql server中使用的dll的分步指南:

https://dbtut.com/index.php/2019/05/05/what-is-clr-and-how-to-import-dll-in-sql-server/

最新更新