繁体   English   中英

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

[英]C# calling User Defined Scalar function in SQL Server that takes table type as its Parameter

我一直在对着一块石头打我的脑袋。 我编写了一个标量函数,它接受我创建的表类型作为参数,它返回一个简单的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

在我的C#方面,我有一个函数,它是一个字符串列表,放在一个数据表中,用作函数的参数。 我相信我写的这一切都是正确的,当我的项目在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.Data.dll中发生了'System.ArgumentException'类型的异常,但未在用户代码中处理

附加信息:从对象类型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)";

只需更改:

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

成为:

sqlCommand.Parameters.Add(tableType);

因为它已经是一个SqlParameter类型。 您可以使用AddWithValue创建SqlParameter (虽然请参阅我底部的说明,不要使用不推荐使用的方法),但您已经创建了SqlParameter并且只需要将它添加到集合中。

是的,从纯粹的T-SQL语法角度来看,从查询中删除* FROM也是必要的。


旁注:最好不要在任何情况下使用AddWithValue ;-):

尝试改变

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

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

您将要添加的参数值设置为不需要的SqlParameter。

SqlParameterCollection.AddWithValue方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM