如何参数化包含IN具有可变数量参数的子句的查询,比如这个?
SELECT * FROM Tags
WHERE Name IN ('ruby','rails','scruffy','rubyonrails')
ORDER BY Count DESC
Run Code Online (Sandbox Code Playgroud)
在此查询中,参数的数量可以是1到5之间的任何值.
我不希望为此(或XML)使用专用存储过程,但如果有一些特定于SQL Server 2008的优雅方式,我对此持开放态度.
我有一个存储过程InsertCars,它接受用户定义的表类型列表CarType.
CREATE TYPE dbo.CarType
AS TABLE
(
CARID int null,
CARNAME varchar(800) not null,
);
CREATE PROCEDURE dbo.InsertCars
@Cars AS CarType READONLY
AS
-- RETURN COUNT OF INSERTED ROWS
END
Run Code Online (Sandbox Code Playgroud)
我需要从Dapper调用这个存储过程.我用Google搜索并找到了一些解决方案.
var param = new DynamicParameters(new{CARID= 66, CARNAME= "Volvo"});
var result = con.Query("InsertCars", param, commandType: CommandType.StoredProcedure);
Run Code Online (Sandbox Code Playgroud)
但是我收到一个错误:
过程或函数InsertCars指定了太多参数
存储过程也InsertCars返回插入行的计数; 我需要得到这个值.
问题的根源在哪里?
我的问题是我在通用列表中有汽车List<Car> Cars,我希望将此列表传递给存储过程.它优雅的方式存在怎么办?
public class Car
{
public CarId { get; set; }
public CarName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助
EDITED …
我有一个过程,它接受一个表值参数,以及其他:
CREATE PROCEDURE [dbo].[Update_Records]
@currentYear INT,
@country INT,
@records Record_Table_Type READONLY
AS
Run Code Online (Sandbox Code Playgroud)
我试图用Dapper.TVP来称呼它.
这是我到目前为止的代码:
var recordsParameter = new List<SqlDataRecord>();
// This metadata matches 'Record_Table_Type' in the Database
var recordsMetaData = new[]
{
new SqlMetaData("OriginalValue", SqlDbType.Decimal, 19, 4),
new SqlMetaData("NewValue", SqlDbType.Decimal, 19, 4),
new SqlMetaData("NewPercent", SqlDbType.Decimal, 7, 2),
};
foreach (var r in records)
{
var record = new SqlDataRecord(recordsMetaData);
record.SetDecimal(0, r.OriginalValue);
record.SetDecimal(1, r.NewValue);
record.SetDecimal(2, r.NewPercent);
recordsParameter.Add(record);
}
var spParams = new DynamicParameters(new
{
currentYear = filter.currentYear,
country = filter.country,
}); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Dapper支持我的服务器应用程序的数据访问.
我的服务器应用程序有另一个应用程序,它以每分钟400的速度将记录丢入我的数据库.
我的应用程序将它们分批拉出,处理它们,然后从数据库中删除它们.
由于数据在我处理时继续流入数据库,因此我没有好的方法可以说delete from myTable where allProcessed = true.
但是,我确实知道要删除的行的PK值.所以我想做一个delete from myTable where Id in @listToDelete
问题是,如果我的服务器停机甚至6分钟,那么我有超过2100行要删除.
由于Dapper接受我的@listToDelete并将每个变成一个参数,我对delete的调用失败了.(导致我的数据清除进一步落后.)
在Dapper处理这个问题的最佳方法是什么?
注意:我已经查看了Tabled Valued Parameters,但从我所看到的情况来看,它们并不是非常高效.这段我的建筑是我系统的瓶颈,我需要非常快.
我试图创建一个通用方法,该方法可以在运行时从类中读取参数名称和值,并为Dapper查询执行创建参数集合。意识到直到所有参数都是输入类型为止,它都能很好地工作,但是如果我必须添加Output / ReturnValue类型参数,则需要使用DynamicParameters,否则我将无法获取Output / ReturnValue参数的值
SP具有以下参数:
PersonList - TableValued - Input
TestOutput - Int - Output
Run Code Online (Sandbox Code Playgroud)
我无法使以下代码起作用:
var dynamicParameters = new DynamicParameters();
dynamicParameters.Add("PersonList", <DataTable PersonList>);
dynamicParameters.Add("TestOutput", 0, Dbtype.Int32, ParameterDirection.Output);
Run Code Online (Sandbox Code Playgroud)
例外是:
System.Data.SqlClient.SqlException:传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数1(“ @PersonList”):数据类型0x62(sql_variant)的类型特定元数据的类型无效。
据我了解,问题是没有有效的DbType可用于向动态参数添加TVP,因为我没有使用SqlDbType,因此DbType中没有替代SqlDbType.Structured的内容。
解决问题的任何指针或解决方法
在尝试通过Dapper将表作为参数传递给存储过程时,我遇到了这个SO答案,这表明它在Dapper中直接受支持.
但是在dotnet核心中,DataTable似乎没有实现,所以这不起作用.
是否有另一种简单的方法可以使用Dapper将自定义/用户定义的表作为参数传递给存储过程?
我试图调用一个接受表值参数的存储过程。
我正在遵循有关此问题的指南,实现自定义参数类型:
internal class IntDynamicParam
{
string name;
IEnumerable<int> numbers;
public IntDynamicParam(string name,IEnumerable<int> numbers)
{
this.name = name;
this.numbers = numbers;
}
public void AddParameters(IDbCommand command)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
// Create an SqlMetaData object that describes our table type.
Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };
foreach (int n in numbers)
{
// Create a new record, using the metadata array above.
Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition); …Run Code Online (Sandbox Code Playgroud) 我需要导入多个sql server关系表中的数百万条记录。
TableA(Aid(pk),Name,Color)----return id using scope identity
TableB(Bid,Aid(fk),Name)---Here we need to insert Aid(pk) which we got using scocpe Identity
Run Code Online (Sandbox Code Playgroud)
如何在一个 Insert 语句中使用 dapper 批量插入数百万条记录的集合