2016-01-26 54 views
4

我一直在抨擊我的頭對抗這個岩石。我寫了一個標量函數,它接受我作爲一個參數創建的表型和在這裏返回一個簡單的VARCHAR是SQL代碼,如果它有助於C#在SQL Server中調用用戶定義的標量函數,它將表類型作爲它的參數

ALTER FUNCTION [dbo].[pe_Get_Manufacturer] 
(
-- Add the parameters for the function here 
@Row [dbo].[pe_StringList] READONLY 
) 

RETURNS VARCHAR(103) 
AS 
BEGIN 

DECLARE @OUT VARCHAR(50) 
DECLARE @tempTable TABLE 
(
    Position INT, 
    ManuName CHAR(100), 
    ManuCat CHAR(3) 
) 

INSERT INTO @tempTable 
    SELECT DISTINCT r.Position, c.ima_mfg, c.ima_cat 
    FROM dbo.[Admin_ MFR Aliases] as c 
     INNER JOIN @Row r 
      ON c.orig_mfg = r.Candidate 
      OR c.ima_mfg = r.Candidate 
      OR c.orgmfgstrp = r.Candidate 
    ORDER BY r.Position 

SELECT TOP 1 @OUT = LTRIM(RTRIM(ManuName)) + '^' + COALESCE(ManuCat,'') 
FROM @tempTable 
ORDER BY Position DESC 

-- Return the result of the function 
RETURN @OUT 
END 

在我的C#身邊,我已經接受一個funcation是一個列表要放入Datatable to的字符串作爲函數的參數。我相信我已經寫了這一切都是正確怎麼過我的項目時,它進入中SqlCommand運行的ExecuteScalar

public string getManufacturer(IList<string> list) 
    { 

     int counter = 1; 
     DataTable dataTable = new DataTable(); 
     dataTable.Columns.Add("Position", typeof (int)); 
     dataTable.Columns.Add("Candidate", typeof (string)); 

     foreach (var candidate in list) 
     { 
      DataRow dataRow = dataTable.NewRow(); 
      dataRow["Position"] = counter++; 
      dataRow["Candidate"] = candidate; 
      dataTable.Rows.Add(dataRow); 
     } 

     SqlParameter tableType = new SqlParameter("@Row" , SqlDbType.Structured) 
     { 
      TypeName = "dbo.pe_StringList", 
      Value = dataTable 
     }; 

     string query = " SELECT * FROM dbo.pe_Get_Manufacturer(@Row)"; 

     SqlCommand sqlCommand = new SqlCommand(query, conn); 
     sqlCommand.Parameters.AddWithValue("@Row", tableType); 

     return sqlCommand.ExecuteScalar().ToString(); 

    } 

這是我從異常獲取的信息拋出:

「類型的異常「 System.ArgumentException」出現在system.data.dll但在用戶代碼中沒有處理

其他信息:從對象類型存在 System.Data.SqlClient.SqlParameter到已知託管提供天然 類型沒有映射。 「

編輯---- 這是我創建

CREATE TYPE pe_StringList 
AS TABLE 
(
    Position INT, 
    Candidate VARCHAR(50) 
) 

表型我從

string query = " SELECT * FROM dbo.pe_Get_Manufacturer(@Row)"; 

改變了查詢

string query = " SELECT dbo.pe_Get_Manufacturer(@Row)"; 
+0

什麼類型pe_StringList的定義?如果從SSMS中調用'SELECT * FROM dbo.pe_Get_Manufacturer(@Row)',是否可以工作? – MattC

+0

什麼是[dbo]。[pe_StringList]'? –

+0

這是我的表格類型 – Fresh

回答

4

簡單的改變:

sqlCommand.Parameters.AddWithValue("@Row", tableType); 

是:

sqlCommand.Parameters.Add(tableType); 

,因爲它已經是一個SqlParameter類型。您可以使用AddWithValue來即時創建SqlParameter(儘管請參閱底部關於不使用該已棄用方法的說明),但您已經創建了SqlParameter,只需將其添加到集合即可。

是的,從查詢中刪除* FROM也是純粹的T-SQL語法立場的必要條件。


邊注:最好是在任何情況下不使用AddWithValue,永遠;-):

+0

如果你解釋了這個評論,會很有幫助:'Side note:最好不要在任何情況下使用AddWithValue ;-)。' –

+0

@MetroSmurf希望懶惰,不要查找參考:-p。但好的通話,所以我添加了兩個鏈接。 –

+1

嘿它工作。非常感謝!知道我沒有離開我很安慰。 – Fresh

0

嘗試改變

sqlCommand.Parameters.AddWithValue("@Row", tableType); 

sqlCommand.Parameters.AddWithValue("@Row", dataTable); 

你設置你與增值到不需要的SqlParameter參數的值。

SqlParameterCollection.AddWithValue Method

+0

試驗了你建議它仍然拋出異常消息已更改爲「附加信息:表類型參數'@Row'必須具有有效的類型名稱。」 – Fresh

相關問題