table 值参数的排序顺序是否保证保持不变?
Is the sort-order of table-valued-parameters guaranteed to remain the same?
我需要知道我是否需要向我的自定义 table-type 添加一个排序列,然后我可以使用它来排序,或者我是否可以相信参数的顺序保持不变,即使没有这样的专栏。
这是我喜欢的类型:
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
来获取排序列值。
我是否还需要向 table 类型添加一个排序列,还是保证(记录)它保持不变?好像还行。
这是我使用它的 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
returns IEnumerable<SqlDataRecord>
IEnumerable<string>
.
谢谢大家。如果未来 reader 有兴趣知道我是如何保证排序顺序的。我按照建议修改了 table 类型,添加了另一列:
CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
[VwdCode] [varchar](50) NOT NULL,
[Sort] [smallint] NOT NULL
)
insert-sql更简单,因为sort-column是传入的,不是计算的:
public const string InsertWatchListCodes = @"
INSERT INTO [dbo].[WatchListCodes]
([WatchListID]
,[VwdCode]
,[Sort])
SELECT @WatchListID, cl.VwdCode, cl.Sort
FROM @VwdCodeList cl;";
为了完整起见,这里是 returns IEnumerable<SqlDataRecord>
用作 table 值参数(省略错误处理)的值的方法:
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;
}
}
一般来说:任何结果集都没有隐式排序顺序。
实现保证排序顺序的唯一方法是ORDER BY
大多数查询.
我相信你已经知道了...
有一个specialty with ROW_NUMBER() OVER(ORDER BY ...)
Read "General Remarks"。但这是危险的。
- 仅当您在
ORDER BY
中使用唯一的排序标准时,排序顺序才确定。您正在使用 SELECT 1
,这将不保证任何排序顺序。这可能会进行数百次测试并突然中断...
- 以后的任何操作都可能破坏此排序顺序。想象一下,您有一个可用的函数,几个月后,您在复杂的查询中使用了这个函数。
我使用它来创建具有确定顺序的 XML,因为在 XML 中有一个由位置给出的隐式顺序...
是的,您需要添加一列。 SQL 是一种基于集合的语言,集合本质上是无序的(诚然,在很多情况下 SQL 对此有点漏洞)。
如果你想使用ORDER BY
并且你想保证结果,你需要确保它基于数据中足够的表达式table 这样它唯一地定义了顺序。在这里,您按常量排序(如果您只是在此处尝试 ORDER BY 1
收到的警告应该足以说明它不会正常工作)因此无法保证实际应用的排序。
不保证相同的订单,除非您明确订购..
下面是一些测试..
create type numbes as table
(
num int primary key
)
DECLARE @nums AS numbes;
insert into @nums
select row_number() over(order by(select 1))
from
master.sys.objects
select Top 100* from @nums
执行计划显示..
所以下面的一段代码..
ROW_NUMBER()OVER(ORDER BY (SELECT 1))
FROM @VwdCodeList;";
可能不会每次都得到相同的订单,除非您通过
提及明确的订单
我需要知道我是否需要向我的自定义 table-type 添加一个排序列,然后我可以使用它来排序,或者我是否可以相信参数的顺序保持不变,即使没有这样的专栏。
这是我喜欢的类型:
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
来获取排序列值。
我是否还需要向 table 类型添加一个排序列,还是保证(记录)它保持不变?好像还行。
这是我使用它的 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
returns IEnumerable<SqlDataRecord>
IEnumerable<string>
.
谢谢大家。如果未来 reader 有兴趣知道我是如何保证排序顺序的。我按照建议修改了 table 类型,添加了另一列:
CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
[VwdCode] [varchar](50) NOT NULL,
[Sort] [smallint] NOT NULL
)
insert-sql更简单,因为sort-column是传入的,不是计算的:
public const string InsertWatchListCodes = @"
INSERT INTO [dbo].[WatchListCodes]
([WatchListID]
,[VwdCode]
,[Sort])
SELECT @WatchListID, cl.VwdCode, cl.Sort
FROM @VwdCodeList cl;";
为了完整起见,这里是 returns IEnumerable<SqlDataRecord>
用作 table 值参数(省略错误处理)的值的方法:
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;
}
}
一般来说:任何结果集都没有隐式排序顺序。
实现保证排序顺序的唯一方法是ORDER BY
大多数查询.
我相信你已经知道了...
有一个specialty with ROW_NUMBER() OVER(ORDER BY ...)
Read "General Remarks"。但这是危险的。
- 仅当您在
ORDER BY
中使用唯一的排序标准时,排序顺序才确定。您正在使用SELECT 1
,这将不保证任何排序顺序。这可能会进行数百次测试并突然中断... - 以后的任何操作都可能破坏此排序顺序。想象一下,您有一个可用的函数,几个月后,您在复杂的查询中使用了这个函数。
我使用它来创建具有确定顺序的 XML,因为在 XML 中有一个由位置给出的隐式顺序...
是的,您需要添加一列。 SQL 是一种基于集合的语言,集合本质上是无序的(诚然,在很多情况下 SQL 对此有点漏洞)。
如果你想使用ORDER BY
并且你想保证结果,你需要确保它基于数据中足够的表达式table 这样它唯一地定义了顺序。在这里,您按常量排序(如果您只是在此处尝试 ORDER BY 1
收到的警告应该足以说明它不会正常工作)因此无法保证实际应用的排序。
不保证相同的订单,除非您明确订购..
下面是一些测试..
create type numbes as table
(
num int primary key
)
DECLARE @nums AS numbes;
insert into @nums
select row_number() over(order by(select 1))
from
master.sys.objects
select Top 100* from @nums
执行计划显示..
所以下面的一段代码..
ROW_NUMBER()OVER(ORDER BY (SELECT 1))
FROM @VwdCodeList;";
可能不会每次都得到相同的订单,除非您通过
提及明确的订单