C# 如何格式化传递给存储过程的数据,以便与IN子句一起使用?
例如,假设我有以下存储过程:C# 如何格式化传递给存储过程的数据,以便与IN子句一起使用?,c#,sql-server,C#,Sql Server,例如,假设我有以下存储过程: CREATE PROCEDURE [dbo].[get_Members] @IsActive INT, @Gender VARCHAR(MAX) AS SELECT first_name, last_name, gender FROM members WHERE is_active IN (@IsActive) AND gender IN (@Gender)
CREATE PROCEDURE [dbo].[get_Members]
@IsActive INT,
@Gender VARCHAR(MAX)
AS
SELECT
first_name, last_name, gender
FROM
members
WHERE
is_active IN (@IsActive)
AND gender IN (@Gender)
GO
ArrayList lst = new ArrayList();
lst.Add(new SqlParameter("@IsActive", IsActive));
lst.Add(new SqlParameter("@Gender", Gender));
try
{
return this.ExecuteDataTable("get_Members", lst);
}
我有下面的c代码来调用这个存储过程:
CREATE PROCEDURE [dbo].[get_Members]
@IsActive INT,
@Gender VARCHAR(MAX)
AS
SELECT
first_name, last_name, gender
FROM
members
WHERE
is_active IN (@IsActive)
AND gender IN (@Gender)
GO
ArrayList lst = new ArrayList();
lst.Add(new SqlParameter("@IsActive", IsActive));
lst.Add(new SqlParameter("@Gender", Gender));
try
{
return this.ExecuteDataTable("get_Members", lst);
}
在我的表中,处于活动状态
将是一种int
类型,可接受值为1
和0
性别是一个varchar
列,可接受值为Male
,Female
,Unknown
我需要使用什么样的变量来传递IsActive
SQL参数的1,0
值,以及in
参数的Male
、Female
、Unknown
值,以便它在in
子句中正常工作
我是一个视觉学习者,所以一个视觉例子会让人惊讶。谢谢。不用iActive,因为这很容易解释:
将参数声明为DbType.Boolean
,将其.Value
设置为c#bool,服务器端的位0/1
列将正确映射为0=false
,1=true
进入您的查询:
您不能像这样将值传递给IN。如果您想将性别作为VARCHAR传递,您必须执行以下操作:
CREATE PROC [dbo].[get_Members]
@IsActive int
,@Gender varchar(max)
AS
SELECT
first_name
,last_name
,gender
FROM members
WHERE is_active IN (@IsActive)
AND @Genders LIKE CONCAT('%.', gender, '.%')
GO
需要注意的重要一点是,您的C#,想要
女性
s和未知
s,应该构建一个如下所示的字符串:
.female.unknown.
sql变成:
'.female.unknown.' LIKE '%.<gender from column>.%'
你为什么不能像以前那样做呢 因为这不起作用:
WHERE Gender IN ('female, male')
这项工作:
WHERE Gender IN ('female', 'male')
这两件事很不一样
如果您非常想在中使用,则必须有更多变量:
WHERE Gender IN (@g1, @g2, @g3)
你的c可以设置@g1='male'
,@g2='female'
,@g3='nonexistent\u或\u null\u或\u even\u male\u,如果你只想要雄性和雌性的话
我会用哪一种?
可能是后一种形式,因为如果您试图通过使用“像%column%这样的值”方法将内容硬塞进一个varchar中,则很有可能不会使用性别索引
最后说明;没有什么可以阻止您使用单个varchar参数并在过程中对其进行切割。最简单的方法是使用sqlserver 2016+和字符串分割函数:
WHERE Gender IN (
SELECT value FROM STRING_SPLIT(@Genders, '.') WHERE LEN(LTRIM(value)) > 0
)
但是如果你想的话,你可以更多地参与用子字符串等来切碎东西。我没有立即使用此选项,因为它非常具体于数据库,是否可以在服务器端轻松拆分字符串,而无需用户定义函数等(我不想编写一个在所有sql server上普遍适用的字符串,使用左/右/子字符串等)省去了IsActive,因为这很容易解释:
将参数声明为DbType.Boolean
,将其.Value
设置为c#bool,服务器端的位0/1
列将正确映射为0=false
,1=true
进入您的查询:
您不能像这样将值传递给IN。如果您想将性别作为VARCHAR传递,您必须执行以下操作:
CREATE PROC [dbo].[get_Members]
@IsActive int
,@Gender varchar(max)
AS
SELECT
first_name
,last_name
,gender
FROM members
WHERE is_active IN (@IsActive)
AND @Genders LIKE CONCAT('%.', gender, '.%')
GO
需要注意的重要一点是,您的C#,想要女性
s和未知
s,应该构建一个如下所示的字符串:
.female.unknown.
sql变成:
'.female.unknown.' LIKE '%.<gender from column>.%'
你为什么不能像以前那样做呢
因为这不起作用:
WHERE Gender IN ('female, male')
这项工作:
WHERE Gender IN ('female', 'male')
这两件事很不一样
如果您非常想在中使用,则必须有更多变量:
WHERE Gender IN (@g1, @g2, @g3)
你的c可以设置@g1='male'
,@g2='female'
,@g3='nonexistent\u或\u null\u或\u even\u male\u,如果你只想要雄性和雌性的话
我会用哪一种?
可能是后一种形式,因为如果您试图通过使用“像%column%这样的值”方法将内容硬塞进一个varchar中,则很有可能不会使用性别索引
最后说明;没有什么可以阻止您使用单个varchar参数并在过程中对其进行切割。最简单的方法是使用sqlserver 2016+和字符串分割函数:
WHERE Gender IN (
SELECT value FROM STRING_SPLIT(@Genders, '.') WHERE LEN(LTRIM(value)) > 0
)
但是如果你想的话,你可以更多地参与用子字符串等来切碎东西。我没有立即使用这个选项,因为在服务器端,没有用户定义的函数等情况下,字符串是否可以很容易地拆分(我不想编写一个在所有sql server上都普遍适用的,使用左/右/子字符串等)考虑到您只需要解析3个值,另一种方法可能是使用拆分数据。请注意,PARSENAME
如果分隔字符串中的项目超过4个,或者如果任何项目超过128个字符,则不会有帮助。文档(在编写本文时)是错误的,因为实际返回类型是sysname
,它是nvarchar(128)
的同义词
使用CONCAT
方法,就像在另一个答案中一样,将使您的查询不可搜索;这可能会有很大的性能问题。考虑到您将只解析3个值,可能会使用另一种方法来拆分数据。请注意,PARSENAME
如果分隔字符串中的项目超过4个,或者如果任何项目超过128个字符,则不会有帮助。文档(在编写本文时)是错误的,因为实际返回类型是sysname
,它是nvarchar(128)
的同义词
使用CONCAT
方法,就像在另一个答案中一样,将使您的查询不可搜索;这可能会有很大的性能问题。表值参数最好。查看表值参数将是最好的。尽管PARSENAME有点粗俗,但请看这个巧妙的把戏。。它旨在分离对表等的引用,比如“dbo.Northwind.orders”,我只会在这样一个非常狭窄的上下文中使用它;很多事情都可能以不同的方式破坏它。未来参观t