SQL选择IN子句

时间:2012-09-15 16:37:11

标签: sql sql-server sql-server-2008

这是我想要完成的一个例子。

declare @MenuIDs varchar(max) = '1,2,3,4';

SELECT 
    tMenuMain.MenuId, 
    tMenuMain.MenuRank 
INTO #TempRankTable 
FROM tMenuMain 
WHERE tMenuMain.MenuId IN (@MenuIDs);

select * from  #TempRankTable;                      

@MenuIDs变量实际上是一个sproc参数。 (我只是在例子中说明了解释)

如何使select工作,因为IN命令仅适用于逗号分隔值而不仅仅是字符串。我面临的其他问题是tMenuMain.MenuId是一个整数列。在这种情况下是否可以进行CAST?

3 个答案:

答案 0 :(得分:2)

您可以声明一个小的帮助函数,将字符串“映射”到表中;

CREATE FUNCTION dbo.str2ints(@str nvarchar(max))
RETURNS @ints TABLE (val INT)
AS
BEGIN
  DECLARE @xml XML
  SET @xml = '<root><str>' + REPLACE(@str, ',', '</str><str>') + '</str></root>'
  INSERT INTO @ints(val)
  SELECT str.value('.', 'int') 
  FROM @xml.nodes('//str') AS RECORDS(str)
  RETURN
END

然后你可以重写你的函数来使用该函数进行拆分;

declare @MenuIDs varchar(max) = '1,2,3,4';

SELECT 
    tMenuMain.MenuId, 
    tMenuMain.MenuRank 
INTO #TempRankTable 
FROM tMenuMain 
WHERE tMenuMain.MenuId IN (SELECT * FROM dbo.str2ints(@MenuIDs));

select * from  #TempRankTable;   

答案 1 :(得分:1)

您必须使用动态SQL并查看:

declare @MenuIDs varchar(max) = '1,2,3,4';
declare @SQL varchar(max);

set @SQL = 'create view vTab as
            SELECT tMenuMain.MenuId, tMenuMain.MenuRank                 
            FROM tMenuMain 
            WHERE tMenuMain.MenuId IN ('+@MenuIDs+')';
/*
   Select in @SQL should look like:
            create view vTab as
            SELECT tMenuMain.MenuId, tMenuMain.MenuRank                 
            FROM tMenuMain 
            WHERE tMenuMain.MenuId IN (1,2,3,4)
*/

exec(@SQL)

select * 
into #TempRankTable 
from vTab 

drop view vTab   

select * from  #TempRankTable; 

或者如果您在插入

之前可以create table
 declare @MenuIDs varchar(max) = '1,2,3,4';
 declare @SQL varchar(max);

 create table #TempRankTable 
 (
   MenuId ...
   MenuRank ...
 ) 

set @SQL = 'insert into #TempRankTable(MenuId,MenuRank) 
            SELECT tMenuMain.MenuId, tMenuMain.MenuRank                 
            FROM tMenuMain 
            WHERE tMenuMain.MenuId IN ('+@MenuIDs+')';
/*
   Select in @SQL should look like:
            insert into #TempRankTable(MenuId,MenuRank) 
            SELECT tMenuMain.MenuId, tMenuMain.MenuRank                 
            FROM tMenuMain 
            WHERE tMenuMain.MenuId IN (1,2,3,4)
*/

exec(@SQL)

select * from  #TempRankTable; 

答案 2 :(得分:0)

有一种简单而干净的方式来做你想做的事。以下问题包含许多变通方法,例如,使用XML或分割值的本地函数:

一个丑陋但容易的替代方法是使用CHARINDEX方法验证',' + tMenuMain.MenuId + ','中是否包含,1,2,3,4,(请注意起始和尾随逗号)。