Вопрос

Я просмотрел веб-сайт SQLTeam, но теперь у меня возникла новая проблема, потому что у меня есть столбец IDENTITY, а в их примере его нет.

У меня есть SQL Server 2008 и VS 2008.Я пытаюсь выполнить InsertPIF SP, используя C # и таблицу UDT, но получаю исключение.Я просмотрел веб-сайт SQLTeam пример с таблицей UDT, но в их примере нет столбца identity, как в моем.

Однако в их таблице примеров нет столбца identity, подобного моему.То, что я пытаюсь сделать, должно быть простым.Я перепробовал много различных вариаций этого, но по сути:

ALTER PROCEDURE [dbo].[InsertPIF] @InputFileParam parseInputFile READONLY
AS
INSERT dbo.ParentTable SELECT strRow FROM @InputFileParam
GO

где

CREATE TABLE [dbo].[ParentTable](
    [ParentID] [int] IDENTITY(1,1) NOT NULL,
    [strInput] [varchar](8000) NULL,
PRIMARY KEY NONCLUSTERED 
(...)

и введите:

CREATE TYPE [dbo].[parseInputFile] AS TABLE(
    [NumCols] [int] IDENTITY(1,1) NOT NULL,
    [strRow] [varchar](500) NOT NULL,
    PRIMARY KEY CLUSTERED 
(...)

То, что я пытаюсь сделать, это выполнить приведенный выше SP для вставки новых записей в родительскую таблицу.Пример:

INSERT INTO ParentTable(strInput) VALUES ('A3|BB|C|DDD')
INSERT INTO ParentTable(strInput) VALUES ('A4|GOB|BLDY|GOOK')
INSERT INTO ParentTable(strInput) VALUES ('A5|Hello|My|Darling')

Вот еще часть моего кода на C #, предшествующего разделу AppendData:

DataTable dt = new DataTable();
String[] header = myStringArray[0].Split('|');

DataRow dr = dt.NewRow();
DataColumn dc = new DataColumn();
dc.DataType = typeof(Int32);
dc.ColumnName = “NumCols”;
dc.AutoIncrement=true;
dt.Columns.Add(dc);

DataColumn dc2 = new DataColumn();
dc2.DataType = typeof(string);
dc2.ColumnName = “strRow”;
dt.Columns.Add(dc2);
dr["NumCols"] = 1;
dr["strRow"] = "AA|BBB|CC|DD|E";
dt.Rows.Add(dr);

...
                SqlConnection conn = new SqlConnection(connString);
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = "dbo.InsertPIF";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = conn;
                SqlParameter param = cmd.Parameters.AddWithValue("@InputFileParam", SqlDbType.Structured);

        param.Value = dt;
        conn.Open();
        RowsAffected = cmd.ExecuteNonQuery();

Я установил, что идентификация должна быть включена для ParentTable, но, похоже, мне приходится выполнять это каждый сеанс, поэтому я не уверен, как убрать требование идентификации или же заставить идентификацию оставаться включенной.Исключение:

ВСТАВИТЬ в столбец идентификатора, не разрешенный для табличных переменных.Данные для параметра с табличным значением '@InputFileParam' не соответствуют табличному типу параметра.

Как мне выполнить этот SP?

Это было полезно?

Решение

Я думаю, что Roland находится на правильном пути - столбцы ИДЕНТИФИКАЦИИ определенно являются проблемой.Поскольку в вашей конечной целевой таблице уже есть столбец идентификатора, который будет заполнен автоматически для вас, я бы рекомендовал не указывать тот же столбец в вашем пользовательском типе таблицы (а также не объявлять первичный ключ для типа таблицы):

CREATE TYPE [dbo].[parseInputFile] AS TABLE
    ([strRow] [varchar](500) NOT NULL)

Затем в вашем коде C # просто настройте DataTable с одним столбцом:

DataTable dt = new DataTable();

DataColumn dc = new DataColumn();
dc.DataType = typeof(string);
dc.ColumnName = “strRow”;
dt.Columns.Add(dc);

а затем добавьте ваши столбцы в вашу таблицу данных "dt" - используя только одну строку "strRow".

В вашей сохраненной процедуре, которая затем вызывается с вашим пользовательским типом таблицы, просто вставьте свои строки:

ALTER PROCEDURE [dbo].[InsertPIF] @InputFileParam parseInputFile READONLY
AS
  INSERT INTO dbo.ParentTable(strInput)
    SELECT strRow FROM @InputFileParam
GO

Я надеюсь, этого должно хватить!(у меня не было времени проверить это самому)

Марк

Другие советы

Ладно, на самом деле я еще не работал с TVP, так что я могу ошибаться, но, исходя из моего чтения и общего опыта работы с SS, я подумай ваша проблема заключается в следующем:

В вашей постоянной таблице есть столбец Identity, поэтому SS хочет обработать это за вас.Ты может установите Identity Insert включенным, но это не очень хорошая идея....

Одна вещь, которую нужно попробовать, это указать столбец для вставки в ваш SP:

ALTER PROCEDURE [dbo].[InsertPIF] @InputFileParam parseInputFile READONLY
AS
INSERT dbo.ParentTable (strInput) SELECT strRow FROM @InputFileParam
GO

Еще одна вещь, на которую следует обратить внимание, как предложил Тим Лентайн (пока я писал этот ответ), заключается в том, действительно ли вы добираетесь до сервера.Поскольку вы определили столбец numCols в вашей DataTable как AutoIncrement , возможно, вы получаете свое исключение в коде C #, в:

...
dr["NumCols"] = 1;
...

< редактировать>

Не знаю, что я имел в виду, когда нажал Отправить...

Если это так, попробуйте исключить автоинкремент при создании вашего DataTable .Если в типы данных столбцов являются согласованными, это свойство не должно иметь значения при настройке TVP как "того же", что и тип SS.

< /редактировать>

Может ли ошибка исходить из таблицы parseInputFile вместо этого?numCols определяется как поле идентификации, но в коде C # вы устанавливаете значение записи равным 1.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top