我需要知道是否需要在我的自定义表类型中添加一个排序列,以便我可以使用它来进行排序,或者我可以相信参数的顺序即使没有这样的列也会保持不变。
这是我的类型:
CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
[VwdCode] [varchar](50) NOT NULL
)
这是其中一个使用它的SQL语句:
/// <summary>
/// Inserts all new WatchListCodes for a given watchlist
/// </summary>
public const string InsertWatchListCodes = @"
INSERT INTO [dbo].[WatchListCodes]
([WatchListID]
,[VwdCode]
,[Sort])
SELECT @WatchListID, VwdCode, ROW_NUMBER()OVER(ORDER BY (SELECT 1))
FROM @VwdCodeList;";
如您所见,我正在使用 ROW_NUMBER
来获取排序列的值。
我是否需要在表类型中添加一个排序列,或者有没有保证(记录)它仍然保持不变?看起来它可以工作。
这是我使用它的 ADO.NET 代码:
SqlParameter vwdCodeListParameter = insertWatchListCodeCommand.Parameters.Add("@VwdCodeList", SqlDbType.Structured);
vwdCodeListParameter.TypeName = "[dbo].[VwdCodeList]";
vwdCodeListParameter.Value = WatchListSql.GetVwdCodeRecords(newVwdCodes, true);
int inserted = insertWatchListCodeCommand.ExecuteNonQuery();
GetVwdCodeRecords
会返回一个IEnumerable<SqlDataRecord>
用于一个IEnumerable<string>
。
谢谢大家。如果将来的读者想知道我是如何确保排序顺序的,我已经按照建议修改了表类型,添加了另一列:
CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
[VwdCode] [varchar](50) NOT NULL,
[Sort] [smallint] NOT NULL
)
插入SQL语句更加简单,因为排序列被传递而不是计算:
插入SQL语句更加简单,因为排序列被传递而不是计算:
public const string InsertWatchListCodes = @"
INSERT INTO [dbo].[WatchListCodes]
([WatchListID]
,[VwdCode]
,[Sort])
SELECT @WatchListID, cl.VwdCode, cl.Sort
FROM @VwdCodeList cl;";
为了完整起见,这里是返回IEnumerable<SqlDataRecord>
作为表值参数的值的方法(省略错误处理):
public static IEnumerable<SqlDataRecord> GetVwdCodeRecords(IEnumerable<string> vwdCodes, bool trimCode = true)
{
short currentSort = 0;
foreach (string vwdCode in vwdCodes)
{
var record = new SqlDataRecord(
new SqlMetaData("VwdCode", SqlDbType.VarChar, 50),
new SqlMetaData("Sort", SqlDbType.SmallInt));
record.SetString(0, trimCode ? vwdCode.Trim() : vwdCode);
record.SetInt16(1, ++currentSort);
yield return record;
}
}