2014-04-30 8 views
1

날짜와 숫자가 변환되는 방식을 더 제어해야하므로 내장 된 'TRY_CONVERT'SQL 함수를 바꾸기 위해 자체 CLR 함수를 작성하려고합니다 (예 : 내장 함수는 과학적 표기법을 포함하는 DECIMAL 변환을 처리).TRY_CONVERT를 대체 할 SQL CLR 함수

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static object TRY_CONVERT(SqlDbType type, SqlString input) 
{ 
    switch (type) 
    { 
     case SqlDbType.Decimal: 
      decimal decimalOutput; 
      return decimal.TryParse(input.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalOutput) ? decimalOutput : (decimal?)null; 
     case SqlDbType.BigInt: 
      long bigIntOutput; 
      return long.TryParse(input.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bigIntOutput) ? bigIntOutput : (long?)null; 
     case SqlDbType.Date: 
     case SqlDbType.DateTime: 
     case SqlDbType.DateTime2: 
      DateTime dateTimeOutput; 
      return DateTime.TryParse(input.Value, CultureInfo.CreateSpecificCulture("en-GB"), DateTimeStyles.None, out dateTimeOutput) ? dateTimeOutput : (DateTime?)null; 
     case SqlDbType.NVarChar: 
     case SqlDbType.VarChar: 
      return string.IsNullOrWhiteSpace(input.Value) ? null : input.Value; 
     default: 
      throw new NotImplementedException(); 
    } 
} 

을하지만 빌드 할 때 그것은 SqlDbType 유형을 좋아하지 않는다 :

나는이 시도했다.

내장 함수에서 사용 된 'target_type'을 전달할 수 있습니까, 아니면 문자열로 전달하거나 사용할 각 유형에 대해 별도의 TRY_CONVERT 메소드를 만들어야합니까?

답변

2

object 반환 형식이 sql_variant로 변환 그래서 내가이 문제를 해결하는 유일한 방법은 다음과 같이 올바른 반환 유형이 별도의 CLR 방법을 만들 생각 SQL에서 올바른 데이터 형식으로 명시 적으로 변환되어야 할 것이다 :

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static SqlDecimal TRY_CONVERT_DECIMAL(SqlString input) 
{ 
    decimal decimalOutput; 
    return !input.IsNull && decimal.TryParse(input.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalOutput) ? decimalOutput : SqlDecimal.Null; 
} 

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static SqlInt64 TRY_CONVERT_BIGINT(SqlString input) 
{ 
    long bigIntOutput; 
    return !input.IsNull && long.TryParse(input.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bigIntOutput) ? bigIntOutput : SqlInt64.Null; 
} 

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static SqlDateTime TRY_CONVERT_DATE(SqlString input) 
{ 
    var minSqlDateTime = new DateTime(1753, 1, 1, 0, 0, 0, 0); 
    var maxSqlDateTime = new DateTime(9999, 12, 31, 23, 59, 59, 0); 
    DateTime dateTimeOutput; 
    return !input.IsNull && DateTime.TryParse(input.Value, CultureInfo.CreateSpecificCulture("en-GB"), DateTimeStyles.None, out dateTimeOutput) && 
     dateTimeOutput >= minSqlDateTime && dateTimeOutput <= maxSqlDateTime ? dateTimeOutput : SqlDateTime.Null; 
} 

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static SqlString TRY_CONVERT_NVARCHAR(SqlString input) 
{ 
    return input.IsNull || string.IsNullOrWhiteSpace(input.Value) ? SqlString.Null : input.Value; 
} 
+0

나는 이것이 최선의 방법이라는 데 동의합니다. SQLCLR API는 오버로드를 허용하지 않으므로 실제로 선택의 여지가 거의 없습니다. 'object' /'SQL_VARIANT'를 사용하는 것은 최소한 목표 데이터 유형이 많든 적든간에 명확한 성능 패널티가 있다는 점에서 문제가 있습니다. –