如何使用SQL Server将可为null的guid声明为C#CLR存储过程的可选参数



我正在编写一个部署在SQL Server 2008 R2(so.Net 3.5)上的C#存储过程,并希望将一个可选参数声明为可为null的guid。以下是我首先尝试的内容:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void spCalcPerc(
SqlGuid pID
, SqlGuid sID = DBNull.Value
)

此操作失败,出现编译时错误:

"sID"的默认参数值必须是编译时常数

这是因为DBNull.Value不是常数,这是一种痛苦。

所以我试着把声明改成:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void spCalcPerc(
SqlGuid pID
, Guid? sID = null
)

这编译了,但现在我得到了这个部署错误:

部署错误:无法为参数System.Nullable创建类型

正在尝试:

, SqlGuid sID = null

给出此编译时错误:

类型为'<null>'不能用作默认参数,因为没有到类型的标准转换"System.Data.SqlTypes.SqlGuid">

所以感觉很困,我求助于这个:

, SqlGuid sID = "00000000-0000-0000-0000-000000000000"

这是我不想做的,因为在代码中测试那个字符串感觉像是一团糟。然而,这也不起作用,因为我得到了这个编译错误:

类型为"string"的值不能用作默认参数,因为没有到类型为"System.Guid"的标准转换

Gah,4种不同的方法,但都不起作用叹息

如果您有任何想法或是向正确的方向努力,我将不胜感激。

尝试

, SqlGuid sID = New Guid()

你可以使用

if (sID == Guid.Empty)

检查是否未为其指定值。

只为您想要的默认值传递Nulls是否有问题
当然,这可能不适用于所有情况
有时您可能想知道实际值是否确实为Null,因此避免使用默认值
如果是这种情况,那么我会添加一个额外的">默认"参数。

[Microsoft.SqlServer.Server.SqlProcedure]
public static void MySproc(SqlGuid pID, SqlGuid sID, SqlBoolean UseDefault_sID)
{
sID = (UseDefault_sID == SqlBoolean.True && sID == SqlGuid.Null)
? SomeDefaultPIDValue : sID;
}

这样就不必编写额外的">包装器"存储过程来接受具有默认值的可选参数,然后调用CLR存储过程。

Null传入时使用默认值:UseDefault_pID=1
Null传入时保留实际值:UseDefault _pID=0

只需将其声明为:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void spCalcPerc(
SqlGuid pID
, SqlGuid sID
)

然后在SQLServer:中手动注册

ALTER PROCEDURE [dbo].[spCalcPerc]
@pID [uniqueidentifier],
@sID [uniqueidentifier] = null
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SqlServerProject3].[StoredProcedures].[spCalcPerc]

然后可以使用IsNull属性来测试sID是否为空:

SqlContext.Pipe.Send(sID.IsNull.ToString());

恐怕我不知道在C#代码中声明默认值的方法。

我没有试过,但你试过吗

Guid.Empty

正如您所指出的,这是因为C#2.0不支持可选参数。

一种解决方法可能是将.NET存储过程包装在接受默认参数的常规T-SQL存储过程中。

例如:

CREATE PROCEDURE TestProcWrapper
(
@TestIntWrapperParam int = null
)
AS
EXEC TestProc @TestInt = @TestIntWrapperParam

如下检查是否为null。

[Microsoft.SqlServer.Server.SqlProcedure]
public static void spCalcPerc(SqlGuid pID)
{
// check for null or set default
Guid refId = pID.IsNull ? Guid.NewGuid() : pID.Value;

最新更新