问题陈述:
@a
只有一个单词(例如'name1'
)或逗号分隔的字符串(示例'name1,name2,name3'
)时,查询应返回name1 and name2 and name3
的员工的经理姓名@a
有一个空字符串,然后返回emp_master
表中所有员工的经理姓名我已经定义了一个传递变量的存储过程。
此变量可以是逗号分隔的字符串,单个字或空字符串。
如果字符串是逗号分隔的,那么我拆分该字符串并根据split语句的返回表获取值 其他 我使用普通子查询
得到非逗号分隔数据的相关值我试图通过以下方式实现这一目标
Declare @a varchar(50)= ''
select emp.Name from
emp_master emp
where
(LEN(@a)=0 AND emp.Name in
(
SELECT DISTINCT [Name] FROM
[dbo].[Emp_Master] WHERE [EmpId] IN
(
SELECT
DISTINCT [MGR_ID]
FROM [dbo].[Emp_Master]
)
)
)
OR
emp.Name in (Select * from [dbo].[SplitString](@a, ','))
以上样本的详细信息:
[dbo]。[SplitString] - 自定义编写函数:返回拆分值表。所以
从[dbo] .SplitString
将返回
SplitTable
----------
name1
name2
name3
和
Select * from [dbo].[SplitString](',','name1')
将返回
SplitTable
----------
name1
我当前的解决方案(上面的疯狂查询)解决了我的目的,但速度非常慢,为问题获得优化且更快的工作解决方案会很有帮助
答案 0 :(得分:0)
CREATE NONCLUSTERED INDEX ix ON dbo.Emp_Master ([MGR_ID])
GO
DECLARE @a VARCHAR(50) = ''
DECLARE @t TABLE (val VARCHAR(50) PRIMARY KEY WITH(IGNORE_DUP_KEY=ON))
INSERT INTO @t
SELECT item = t.c.value('.', 'INT')
FROM (
SELECT txml = CAST('<r>' + REPLACE(@a, ',', '</r><r>') + '</r>' AS XML)
) r
CROSS APPLY txml.nodes('/r') t(c)
SELECT /*DISTINCT*/ [Name]
FROM dbo.Emp_Master e1
WHERE (
@a = ''
AND
e1.[EmpId] IN (SELECT DISTINCT MGR_ID FROM dbo.Emp_Master)
)
OR (
@a != ''
AND
e.Name IN (SELECT * FROM @t)
)
OPTION(RECOMPILE)
答案 1 :(得分:0)
尝试
CREATE NONCLUSTERED INDEX IX_MGR_ID_Emp_Master ON dbo.Emp_Master ([MGR_ID])
GO
Create Procedure searchname (@a varchar(255))
as
IF (@a = '')
BEGIN
EXEC Searchname1 @a
END
ELSE
BEGIN
EXEC Searchname2 @a
END
GO
Create Procedure Searchname1 (@a varchar(255))
AS
SELECT DISTINCT [Name] FROM
[dbo].[Emp_Master] m1 WHERE
exists
(
SELECT
*
FROM [dbo].[Emp_Master] m2
WHERE
m1.[EmpId]= m2.[MGR_ID]
)
GO
Create Procedure Searchname2 (@a varchar(max))
AS
Select @a = ' SELECT '''+replace( @a,',',''' Union ALL SELECT ''')+' '''
Create table #names (name varchar(255))
insert into #names
EXEC ( @a )
select emp.Name from
emp_master emp
WHERE
emp.Name in( Select name FRom #names)
option (recompile)
如果您已经在应用程序级别处理 SQL INJECTION THEN
ALTER procedure [dbo].[Searchname2] (@a varchar(max))
AS
select @a = ''''+replace ( @a,',',''',''')+''''
DECLARE @sql NVARCHAR(MAX) = N'
select distinct emp.Name from
emp_master emp
WHERE
emp.Name in( '+@a+')'
EXEC (@sql)