我正在编写一个部署在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
一种解决方法可能是将.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;