2010-12-17 2 views
9

를 사용하지 않고, INT에 쉼표로 구분 된 문자열로 변환t-SQL 내가 INT의 목록을 통과하고있어 사용자 생성 기능

즉, (쉼표로 구분). 1, 2, 3, 4

to my sp. 그러나 목록이 문자열이기 때문에 오류가 발생하며 int 필드와 비교합니다. 사용자가 만든 함수를 사용하지 않고 목록을 int로 변환 할 수있는 방법이 있습니까?

참고 : 직원 ID는 오류가

+0

어떤 버전의 SQL Server가 있습니까? 그리고 당신의 SP를 호출하는 코드를 변경할 수 있습니까? –

+0

@Damien SQL Server 2005. 예 sp를 호출하는 코드를 변경할 수 있습니다. – Kukoy

+1

쥐. 2008 년에는 테이블 값 매개 변수 사용으로 변경하는 것이 좋습니다. –

답변

8

이 목록을 int로 변환하지 않고 int 목록으로 변환합니다.

캐스트 연산자 또는 함수가 없지만 동적 SQL을 사용하여이를 처리 할 수 ​​있습니다.

은 기본적으로 당신은

EXECUTE('SELECT * FROM tbl_Employee WHERE employeeID IN ('[email protected]+')') 

그래도 SQL 주입 공격에주의 쓰기!

+3

이것은 OP가 원하는 것을 수행하는 훌륭한 기본 방법입니다. 직원 명단과 ID가 커짐에 따라 IN 문구는 점차 비효율적으로 변합니다. 2005/2008 년에는 '존재'가 선호됩니다. 또한 동적 SQL은 캐시 될 수 없으므로 실행이 다른 명령문에서와 같이 결코 빨리 수행되지 않습니다. – Brad

+0

@ 브래드 : 동적 문은 다른 것과 마찬가지로 캐시됩니다. 쿼리 텍스트를 변경하지 않는 한 캐시 된 계획이 사용됩니다. 물론 쿼리가 자주 실행되면 다른 ID 목록이 문제가됩니다. EXISTS는 검색된 ID를 저장할 임시 테이블을 필요로합니다.이자형. 사용자가 확인란을 사용하여 특정 직원을 선택할 수있는 웹 앱에서) IN은 여전히 ​​최상의 옵션입니다. – TToni

+0

나는'EXISTS'가 여기 실제적으로 실용적이지 않다는 것에 동의한다. 테이블이나'IN'리스트가 크면 선호된다고 지적하고 싶었다. SQL이 동적 SQL (각 변경 사항에 대한)에 대한 캐시 계획을 수행한다는 것을 알면 좋습니다. 그러나 쿼리가 자주 변경되므로이 캐싱은 크게 할인 될 수 있다고 생각합니다. 그렇지 않다면 동적 SQL을 사용하는 이유는 무엇입니까? – Brad

4
당신은뿐만 아니라 string int로 변환하려는

하지만 여러int들 "int로 varchar 형으로 변환 할 수 없습니다"입니다 INT

declare @intArray varchar(200) 

SELECT * 
FROM tbl_Employee 
WHERE employeeID IN (@intArray) 

입니다 하나. SELECT이 배열에 나열된 모든 직원의 ID와 ID를 반환 할 것으로 기대하십니까?

나는이 작업을 없이 수행하고 싶다는 것을 알고 있습니다. 그러나, 이것은 내가 현재 어떻게 그것을하고 그것을 잘 작동합니다. 내 대답에서 네가 할 일을 가져 가라.

이 코드는 while 루프를 사용합니다.이 루프는 SQL 2005/2008에있는 경우 반복적 인 CTE로 향상 될 수 있습니다. 함수의 출력을 INNER JOIN 테이블로 사용하면 매우 빠르게 필터링 할 수 있습니다.

/* 
************************************************************************************************************************ 
    Name:   ConvertDelimitedListIntoTable 
    Description: Converts a list of delimited values into a table for use like a dynamic IN statment 

    Modification History 
    Date  Author   Description 
    ========== ============ ==================================== 
    2009-01-31 B. Williams  Initial Creation 

************************************************************************************************************************ 
*/ 
ALTER FUNCTION [dbo].[ConvertDelimitedListIntoTable] (
    @list NVARCHAR(MAX) ,@delimiter CHAR(1)) 
RETURNS @table TABLE ( 
    item VARCHAR(255) NOT NULL) 
AS 
    BEGIN 
     DECLARE @pos INT ,@nextpos INT ,@valuelen INT 

     SELECT @pos = 0 ,@nextpos = 1 

     WHILE @nextpos > 0 
      BEGIN 
       SELECT @nextpos = CHARINDEX(@delimiter,@list,@pos + 1) 
       SELECT @valuelen = CASE WHEN @nextpos > 0 THEN @nextpos 
             ELSE LEN(@list) + 1 
            END - @pos - 1 
       INSERT @table (item) 
       VALUES (CONVERT(INT,SUBSTRING(@list,@pos + 1,@valuelen))) 
       SELECT @pos = @nextpos 

      END 

     DELETE FROM @table 
     WHERE item = '' 

     RETURN 
    END 

사용 :

DECLARE @intArray varchar(200) 

SELECT * 
FROM tbl_Employee e 
     INNER JOIN dbo.ConvertDelimitedListIntoTable(@intArray,',') arr 
       ON e.EmployeeID = arr.Item 

또한 tally 테이블과이 작업을 수행하는 빠른 방법이있을 수 있습니다.

+0

정말 대단합니다, 고마워요! –

+0

저장 프로 시저에서 첫 번째 솔루션 작업을 관리하지 못했습니다. 감사합니다. –