2014-02-26 5 views
1

내가 SQL 서버 여기에 2008SQL 서버 : 기능

를 사용하고 저장 프로 시저에 하나의 문자를 반환하는 기능 (분할 문자열과 반환 INT 값)이 방법을 사용하는 경우

USE [SANNET] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata int 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
     IF @end = 0 
      SET @end = LEN(@string) + 1 

     INSERT INTO @output (splitdata) 
     VALUES(CAST(SUBSTRING(@string, @start, @end - @start)AS int)) 
     SET @start = @end + 1 
     SET @end = CHARINDEX(@delimiter, @string, @start) 

    END 
    RETURN 
END 
GO 

모든 괜찮이다

select * from fnSplitString('65,1,2,27,28,33,34',',') 
/** 
Returning 
splitdata 
----------- 
65 
1 
2 
27 
28 
33 
34 

(7 row(s) affected) 


*/ 

그러나 내가 저장 프로 시저에서 사용하는 경우 하나의 문자 (심지어 행)

,691,363을 반환210
-- Procedure which calling the function 


CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values varchar 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
    select * from fnSplitString(@values,','); 

END 
GO 

사용

DECLARE @result int 

EXEC @result = [dbo].[CallerProcedure] 
     @values = '65,1,2,27,28,33,34' 

SELECT @result 

GO 
/* 
Returns 
splitdata 
----------- 
6 


----------- 
0 

(영향 1 행 (들)) */

는 짝수 값이 "64"이 반환되지시피

. 그냥 returnet 6.

어디에서 잘못하고 있습니까? 다음과 같이

감사

+0

시작은,'OUTPUT' 변수를 사용. – user2989408

답변

3

당신은 당신의 VARCHAR 입력 변수 @values의 길이를 정의하지 않은, 그래서 VARCHAR(1)을 디폴트됩니다 : 당신은 당신이 '65,1,2,27,28,33,34'을 통과 생각하지만

CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values varchar 

을 그래서,이 단지 '6'에 잘립니다

@Values의 선언을 VARCHAR(MAX)으로 변경하면 문제가 해결됩니다.

CREATE /*ALTER*/ PROCEDURE [dbo].[CallerProcedure] 
    @values VARCHAR(MAX) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
    select * from fnSplitString(@values,','); 

END 
GO 

Example on SQL Fiddle

로 전환, 또는 VARCHAR를 선언 할 때 당신은 은 항상의 길이를 정의해야합니다. 추가 읽기의 경우 : 값이 저장 프로 시저를 형성 반환 할 경우 Bad habits to kick : declaring VARCHAR without (length)

+0

정말 고마워요. 그것의 일했다. –

0

은 프로 시저를 수정합니다. 먼저 결과를 변수 테이블에 삽입하고 리턴하십시오. 또한 VARCHAR 필드의 크기를 설정하는 것을 잊지 마십시오.

CREATE PROCEDURE [dbo].[CallerProcedure] @values VARCHAR(MAX) 
AS 
    BEGIN 
     SET NOCOUNT ON; 

     DECLARE @MyTable AS TABLE 
     (
      value VARCHAR(20) 
     ) 

     INSERT INTO @MyTable 
     SELECT * 
      FROM fnSplitString(@values, ','); 

     SELECT * 
     FROM @MyTable 
    END 
GO