2012-04-23 5 views
3

У меня есть таблица, которая имеет столбец «Faktor» (VARCHAR (50)), который содержит такие выражения, как:Преобразовать строку с выражением в десятичную

1/3 
2*9/5 
0.567 
0.23 

Нет, я ищу способ, чтобы выполнить отборное как

select Faktor from Artikel 

, который должен возвращать столбец типа десятичного со значениями

0.333333 
3.6 
0.567 
0.23 

ответ

4

Я бы с CLR, что-то вроде этого (это имеет преимущество работы в SET операции на основе, тогда как альтернативные варианты динамического SQL (т.е. Abduls ответ) не будет):

EDIT: Исходный код для DLL CLR (Visual Studio 2008) размещена здесь: http://www.heavencore.co.uk/filehub/uploaded/EvalFunction.zip

Если вы предпочитаете скомпилировать сборку самостоятельно, вот код:

Imports System 
Imports System.Data 
Imports System.Data.SqlClient 
Imports System.Data.SqlTypes 
Imports Microsoft.SqlServer.Server 
Imports System.Runtime.InteropServices  

Partial Public Class UserDefinedFunctions 
    <Microsoft.SqlServer.Server.SqlFunction()> _ 
    Public Shared Function EVAL(ByVal InputExpression As SqlString) As SqlDecimal 
     Return Evaluate(InputExpression) 
    End Function 

    Private Shared Function Evaluate(ByVal expression As SqlString) As SqlDecimal 
     Dim expressionStr As String = expression.ToString() 
     Dim loDataTable = New DataTable() 
     Dim loDataColumn = New DataColumn("Eval", GetType(Double), expressionStr) 
     loDataTable.Columns.Add(loDataColumn) 
     loDataTable.Rows.Add(0) 
     Return ParseDecimal(loDataTable.Rows(0)("Eval").ToString(), 0) 
    End Function 

    Public Shared Function ParseDecimal(ByVal InputStr As String, Optional ByVal ReturnIfFail As Decimal = 0) As Decimal 
     Dim ParseOutput As Decimal = 0 
     If Decimal.TryParse(InputStr, ParseOutput) = False Then 
      Return ReturnIfFail 
     Else 
      Return ParseOutput 
     End If 
    End Function 
End Class 

после установки и оценка вы могли бы сделать это:

SELECT Faktor, dbo.Eval(Faktor) as Result FROM Artikel 

Edit: Хорошо, я только что проверил это и она отлично работает в операциях на основе набора и т.д., установка была выполнена следующим образом:

-- Enable the CLR to run user-defined functions 
EXEC sp_configure 
    'clr enabled' , 
    '1' 
GO 
RECONFIGURE 
GO 

-- Set the appropriate database security permission 
ALTER DATABASE [TargetDatabase] SET TRUSTWORTHY ON 
GO 

-- Import the assembly 
CREATE ASSEMBLY EvalFunction 
FROM 'C:\bin\EvalFunction.dll' 
WITH PERMISSION_SET = EXTERNAL_ACCESS; 
GO 

-- Create the Eval function for easy use 
CREATE FUNCTION dbo.Eval 
    (
     @Expression NVARCHAR(255) 
    ) 
RETURNS DECIMAL(18, 2) 
AS EXTERNAL NAME 
    EvalFunction.[EvalFunction.UserDefinedFunctions].EVAL 
GO 
+0

Большое спасибо за ваш образец. Я сделал все ваши шаги успешно. Но когда я пытаюсь выполнить SQL-Select, я получаю зависание Исключение: System.IO.FileLoadException: Die Datei oder Assembly «pp.sqlserver.library, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null» oder eine Abhängigkeit davon wurde nicht gefunden. Der angegebene Assemblyname oder die Codebasis ist ungültig. (Ausnahme von HRESULT: 0x80131047) System.IO.FileLoadException – BennoDual

+0

Мой немецкий isnt отлично, но похоже, что сборка не может быть найдена? вы уверены, что установили правильную базу данных? – HeavenCore

+0

Да - я использовал ваш запрос - я добавил «использовать [PPSystem_DOS]» в начале. Когда я смотрю в Management Studio, сборка отображается в правильной базе данных. Я спрашиваю, почему он не показывает версию-информацию в Exception (вместо 0.0.0.0) - моя сборка имеет версию. – BennoDual

0

Вы можете использовать выполнить ул чтобы компилировать строку в результат представленного выражения или вы оцениваете выражение в своем приложении.

+0

Можете ли вы дать мне пример, как это сделать? – BennoDual

3

слишком плохо. В выражении все числа: int Тип данных. Поэтому его сложно вычислить и показать результат в decimal.

Вот пример, надеюсь, что он будет Помощь-

declare @expr nvarchar(10) 
set @expr='2*9/5' 
declare @query varchar(800) 

BEGIN TRY 
    SELECT CAST(@expr as decimal(5,2)) 
END TRY 
BEGIN CATCH 
    SET @query='SELECT CAST('[email protected]+'.0 as decimal(5,2))' 
    EXECUTE(@query) 
END CATCH