简体   繁体   English

C#调用SQL Server中的用户定义标量函数,以表类型作为参数

[英]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.

相关问题 将多列从 c# 传递到 sql server 中的用户定义表类型 - Passing multiple columns from c# to user defined table type in sql server 在c#中创建用户定义的表类型以在sql server存储过程中使用 - Create a user defined table type in c# to use in sql server stored procedure C#auto生成SQL“用户自定义表类型” - C# auto generate SQL “user-defined table type” 从用户定义的表类型SQL生成C#类 - Generating a C# class from a user defined table type SQL 将 C# 中的用户定义类型发布到 SQL Server 时出错 - Error publish user defined type in C# to SQL Server 在 C# 中调用 SQL 定义的函数 - Calling SQL Defined function in C# 如何使用C#和SQL将表值参数传递给用户定义的数据表 - How to pass table value parameter to user defined data table using C# and SQL 传递IEnumerable <string> SQL Server存储过程作为用户定义的表类型参数 - Passing IEnumerable<string> to a SQL Server stored procedure as a user defined table type parameter 使用C#中的复杂用户定义类型(UDT)调用VB6 DLL函数 - Calling a VB6 DLL function with a complex User Defined Type (UDT) from C# 如何在 C# 中将用户定义的表类型作为存储过程参数传递 - How to pass User Defined Table Type as Stored Procedured parameter in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM