我在让SQL Server为我的CLR函数创建存储过程时遇到问题。
这是我得到的错误:
Msg 6567,Level 16,State 2,Procedure PerfInsert,Line 12[Batch Start Line 0]
CREATE Procedure失败,因为CLR过程只能在返回SqlInt32或System的CLR方法上定义。Int32,系统。可为空,无效。
我做错了什么?
(更新(C#代码:
using Microsoft.SqlServer.Server;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
namespace MiddleMan
{
public static class MiddleMan
{
[SqlProcedure(Name = "PerfInsert")]
public static SqlInt32 CreateCommand(SqlChars tblString, SqlChars featureName, SqlChars connectionString, SqlChars perfionConnectionString, SqlChars logFile)
{
Process compiler = new Process();
compiler.StartInfo.FileName = "C:\SQL Server C# Functions\PerfionLoader\PerfionLoader\bin\Release\PerfionLoader.exe";
compiler.StartInfo.Arguments = tblString.Value + " " + featureName.Value + " " + connectionString.Value + " " + perfionConnectionString.Value + " " + logFile.Value;
//compiler.StartInfo.UseShellExecute = false;
//compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();
return SqlInt32.Zero;
}
}
}
(更新(SQL代码:
CREATE PROCEDURE PerfInsert
(
@tblString nvarchar(max)
, @featureName nvarchar(max)
, @connectionString nvarchar(max)
, @perfionConnectionString nvarchar(max)
, @logFiel nvarchar(max)
)
AS EXTERNAL NAME PerfInsert.[MiddleMan.MiddleMan].[CreateCommand]
GO
您应该用装饰方法
[SqlProcedure()]
public static SqlInt32 ...
{
...
}
而且,SQLCLR不适用于VARCHAR
。您需要更改T-SQL定义才能使用NVARCHAR(4000)
。如果4000还不够,那么您可以使用MAX
,但如果输入保证不超过4000字节,那么1-4000更有效。这里可能没有什么不同,但有一个好习惯:-(。
此外,最好使用Sql*
类型作为输入参数。也就是说,使用SqlString
并从param.Value
中获取值。
相关文章:
- 系统。SQL Server CLR函数中的Web(在DBA.StackExchange上(
- 系统。安全CLR函数出现SecurityException
;
更新
O。P.确认:
原来问题是我需要删除程序集并重新创建它。没有意识到构建版本不同。
这意味着,最初声明的错误消息"CREATE PROCEDURE失败,因为CLR过程只能在返回SqlInt32、System.Int32、System.Nullable、void的CLR方法上定义。"可能是由于发布问题时代码本身已解决的问题。该错误不是由于缺少SqlProcedure
属性造成的,也不是由于将VARCHAR
指定为数据类型造成的,所以它一定是由于我们从未见过的原因造成的。
您不需要SqlProcedureAttribute
。这只是告诉SSDT发出CREATE PROCEDURE
的元数据。存储过程应该使用NVARCHAR(MAX)
来匹配System.String
。例如:
将该C#文件编译为.dll:
c:test> C:WindowsMicrosoft.NETFramework64v4.0.30319csc /target:library .proc.cs
然后:
create assembly PerfInsert from 'c:testproc.dll'
WITH PERMISSION_SET = UNSAFE;
go
CREATE PROCEDURE PerfInsert
(@tblString NVARCHAR(max),
@featureName NVARCHAR(max),
@connectionString NVARCHAR(max),
@perfionConnectionString NVARCHAR(max),
@logFiel NVARCHAR(max)
)
AS EXTERNAL NAME PerfInsert.[MiddleMan.MiddleMan].[CreateCommand]
GO