[SQL] DECIMAL에 VARCHAR
SQLDECIMAL에 VARCHAR
나는 진수 (10,4)에 VARCHAR (최대) 열을 변환 할.
내가 사용하는 캐스트를 시도하거나 변환 할 때 나는 산술 오버플로 예외를 얻고있다. 문제는 varchar 열 내에 저장된 데이터는 상이한 정밀도 다른 척도를 포함 할 수 있다는 것이다. 예를 들어, 123456789.1234567 ', 1.12345678 또는 123456.1234.
123456.1234 같은 값의 경우는 어떤 문제를 밖으로 변환되어 있지만 다른 값에 대한 좀 문제가 있어요.
어떤 도움을 주시면 감사하겠습니다.
해결법
-
==============================
1.나는 그것이 문제의 원인이 된 소수의 장소가 아니다 것을 발견 테스트 후에이었다 정밀도 (10)
나는 그것이 문제의 원인이 된 소수의 장소가 아니다 것을 발견 테스트 후에이었다 정밀도 (10)
이것은 작동하지 않습니다 : 산술 오버플로 오류가 데이터 형식의 숫자에 VARCHAR로 변환.
DECLARE @TestConvert VARCHAR(MAX) = '123456789.12343594' SELECT CAST(@TestConvert AS DECIMAL(10, 4))
이 일
DECLARE @TestConvert VARCHAR(MAX) = '123456789.12343594' SELECT CAST(@TestConvert AS DECIMAL(18, 4))
-
==============================
2.내 설명은 코드입니다. :)
내 설명은 코드입니다. :)
DECLARE @TestConvert VARCHAR(MAX) = '123456789.1234567' BEGIN TRY SELECT CAST(@TestConvert AS DECIMAL(10, 4)) END TRY BEGIN CATCH SELECT 'The reason you get the message "' + ERROR_MESSAGE() + '" is because DECIMAL(10, 4) only allows for 4 numbers after the decimal.' END CATCH -- Here's one way to truncate the string to a castable value. SELECT CAST(LEFT(@TestConvert, (CHARINDEX('.', @TestConvert, 1) + 4)) AS DECIMAL(14, 4)) -- If you noticed, I changed it to DECIMAL(14, 4) instead of DECIMAL(10, 4) That's because this number has 14 digits, as proven below. -- Read this for a better explanation as to what precision, scale and length mean: http://msdn.microsoft.com/en-us/library/ms190476(v=sql.105).aspx SELECT LEN(LEFT(@TestConvert, (CHARINDEX('.', @TestConvert, 1) + 4)))
-
==============================
3.당신은 6.999,50이 유효한 진수 아니라는 사실을 누락되었습니다. 쉼표 확실 진수 값의 소수점을 가질 수 없습니다? 어떤 숫자 것은이 있어야하는데?
당신은 6.999,50이 유효한 진수 아니라는 사실을 누락되었습니다. 쉼표 확실 진수 값의 소수점을 가질 수 없습니다? 어떤 숫자 것은이 있어야하는데?
로케일 지정 가정. 로 소수 구분 기호로, 그룹화 : 그룹화 자리를 제거하려면 :
SELECT CONVERT (십진수 (11,2), REPLACE ( '6.999,50', '.', ''))
소수로 6999,50을 얻을 것입니다
-
==============================
4.나는 다음과 같은 해결책을했다 :
나는 다음과 같은 해결책을했다 :
SELECT [Str], DecimalParsed = CASE WHEN ISNUMERIC([Str]) = 1 AND CHARINDEX('.', [Str])=0 AND LEN(REPLACE(REPLACE([Str], '-', ''), '+', '')) < 29 THEN CONVERT(decimal(38,10), [Str]) WHEN ISNUMERIC([Str]) = 1 AND (CHARINDEX('.', [Str])!=0 AND CHARINDEX('.', REPLACE(REPLACE([Str], '-', ''), '+', ''))<=29) THEN CONVERT(decimal(38,10), CASE WHEN LEN([Str]) - LEN(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([Str], '0', ''), '1', ''), '2', ''), '3', ''), '4', ''), '5', ''), '6', ''), '7', ''), '8', ''), '9', '')) <= 38 THEN [Str] ELSE SUBSTRING([Str], 1, 38 + LEN(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([Str], '0', ''), '1', ''), '2', ''), '3', ''), '4', ''), '5', ''), '6', ''), '7', ''), '8', ''), '9', ''))) END) ELSE NULL END FROM TestStrToDecimal
나는 그것이 잔인한 것 같습니다 아마도 그것이 알고 있지만, 그것은 나를 위해 작동 (다른 정밀도와 규모 모두 긍정적, 부정적, 크고 작은 번호를 확인 - 모든 것이 진수 (38,10) 또는 NULL로 변환된다).
당신이 다른 정밀도를 필요로하는 코드 (38, 10, 29)에 상수를 변경 그렇다면, 진수 (38,10) 유형에 하드 코딩되어있다.
그것은 어떻게 작동 하는가? 결과는 다음과 같습니다
각각의 경우는 위의 코드에서 언제 문 별개입니다.
다음은 변환의 몇 가지 예입니다 :
-
==============================
5.당신은 당신이 칼럼에 넣어 전에 문자열로 값을 직접 절단해야 할 것입니다.
당신은 당신이 칼럼에 넣어 전에 문자열로 값을 직접 절단해야 할 것입니다.
당신이 더 많은 소수 자릿수를 원하는 경우 그렇지 않으면, 당신은 소수점 열 당신의 선언을 변경해야합니다.
-
==============================
6.당신은 플로트 데이터 형식을 사용할 수없는 이유 당신은 아직 설명하지 않은, 그래서 여기에 예입니다 :
당신은 플로트 데이터 형식을 사용할 수없는 이유 당신은 아직 설명하지 않은, 그래서 여기에 예입니다 :
DECLARE @StringVal varchar(50) SET @StringVal = '123456789.1234567' SELECT @StringVal, CAST(@StringVal AS FLOAT) SET @StringVal = '1.12345678' SELECT @StringVal, CAST(@StringVal AS FLOAT) SET @StringVal = '123456.1234' SELECT @StringVal, CAST(@StringVal AS FLOAT)
-
==============================
7.귀하의 주요 문제는 소수의 오른쪽에 물건 아니라, 왼쪽으로 물건입니다. 당신의 유형 선언에서 두 값은 정밀도와 스케일입니다.
귀하의 주요 문제는 소수의 오른쪽에 물건 아니라, 왼쪽으로 물건입니다. 당신의 유형 선언에서 두 값은 정밀도와 스케일입니다.
당신이 (10, 4)를 지정하면, 그 수단은 당신은 단지 소수, 또는 999999.9999의 최대 숫자의 왼쪽에 6 개 자리를 저장할 수 있습니다. 보다 더 큰 아무거나는 오버 플로우가 발생합니다.
-
==============================
8.사용자 정의 기능을 사용하여 구현됩니다. 문자열 값 안전하게 진수로 변환 할 수 있는지 여부를이 확인합니다
사용자 정의 기능을 사용하여 구현됩니다. 문자열 값 안전하게 진수로 변환 할 수 있는지 여부를이 확인합니다
CREATE FUNCTION [dbo].[TryParseAsDecimal] ( @Value NVARCHAR(4000) ,@Precision INT ,@Scale INT ) RETURNS BIT AS BEGIN IF(ISNUMERIC(@Value) =0) BEGIN RETURN CAST(0 AS BIT) END SELECT @Value = REPLACE(@Value,',','') --Removes the comma --This function validates only the first part eg '1234567.8901111111' --It validates only the values before the '.' ie '1234567.' DECLARE @Index INT DECLARE @Part1Length INT DECLARE @Part1 VARCHAR(4000) SELECT @Index = CHARINDEX('.', @Value, 0) IF (@Index>0) BEGIN --If decimal places, extract the left part only and cast it to avoid leading zeros (eg.'0000000001' => '1') SELECT @Part1 =LEFT(@Value, @Index-1); SELECT @Part1=SUBSTRING(@Part1, PATINDEX('%[^0]%', @Part1+'.'), LEN(@Part1)); SELECT @Part1Length = LEN(@Part1); END ELSE BEGIN SELECT @Part1 =CAST(@Value AS DECIMAL); SELECT @Part1Length= LEN(@Part1) END IF (@Part1Length > (@Precision-@Scale)) BEGIN RETURN CAST(0 AS BIT) END RETURN CAST(1 AS BIT) END
-
==============================
9.나는이 오래된 질문 알아요,하지만 빌은 실제로 문제를 "설명"한 유일한 것 같다. 모두가 다른 선언의 오용 복잡한 솔루션으로 올라오고있는 것 같다.
나는이 오래된 질문 알아요,하지만 빌은 실제로 문제를 "설명"한 유일한 것 같다. 모두가 다른 선언의 오용 복잡한 솔루션으로 올라오고있는 것 같다.
...
당신이 DECIMAL (10,4)를 선언하는 경우 그래서 당신은 그들 중 4 소수점 후에 오는 10 개 숫자의 총을 가질 수 있습니다. 그래서 123456.1234 10 자리 소수점 후 4를 갖는다. 즉, 소수의 매개 변수 (10,4)에 맞는. 1234567.1234 오류가 발생합니다. 착용감이 11 진수 10 자릿수의 공간으로하고, 4 개 자리가 소수점하여 사용되어야한다. 소수의 왼쪽에 떨어져 자리를 트리밍 옵션을 선택하지 않습니다. 당신의 11 개 문자 123456.12345가 있다면, 이것은 진수 값의 끝에서 (반올림)를 트리밍으로 오류가 발생하지 않을 것은 허용됩니다.
소수를 선언 할 때, 항상 열이 현실적으로 사용할 수있는 최대 당신이보고 싶은 소수 자릿수의 최대 수를 선언하려고합니다. 그래서 열은 오직 1 백만의 최대 값을 표시 할 경우에만 DECIMAL로, 처음 두 소수점에 대해 (9,2)를 선언 신경. 오류가 발생하기 전에 이렇게하면 9,999,999.99의 최대 수를 줄 것이다.
당신이 그것을 해결하기 전에 문제를 이해, 당신은 당신의 상황에 맞는 수정을 선택 보장합니다, 도움 당신은 수정이 / 작품을 필요로하는 이유를 이해할 수 있습니다.
다시 말하지만, 나는 5 년 늦게 파티에이야 알고있다. 그러나, 이것에 대한 해결책을 내 두 센트 (열이 이미 DECIMAL (10,4로 설정) 변경 될 질수 귀하의 의견에 의해 판단) 가장 쉬운 방법은 두 가지 단계가 될 것이라고 할 수 있습니다. 다음 10 자리 트림, 당신의 진수 멀리 10 점보다 더하지 있는지 확인합니다.
CASE WHEN CHARINDEX('.',CONVERT(VARCHAR(50),[columnName]))>10 THEN 'DealWithIt' ELSE LEFT(CONVERT(VARCHAR(50),[columnName]),10) END AS [10PointDecimalString]
당신은 이상 10 자리, 소수의 왼쪽에있는 값으로 처리 할 수 있도록 내가 문자열로이 왼쪽 이유입니다.
그러나 자사의 시작.
-
==============================
10.혹시 ROUND에 결과가 아니라 잘라 내기 필요, 이것을 사용할 수 있습니다 :
혹시 ROUND에 결과가 아니라 잘라 내기 필요, 이것을 사용할 수 있습니다 :
select convert(decimal(38,4), round(convert(decimal(38,10), '123456789.1234567'),4))
이것은 다음을 반환합니다 :
'123456789.1235' for '123456789.1234567' '123456789.1234' for '123456789.1234467'
from https://stackoverflow.com/questions/11089125/varchar-to-decimal by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 2005 SQL Server에서 데이터베이스의 기본 스키마를 설정하는 방법? (0) | 2020.07.09 |
---|---|
[SQL] "절"평가 순서를 선택합니다 (0) | 2020.07.09 |
[SQL] 하나 개의 레코드로 쿼리를 제한하면 성능을 향상합니까 (0) | 2020.07.09 |
[SQL] GROUP BY 후 연결하여 하나의 필드 (0) | 2020.07.09 |
[SQL] 바로 단어를 검색 MYSQL | 철자 오류를 수정 (0) | 2020.07.09 |