SqlMetaData.Name кажется неуместным при передаче пользовательскому типу таблицы через SqlDataRecord. - PullRequest
1 голос
/ 27 марта 2019

У меня есть хранимая процедура, которая принимает определяемый пользователем тип таблицы в качестве параметра.В C # я использую SqlDataRecord и SqlMetaData (и SqlParameter), чтобы создать параметр таблицы с моими данными и отправить его в хранимую процедуру.

Это прекрасно работает, когда столбцы (SqlMetaData) находятся в том же порядке, что и столбецопределения внутри фактического типа таблицы sql-сервера.Если они НЕ в одном и том же порядке, то будут сопоставлены неправильные столбцы.

Так в чем же смысл свойства SqlMetaData.Name?Кажется, он игнорируется (по крайней мере, для этого варианта использования), и учитывается только порядок столбцов (и данных).


Пример ...

У меня есть тип таблицы в SQL:

CREATE TYPE [dbo].[TestingTableParamType] AS TABLE(
    [FName] VARCHAR(50) NULL,
    [Numb] INT NULL,
    [LName] VARCHAR(50) NULL
);

У меня есть хранимая процедура:

CREATE PROCEDURE spTEST_TableParam
@input TestingTableParamType READONLY
AS
SELECT FName, Numb, LName FROM @input

И у меня есть метод генерации тестовых данных, который дает три строки тестовых данных ссоответствующие типы столбцов в соответствующем порядке (чтобы соответствовать определению TestingTableParamType). Обратите внимание, однако, что я использую пустые строки в качестве имен! Я пробовал с бессмысленными строками, и это также работало нормально (null приведет к исключению):

private IEnumerable<SqlDataRecord> genTestSqlDataRecords()
{
    SqlDataRecord record = new SqlDataRecord(
        new SqlMetaData("", SqlDbType.VarChar, 50),
        new SqlMetaData("", SqlDbType.Int),
        new SqlMetaData("", SqlDbType.VarChar, 50));

    record.SetValues("fn1", 101, "ln1");
    yield return record;
    record.SetValues("fn2", 102, "ln2");
    yield return record;
    record.SetValues("fn3", 103, "ln3");
    yield return record;
}

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

Существует еще некоторый код, который выполняет сама база данных, вотсоответствующий фрагмент:

...
SqlParameter param = new SqlParameter("@input", SqlDbType.Structured);
param.Direction = ParameterDirection.Input;
param.TypeName = "TestingTableParamType";
param.Value = genTestSqlDataRecords();

dbCommand.Parameters.Add(param);

conn.Open();

var dataReader = dbCommand.ExecuteReader();
...

Итак, похоже, что свойство SqlMetaData (column) Name не имеет значения, по крайней мере, для этого варианта использования.Это создает вводящий в заблуждение код - в том смысле, что вы можете изменить порядок столбцов (и данных), и он должен соответствовать их именам, но этого не происходит!

Кроме того, во всех примерахвидел использование SqlDataRecord и SqlMetaData для передачи параметров типа таблицы, предоставляющих имена для своих столбцов, как будто это необходимо.

Что я пропустил во всем этом?Спасибо, любезно.

1 Ответ

0 голосов
/ 27 марта 2019

в чем смысл свойства SqlMetaData.Name?

Нет вообще здесь .Но для хранимой процедуры CLR, передающей набор результатов через SendResultsStart и связанные методы или Send(SqlDataRecord), жизненно важно, потому что до вызова этих методов SQL Server не имеет представления, что такое «форма» 1 из результирующего набора есть, и он использует эти метаданные для его понимания (и для возможности пересылки этих метаданных обратно в клиентские приложения).


1 Я часто использую форму, когда говорю о результирующих наборах.Это количество столбцов, их имена и типы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...