SQLCLR 存储过程的 CREATE PROCEDURE 获得 "Msg 6567, Level 16, State 2"
CREATE PROCEDURE gets "Msg 6567, Level 16, State 2" for SQLCLR stored procedure
我在获取 SQL 服务器为我的 CLR 函数创建存储过程时遇到问题。
这是我得到的错误:
Msg 6567, Level 16, State 2, Procedure PerfInsert, Line 12 [Batch Start Line 0]
CREATE PROCEDURE failed because a CLR Procedure may only be defined on CLR methods that return either SqlInt32, System.Int32, System.Nullable, void.
我做错了什么?
(已更新)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
.
中获取值
相关帖子:
- System.Web in SQL Server CLR Function(在 DBA.StackExchange 上)
更新
O.P。确认:
it turns out the issue was I needed to drop the assembly and recreate it. Didn't realize the build version was different.
意思是,最初陈述的错误消息“CREATE PROCEDURE 失败,因为 CLR 过程只能在 return SqlInt32、System.Int32、System.Nullable, void." 可能是由于问题发布时代码本身已经解决的问题。该错误不是由于缺少 SqlProcedure
属性造成的,也不是由于将 VARCHAR
指定为数据类型造成的,因此它一定是由于我们从未见过的东西造成的。
您不需要 SqlProcedureAttribute
。这只是告诉 SSDT 发出 CREATE PROCEDURE
的元数据。存储过程应该使用NVARCHAR(MAX)
来匹配System.String
。例如:
将该 C# 文件编译成 .dll:
c:\test> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc /target:library .\proc.cs
然后:
create assembly PerfInsert from 'c:\test\proc.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
我在获取 SQL 服务器为我的 CLR 函数创建存储过程时遇到问题。
这是我得到的错误:
Msg 6567, Level 16, State 2, Procedure PerfInsert, Line 12 [Batch Start Line 0]
CREATE PROCEDURE failed because a CLR Procedure may only be defined on CLR methods that return either SqlInt32, System.Int32, System.Nullable, void.
我做错了什么?
(已更新)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
.
相关帖子:
- System.Web in SQL Server CLR Function(在 DBA.StackExchange 上)
更新
O.P。确认:
it turns out the issue was I needed to drop the assembly and recreate it. Didn't realize the build version was different.
意思是,最初陈述的错误消息“CREATE PROCEDURE 失败,因为 CLR 过程只能在 return SqlInt32、System.Int32、System.Nullable, void." 可能是由于问题发布时代码本身已经解决的问题。该错误不是由于缺少 SqlProcedure
属性造成的,也不是由于将 VARCHAR
指定为数据类型造成的,因此它一定是由于我们从未见过的东西造成的。
您不需要 SqlProcedureAttribute
。这只是告诉 SSDT 发出 CREATE PROCEDURE
的元数据。存储过程应该使用NVARCHAR(MAX)
来匹配System.String
。例如:
将该 C# 文件编译成 .dll:
c:\test> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc /target:library .\proc.cs
然后:
create assembly PerfInsert from 'c:\test\proc.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