2009-06-16 31 views
2

我查看了SQLTeam網站,但現在出現了一個新問題,因爲我有一個IDENTITY列,但他們的示例沒有。如何執行C表中的表SP#

我有SQL Server 2008和VS 2008.我嘗試使用C#和表UDT執行InsertPIF SP,但得到異常。我已經用表UDT看了一個SQLTeam網站 的例子,但是他們的例子並沒有像我這樣的標識列。

但是,他們的示例表沒有像我的標識列。 我想要做的事情應該很簡單。我已經試過這許多不同的變化,但本質:

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來將新記錄插入到ParentTable中。例如:

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?

回答

1

我認爲羅蘭是在正確的軌道上 - 標識列肯定是問題。由於您的最終目標表已經有一個IDENTITY列,它將自動爲您填充,因此我建議您不要在用戶定義的表類型中指定相同的列(並且也不要在表類型上聲明主鍵):

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

然後在你的C#代碼,只設置了一列數據表:

DataTable dt = new DataTable(); 

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

,然後添加你的列到您的DataTable「DT」 - 只用一個字符串「strRow」。

在你的存儲過程是那麼被調用與用戶定義的表型,只是簡單地插入你的字符串:

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

應該這樣做,我希望! (還沒有時間去親自測試)

Marc

+0

非常感謝你!馬克,我嘗試了你最後的解決方案,併爲我解決了這個問題!我現在很開心! (我一直在處理這個問題3天)。 – salvationishere 2009-06-16 18:49:06

0

錯誤可能來自parseInputFile表嗎? NumCols被定義爲標識字段,但在C#代碼中,您將記錄的值設置爲1.

1

好吧,我還沒有真正與TVPs一起工作過,所以我可能是錯的 - 但是從我的讀書,&一般SS的背景下,我認爲問題是這樣的:

你永久表有標識列,所以SS要搞定你。您可以一套標識插入上,但是這不是一個好主意....

一件事是嘗試以指定的SP插入列:

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

的另一件事看正如Tim Lentine所建議的(當我正在寫這個答案的時候),就是你是否真正進入服務器。既然你已經在你的數據表作爲自動遞增定義的NUMCOLS列,這可能是因爲你得到你的異常在C#代碼,網址爲:

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

<編輯>

不知道是什麼當我點擊提交時,我正在搜索...

如果是這種情況,請嘗試在創建DataTable時忽略AutoIncrement。如果列數據類型是一致的,則當將TVP排列爲與SS類型「相同」時,此屬性應該沒有關係。

< /編輯>