我正在以复杂的方式做的逻辑。
我只需要在存储过程中执行此查询:
select Sizes, SUM(Quantity)
from tbl_SizeBreakup
where (Brand=@brand)
and (Combo in ('1','2')) ...
组件我必须在C#中使用SQL参数传递
DataSet dt = new DataSet();
cmd = new SqlCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "sp_Accessories";
cmd.Connection = con;
cmd.Parameters.AddRange(
new SqlParameter[] {
new SqlParameter("@Mode",mode),
new SqlParameter("@Combo",combo),
}}
所以,如果我传递1个参数,按预期工作。我应该传递的组合是string[]
(字符串数组)。数组长度可以取决于用户在UI中选择的任何内容。
我的问题是,如何将string[]
传递给new SqlParameter("@Combo",combo)
?
我的存储过程..
ALTER proc [dbo].[sp_Accessories]
(
@Mode varchar(50)=null,
@id int=null,
@brand varchar(50)=null,
@department varchar(MAX)=null,
@season varchar(50)=null,
@groupname varchar(MAX)=null,
@styles varchar(50)=null,
@combo varchar(50)=null,
@combo_color nvarchar(max)=null,
)
as
if @Mode='getsizewise'
begin
select Sizes,SUM(Quantity) from tbl_SizeBreakup where (Brand=@brand) and (Department=@department) and (Season=@season) and (Group_Name=@groupname) and (Style=@styles)
and (Combo_Color=@color) and (Total_Add_Qty='Total Quantity') Group By Sizes
end
答案 0 :(得分:6)
简介:尽管OP已经接受了答案,但我认为分享我的经验会更好,因为我相信我要展示的方法比那个更好。接受。
我发现将数组传递给sql server数据库的最佳方法是使用user defined table type
和c#DataTable
。
在您的情况下,因为您想传递一个维度的字符串数组,所以很容易:
首先,您需要在数据库中创建用户定义的表类型:
CREATE TYPE dbo.StringArray As Table (
StringItem varchar(50) -- you can use any length suited for your needs
)
然后你需要在c#代码中创建一个数据表:
DataTable dt = new DataTable();
dt.Columns.Add("StringItem", typeof(System.String));
然后更改存储过程以接受此数据类型作为参数:
ALTER proc [dbo].[sp_Accessories]
(
@Mode varchar(50)=null,
@id int=null,
@brand varchar(50)=null,
@department varchar(MAX)=null,
@season varchar(50)=null,
@groupname varchar(MAX)=null,
@styles varchar(50)=null,
@combo dbo.StringArray Readonly=null, -- NOTE THIS CHANGE
@combo_color nvarchar(max)=null,
)
as
if @Mode='getsizewise'
begin
select Sizes,SUM(Quantity) from tbl_SizeBreakup where (Brand=@brand) and
(Department=@department) and (Season=@season) and (Group_Name=@groupname) and (Style=@styles)
and (Combo_Color=@color) and (Total_Add_Qty='Total Quantity')
and comboColumn in(select StringItem from @Combo) -- NOTE THIS CHANGE
Group By Sizes
end
然后,您需要将字符串数组转换为c#代码中的dataTable。
foreach (string s in YourStringArray) {
string[] temp = {s};
dt.Rows.Add(temp);
}
将DataTable作为参数添加到存储过程:
System.Data.SqlClient.SqlParameter sp = new Data.SqlClient.SqlParameter();
sp.SqlDbType = SqlDbType.Structured;
sp.Value = dt;
sp.ParameterName = "@Combo";
cmd.Parameters.Add(sp);
构建并运行。
这种方法应该具有更好的性能,然后使用sql用户定义的函数,也可以用于不同的数据类型。这是使用它的最佳理由之一: 考虑一个需要传递Dates数组的场景:csv方法需要sql将每个字符串转换为日期,而使用这种方法,您可以简单地按日期传递日期,而不将它们转换为字符串然后再转换为日期。此外,您可以传递2维数组或字典,您只需在sql数据库中创建适当的用户定义数据类型。
注意:此处直接编写代码,可能会有一些拼写错误。
答案 1 :(得分:1)
你可以在csv中传递一个列表(昏迷分隔值):' 1,2,3',SP中的这个字符串是没用的,但你可以转换成一个表,首先创建这个函数:
CREATE FUNCTION fun_CSV_to_Table
(
@pcsvList varchar(max)
)
RETURNS @tableWithValues table(theColumn varchar(100))
AS
BEGIN
DECLARE @pos INT
WHILE CHARINDEX(',', @pcsvList) > 0
BEGIN
SELECT @pos = CHARINDEX(',', @pcsvList)
INSERT INTO @tableWithValues
SELECT LTRIM(RTRIM(SUBSTRING(@pcsvList, 1, @pos-1)))
SELECT @pcsvList = SUBSTRING(@pcsvList, @pos+1, LEN(@pcsvList)-@pos)
END
--Insert the last value.
INSERT INTO @tableWithValues SELECT @pcsvList
RETURN
END
GO
然后你可以使用它:
SELECT SIZES, SUM(QUANTITY)
FROM TBL_SIZEBREAKUP
WHERE BRAND=@BRAND
AND COMBO IN (select theColumn FROM dbo.fun_CSV_to_Table(@aList))
/* @aList must be a csv: '1,2,3,...,n' */
你应该关心白色空间。
答案 2 :(得分:-1)
您可以使用Parameters.AddWithValues
(已更新):
DataSet dt = new DataSet();
cmd = new SqlCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "sp_Accessories";
cmd.Connection = con;
var parameterList = new StringBuilder();
for (int i = 0; i < items.Length; i++)
{
parameterList.Append(items[i] + ",");
}
var parameters= parameters.ToString().TrimEnd(',');
cmd.Parameters.AddWithValue("@Combo", parameters);
cmd.Parameters.AddRange(
new SqlParameter[] {
new SqlParameter("@Mode",mode),
}}