我有一个带有DEFAULT约束的表类型:
CREATE TYPE dbo.T_MY_TABLE_TYPE AS TABLE
(
ID INT NOT NULL PRIMARY KEY,
VALUE VARCHAR(64) NULL DEFAULT ''
)
我使用type作为我的存储过程的输入参数:
CREATE PROCEDURE USP_MY_PROCEDURE
(
@P1 T_MY_TABLE_TYPE READONLY
)
AS
BEGIN
SELECT * FROM @P1
END
在T-SQL中,我可以通过以下方式运行SP:
declare @p1 dbo.T_MY_TABLE_TYPE;
insert into @p1 values(1, default);
insert into @p1 values(2, NULL);
insert into @p1 values(3, 'abc');
exec dbo.USP_MY_PROCEDURE @P1 = @p1;
如何从ADO.NET生成相同的脚本?我尝试了以下代码:
public void MyMethod(List<string> input)
{
using (SqlConnection con = GetConection())
{
using (var cmd = new SqlCommand("USP_MY_PROCEDURE", con))
{
cmd.CommandType = CommandType.StoredProcedure;
AddTableParameter(cmd.Parameters, input);
cmd.Connection.Open();
using (IDataReader dataReader = cmd.ExecuteReader())
{
//...
}
}
}
}
private void AddTableParameter(SqlParameterCollection sqlParameters, IEnumerable<string> input)
{
SqlMetaData[] metaData =
{
new SqlMetaData("ID", SqlDbType.Int, false, true, SortOrder.Ascending, 0),
new SqlMetaData("VALUE", SqlDbType.VarChar, 64)
};
int i = 1;
var param = new SqlParameter("@P1", SqlDbType.Structured)
{
TypeName = "T_MY_TABLE_TYPE",
Value = input.Select(s =>
{
var record = new SqlDataRecord(metaData);
record.SetInt32(0, i++);
if (s == null)
record.SetDBNull(1);
else if (s == "default")
{
//Do nothing. Expect that DEFAULT constraint of T_MY_TABLE_TYPE inserts ''. BUT IT DOES NOT HAPPEN!.
}
else
record.SetString(1, s);
return record;
})
};
sqlParameters.Add(param);
}
但是,当我运行以下代码时:
new MyTest().MyMethod(new List<string> { "default", null, "abc" });
代码生成的脚本忽略DEFAULT约束:
declare @p1 dbo.T_MY_TABLE_TYPE
insert into @p1 values(1, NULL) --This line is wrong!
insert into @p1 values(2, NULL)
insert into @p1 values(3, 'abc')
exec USP_MY_PROCEDURE @P1 = @p1
我尝试通过替换此行来使用SqlMetaData.UseServerDefault
属性:
new SqlMetaData("VALUE", SqlDbType.VarChar, 64)
这一行:
new SqlMetaData("VALUE", SqlDbType.VarChar, 64, true, false, SortOrder.Unspecified, -1)
但似乎当我将useServerDefault
参数指定为true时,SQL Server会忽略我为该列设置的任何值,但始终将列设置为其默认值。结果如下:
declare @p1 dbo.T_MY_TABLE_TYPE
insert into @p1 values(1, default)
insert into @p1 values(2, default)
insert into @p1 values(3, default)
exec USP_MY_PROCEDURE @P1 = @p1
有什么想法吗?