[英]C# calling User Defined Scalar function in SQL Server that takes table type as its Parameter
I have been beating my head against a rock on this. 我一直在对着一块石头打我的脑袋。 I have written a scalar function that takes a table type I created as a parameter and it returns a simple varchar here is the sql code if it helps
我编写了一个标量函数,它接受我创建的表类型作为参数,它返回一个简单的varchar,这里是sql代码,如果它有帮助
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
on my C# side I have a funcation that takes is a list of strings that is to be put into a Datatable to to be used as the parameter for the function. 在我的C#方面,我有一个函数,它是一个字符串列表,放在一个数据表中,用作函数的参数。 I believe I have written this is all correctly how ever my project throws when it goes to run ExecuteScalar on the SQLCommand
我相信我写的这一切都是正确的,当我的项目在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();
}
This is the information I get from the exception: 这是我从异常中获得的信息:
"An exception of type 'System.ArgumentException' occurred in System.Data.dll but was not handled in user code “System.Data.dll中发生了'System.ArgumentException'类型的异常,但未在用户代码中处理
Additional information: No mapping exists from object type System.Data.SqlClient.SqlParameter to a known managed provider native type."
附加信息:从对象类型System.Data.SqlClient.SqlParameter到已知的托管提供程序本机类型不存在映射。“
EDIT---- this is the table type I created 编辑----这是我创建的表格类型
CREATE TYPE pe_StringList
AS TABLE
(
Position INT,
Candidate VARCHAR(50)
)
I changed the query from 我改变了查询
string query = " SELECT * FROM dbo.pe_Get_Manufacturer(@Row)";
To 至
string query = " SELECT dbo.pe_Get_Manufacturer(@Row)";
Simply change: 只需更改:
sqlCommand.Parameters.AddWithValue("@Row", tableType);
to be: 成为:
sqlCommand.Parameters.Add(tableType);
since it is already a SqlParameter
type. 因为它已经是一个
SqlParameter
类型。 You would use AddWithValue
to create the SqlParameter
on-the-fly (though please see my note at the bottom about not using that deprecated method), but you have already created the SqlParameter
and just need to add it to the collection. 您可以使用
AddWithValue
创建SqlParameter
(虽然请参阅我底部的说明,不要使用不推荐使用的方法),但您已经创建了SqlParameter
并且只需要将它添加到集合中。
And yes, removing the * FROM
from the query was also necessary from a purely T-SQL syntax stand-point. 是的,从纯粹的T-SQL语法角度来看,从查询中删除
* FROM
也是必要的。
Side note: it is best to not use AddWithValue
in any case, ever ;-): 旁注:最好不要在任何情况下使用
AddWithValue
;-):
Try changing 尝试改变
sqlCommand.Parameters.AddWithValue("@Row", tableType);
to 至
sqlCommand.Parameters.AddWithValue("@Row", dataTable);
You're setting the value of the Parameter you're adding with value to a SqlParameter which is not needed. 您将要添加的参数值设置为不需要的SqlParameter。
SqlParameterCollection.AddWithValue Method SqlParameterCollection.AddWithValue方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.