6

Мне нужно знать, нужно ли мне добавить столбец сортировки в свой собственный тип таблицы, который я мог бы использовать для сортировки, или если я могу доверять тому, что порядок параметров остается неизменным даже без такого столбца.Является ли порядок сортировки табличных параметров неизменным?

Это мой тип:

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(); 

GetVwdCodeRecordsIEnumerable<SqlDataRecord> возвращается для IEnumerable<string>.


Спасибо всем. Если будущему читателю интересно узнать, как я гарантировал порядок сортировки. Я доработанную таблицу типа, как предложено добавить еще один столбец:

CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
    [VwdCode] [varchar](50) NOT NULL, 
    [Sort] [smallint] NOT NULL 
) 

Вкладыш-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; 
    } 
} 
+0

Хорошие шансы, это зависит от определения типа таблицы. Например, определение первичного ключа в вашем типе таблицы имеет неплохую возможность изменить порядок, в котором вы возвращаете свои записи. Я бы взял более безопасный подход к добавлению другого столбца в тип таблицы и настройке его в коде ADO.NET. – dasblinkenlight

ответ

3

В целом: Нет никакого неявного порядка сортировки по любому набору результатов.

единственный способом для достижения гарантированного заказа на сортировку является ORDER BY на внешнепризматических большинстве запросов.

Я уверен, что вы знали об этом уже ...

Существует один specialty with ROW_NUMBER() OVER(ORDER BY ...) Read "General Remarks". Но это опасно.

  • Порядок сортировки только в том случае, если вы используете уникальный критерий сортировки в ORDER BY. Вы используете SELECT 1, что не гарантирует порядок сортировки. Это может сработать сотни тестов и внезапно ломаться ...
  • Любое последующее действие может уничтожить этот порядок сортировки. Просто воображайте, что у вас есть рабочая функция, и через несколько месяцев вы используете эту функцию в сложном запросе.

Я использую это, например, для создания XML с уверенным порядком, потому что в XML есть неявный порядок, заданный позицией ...

1

Да, вам нужно добавить столбец. SQL - это язык, основанный на наборе, и наборы по своей сути неупорядочены (по общему признанию, существует более чем несколько случаев, когда SQL является неаккуратным по этому поводу).

Если вы хотите использовать ORDER BY, и вы хотите, чтобы гарантировать результаты, вы должны убедиться, что он основан на достаточно выражений, основанных на данных в таблице таким образом, что она однозначно определяет порядок. Здесь вы заказываете константу (и предупреждения, которые вы получаете, если вы просто попробуете ORDER BY 1, здесь должно быть достаточно информации о том, что он не будет работать хорошо), поэтому нет никаких гарантий относительно того, какой заказ фактически применяется.

+0

Спасибо. Но не могло ли быть так, что пользовательский тип таблицы, который используется для табличных параметров, обрабатывается по-разному с помощью sql-сервера? Чтобы они фактически гарантировали, что порядок вставки останется прежним. Это было бы полезно. Я знаю, что заказ не гарантируется нормально и что таблица не имеет «неотъемлемого» порядка. Но тип таблицы, который имеет очень короткий срок службы в качестве параметра и может вести себя по-разному. Но я думаю, что нет никакой разницы в простой таблице. –

+1

@TimSchmelter - в момент времени, когда были введены типы таблиц, каждый опытный разработчик SQL использовался для работы с таблицами, в которых нет неотъемлемого порядка. Что тогда было бы оправданием для предоставления дополнительных гарантий или усилий по развитию для этих новых объектов, чтобы они действовали по-разному? И если у них было это удивительное новое поведение, вы ожидаете, что он будет выделен в документации как часть этой функции. –

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 

и план выполнения показывает ..

enter image description here

Таким образом, ниже фрагмента кода.

ROW_NUMBER()OVER(ORDER BY (SELECT 1)) 
FROM @VwdCodeList;"; 

Возможно, вы не получите тот же заказ каждый раз, если вы не указали явный порядок на

+0

Спасибо. Но не могло ли быть так, что пользовательский тип таблицы, который используется для табличных параметров, обрабатывается по-разному с помощью sql-сервера? Чтобы они фактически _guarantee_, порядок вставки остался прежним. Это было бы полезно. Я знаю, что заказ не гарантируется нормально и что таблица не имеет «неотъемлемого» порядка. Но тип таблицы, который имеет очень короткий срок службы в качестве параметра и может вести себя по-разному. В вашем примере вы выбираете из простой таблицы. –

+0

Я тоже думал о том же, что и для табличных параметров, так как они читаются только. Но порядок не гарантируется для какого-либо набора результатов, пока вы не закажете .. вы также можете проверить эту статью .. – TheGameiswar

+0

https: // blogs .msdn.microsoft.com/conor_cunningham_msft/2008/08/27/no-seatbelt-expecting-order-without-order-by/ – TheGameiswar

Смежные вопросы