2017-09-11 12 views
1

처음에 게시 할 코드의 양을 유감스럽게 생각합니다! :(그러나 저는 붙어 있습니다. 많은 일을 시도했지만 아무 것도 작동하지 않는 것 같습니다. 오류가 어디에 있는지 정말로 알지 못합니다 ...SUBSTRING을 (를) 사용하는 길이 매개 변수 오류가 잘못되었습니다.

이 함수의 기능에 대해 설명하겠습니다. 사용자 정의 형식을 단 몇 초 만에 알 수 있습니다. 자세한 내용을 보려면이 값이 맥박 조정기에서 감지 된 부정맥 에피소드의 지속 시간을 나타냅니다. 예를 들어 지속 시간이 2 분 35 초인 경우 사용자 지정 형식은 'PT2M35S'

내 함수 (원래 VBA에서 생성되었지만 현재 SQL Server로 마이그레이션하려고 시도 함)는 char에 의해 char이라는 텍스트를 읽고 char에 따라 다른 계산을 수행합니다. 코드는 SQL 함수로 변환 :

ALTER FUNCTION PTtoSeconds(@duration varchar(30)) 
RETURNS FLOAT 
AS 
BEGIN 
    DECLARE @posLetraReciente INT 
    DECLARE @hayComa INT 
    DECLARE @posComa INT 

    SET @posLetraReciente = 1 
    SET @hayComa = 0 
    SET @posComa = 0 

    DECLARE @texto VARCHAR(30) 
    SET @texto = @duration 

    DECLARE @tiempoTotal FLOAT 
    DECLARE @factorTiempo FLOAT 
    DECLARE @incremento FLOAT 

    SET @tiempoTotal = 0.0 
    SET @factorTiempo = 0 
    SET @incremento = 0 

    DECLARE @caracter VARCHAR(30) 
    DECLARE @counter INT 
    SET @counter = 1 

    DECLARE @longtexto INT 
    SET @longtexto = LEN(@duration) 

    WHILE @counter < @longtexto 
     BEGIN 
     SET @caracter = SUBSTRING(@texto,@counter, 1) 

     SET @hayComa = CASE @caracter 
       WHEN '.' THEN 1 
       ELSE 0 
       END 

     SET @factorTiempo = CASE 
        WHEN @caracter = 'D' THEN 86400 
        WHEN @caracter = 'H' THEN 3600 
        WHEN @caracter = 'M' THEN 60 
        WHEN (@caracter = 'S' AND @hayComa = 1) THEN (1/(POWER(10,(@counter - (@posComa + 1))))) 
        WHEN (@caracter = 'S' AND @hayComa = 0) THEN 1 
        WHEN @caracter = 'T' THEN 0 
        WHEN @caracter = '.' THEN 1 
        ELSE 0 
     END 

     SET @posLetraReciente = @counter 

     SET @incremento = CASE 
       WHEN @caracter = 'D' THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN @caracter = 'H' THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN @caracter = 'M' THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN (@caracter = 'S' AND @hayComa = 1) THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN (@caracter = 'S' AND @hayComa = 0) THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN @caracter = 'T' THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       WHEN @caracter = '.' THEN CAST((SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))) as FLOAT) * @factorTiempo 
       ELSE @factorTiempo 
     END 

     SET @tiempoTotal = @tiempoTotal + @incremento 
     SET @counter = @counter + 1 

    END 

    RETURN @tiempoTotal 
END 

SUBSTRING을 호출 할 때 오류가 나타납니다. 그것은 다음과 같습니다 :

Invalid length parameter passed to the LEFT or SUBSTRING function. 

그리고 나는 그것을 일으킬 수 있습니다 모르겠어요. 다른 쿼리에서 SUBSTRING을 분리하여 사용하려고 시도했습니다.

select X = SUBSTRING('PT3M44S',2,1) 

그리고 제대로 작동합니다. 이것은 아마도 @counter 변수에서 오류가 발생했음을 의미하지만 그 이유는 알 수 없습니다.

오리엔테이션을 환영합니다.

감사합니다. 나는 가능한 한 구체적으로하려고 노력했다. 내가 그렇게 생각하지 않는다면 제발 친절히 말해주세요!

이그나시오

답변

0

로직을 다시 작성해야합니다.

나는 코드에서 @posLetraReciente 검색이 발견 SET @posLetraReciente = @counter

는 그리고이 표현 @counter - (@posLetraReciente + 1)는 항상 당신에게 -1을 제공합니다.

그리고 당신이 잘못 귀하의 SUBSTRING에서 세 번째 매개 변수로이 -1을 통과

+0

맞아요! 나는 당신의 대답을 사용하려고하는 동안 그것을 발견했습니다. 좋아요, 이제는 "길이 매개 변수가 잘못되었습니다 ...""오류가 발생하지만이 함수는 다음을 호출 할 때 null 값을 반환합니다. dbo.PTtoSeconds ('PT3M44S') 선택 하지만이 질문에 대한 대답은이 스레드의 범위를 벗어날 수 있습니다. –

+0

>> > 그러나 함수는 <<<를 호출 할 때 null 값을 반환합니다. 함수에서 코드를 추출하고 함수 외부에서 실행하십시오; WHILE주기마다 모든 SET 연산 후에 PRINT 문을 추가하면 잘못된 단계를 찾는 데 도움이됩니다. – sepupic

0

문제는 코드의이 부분에 있어야합니다 :

SUBSTRING(@texto, (@posLetraReciente + 1), @counter - (@posLetraReciente + 1))

항상 다음 SET @counter = 1SET @posLetraReciente = @counter@counter - (@posLetraReciente + 1)하는 경우 줘. -1

에 말한대로 0 :

세 번째 매개 변수 길이는 반환 할 식의 문자 수를 지정하는 양의 정수 또는 bigint 식입니다. length가 음수이면 오류가 생성되고 명령문이 종료됩니다. start와 length의 합계가 expression의 문자 수보다 큰 경우 start에서 시작하는 전체 값 표현식이 반환됩니다.

+0

감사합니다! 그것을 찾았습니다. 오류가 발생하지 않았지만 기능이 제대로 작동하지 않습니다 ... 내가 할 수있는 일을 볼 수 있습니다! : D (그러나이 문제에 여전히 관심이 있다면 계속 도움을받을 수 있습니다. ... 정말 고맙겠습니다. 그러나 도움을받지 않기로 결정한 것을 이해할 것입니다!) –

+0

'@counter '(@posLetraReciente + 1)'~ (@posLetraReciente + 1) - @ counter' (당신이 원하는 길이라면 무엇을 할 것인지 모르겠다)'dbo.PTtoSeconds (PT3M44S)'선택' "240"을 반환합니다. 다음 오류가 작동하지 않는 이유를 모르겠습니다. – Ragmar