一点背景知识,我需要一种在不使用参数的情况下无损插入/选择/比较单精度和双精度浮点到 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”创建程序集失败,因为程序集“SqlServerCast”格式错误或不是纯 .NET 程序集。
无法验证的 PE 标头/本机存根。
有人可以给我一步一步的成功之路吗?我被困住了...
顺便说一句:我知道创建哈希值,但我认为这还不是问题。
这些说明适用于 Microsoft SQL Server Management Studio 2014。
导入程序集
首先,您需要通过导航到“新建程序集”对话框窗口将该程序集导入到 SQL Server Management Studio 内的数据库中:
DatabaseName -> Programmability -> Assemblies -> (Right Click) 'New Assembly...'
在“新建程序集”对话框窗口中,选择
Browse
字段下的 Path to assembly
,然后选择要导入的程序集。调整权限并单击确定。
将汇编方法包装在 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/
之前的评论已失效,但该链接已失效。我有使用 4.8.0 .NET 的 SQL 2019 和 Visual Studios 2022,并且能够通过此链接让我的库正常工作。
https://learn.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-ver16&tabs=cs