2016-01-26 26 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

相关问题