我创建了User-Defined Table Type
并编写了存储过程,如下所示:
//Create the data type
CREATE TYPE [dbo].tbl_admintype AS TABLE
(
[code] [varchar](50) NULL,
[name] [varchar](100) NULL,
[branch] [varchar](100) NULL default '',
[location] [varchar](100) NULL default '',
[usertype] [varchar](50) NULL,
[password] [varchar](max) NULL,
[saltkey] [varchar](100) NULL
)
GO
//Stored Procedure
create PROCEDURE [dbo].[proc_tbl_admin_InsertItem]
@tbl_admintype tbl_admintype READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
MERGE INTO tbl_admin a
USING @tbl_admintype at
ON a.code=at.code and a.usertype=at.usertype
--WHEN MATCHED THEN
--UPDATE SET a.Name = at.Name,a.Country = at.Country
WHEN NOT MATCHED THEN
INSERT VALUES(at.name, at.code, at.password, at.saltkey,at.branch,at.location,at.usertype,1,getdate(),getdate());
select ''
END
以下代码可以正常工作:
using (SqlConnection con1 = new SqlConnection(connectionstring))
{
using (SqlCommand cmd1 = new SqlCommand("proc_tbl_admin_InsertItem"))
{
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Connection = con1;
cmd1.Parameters.AddWithValue("@tbl_admintype", dt);
con1.Open();
cmd1.ExecuteNonQuery();
con1.Close();
}
}
但是当我使用以下功能时:
public int ExecuteNonQuery(string spName, params object[] parameterValues)
{
try
{
return db.ExecuteNonQuery(spName, parameterValues);
}
catch (DALException ex)
{
throw ex;
}
}
它给出了错误:
"传入的表格数据流(TDS)远程过程调用(RPC) 协议流不正确。表值参数1 (" @ tbl_admintype"),第0行,第0列:数据类型0xF3(用户定义) table type)指定了一个非零长度的数据库名称。数据库 表值参数不允许使用name,只允许使用模式名称 和类型名称有效。"。
答案 0 :(得分:0)
请勿使用AddWithValue
。相反,这样做:
cmd1.Parameters.Add("@tbl_admintype", SqlDbType.Structured).Value = dt;
如果您坚持使用AddWithValue
,可以这样做:
SqlParameter tvpParam = cmb1.Parameters.AddWithValue(
"@tbl_admintype", dt);
tvpParam.SqlDbType = SqlDbType.Structured;
这可以完成,因为Add
方法和AddWithValue
方法都返回对参数的引用。
有关详细信息,请read this MSDN page.
答案 1 :(得分:0)
您应该在SQL Server上创建User Defined Table Type
,以便将DataTable
从C#发送到存储过程。
在SSMS中打开:
Programmability -> Types -> UserDefined Table Types
并右键点击New -> UserDefinedTableType
然后:
USE [YourDatabase]
GO
/****** Object: UserDefinedTableType [dbo].[tp_ParameterList]
Script Date: 18.10.2017 10:36:40 ******/
CREATE TYPE [dbo].[tp_ParameterList] AS TABLE(
[Name] [VARCHAR](255) NULL,
[Val] [VARCHAR](255) NULL
)
GO
现在,您可以使用可以接受DataTable
的参数执行存储过程:
ALTER PROCEDURE [dbo].[YourSPWithDataTable](
@AdditionalParams dbo.tp_ParameterList READONLY
)
AS
你可以从stored procedure
那样打电话给C#
:
var cmd = new SqlCommand("YourSPWithDataTable", db.Database.Connection as SqlConnection,
db.Database.CurrentTransaction.UnderlyingTransaction as SqlTransaction);
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Val");
dt.Rows.Add("id_Person", 1);
dt.Rows.Add("id_Dep", 1);
cmd.Parameters.Add(new SqlParameter("@AdditionalParams", dt));
cmd.ExecuteNonQuery();