2011-02-27 37 views
0

我正在爲SQL Server 2008編寫一些自定義的.Net擴展。其中之一是用戶定義的聚合,應將一組十進制數字聚合爲十進制值。使用SQL CLR擴展(用戶定義的聚合)舍入錯誤

爲了縮小我的問題,我使用了一個簡單的Const聚合,它只是返回一個常數十進制值。將此用戶定義的聚合添加到SQL Server時,返回的值總是舍入:

SELECT dbo.Const(n, 2.5) from (select 1 n) x -- returns 3, not 2.5 

我錯過了什麼?

下面的代碼:

using System; 
using System.Data.SqlTypes; 
using System.IO; 
using Microsoft.SqlServer.Server; 
using SqlServer.Clr.Extensions.Aggregates.Implementation; 

[Serializable] 
[SqlUserDefinedAggregate(Format.UserDefined,MaxByteSize = -1)] 
public class Const : IBinarySerialize 
{ 
    private decimal _constValue; 

    public void Init() {} 

    public void Accumulate(SqlDecimal value, SqlDecimal constValue) 
    { 
     _constValue = constValue.Value; 
    } 

    public void Merge(Const value) {} 

    public SqlDecimal Terminate() 
    { 
     return new SqlDecimal(_constValue); 
    } 

    public void Read(BinaryReader r) 
    { 
     _constValue = r.ReadDecimal(); 
    } 

    public void Write(BinaryWriter w) 
    { 
     w.Write(_constValue); 
    } 
} 

編譯此代碼名爲SqlServer.Clr.Extensions.dll組件。下面的腳本可以用來將其添加到SQL Server和驗證意外的行爲:

use [MyDb] -- replace with your db name 
go 

-- drop the Const aggregate if it exists 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Const]')) 
    DROP AGGREGATE [Const] 
GO 
-- drop the assembly if it exists 
IF EXISTS (SELECT * FROM sys.assemblies asms WHERE asms.name = N'SqlServer.Clr.Extensions' and is_user_defined = 1) 
    DROP ASSEMBLY [SqlServer.Clr.Extensions] 
GO 

-- import the assembly 
CREATE ASSEMBLY [SqlServer.Clr.Extensions] 
AUTHORIZATION [dbo] 
    FROM 'C:\Path\To\SqlServer.Clr.Extensions.dll' 
WITH PERMISSION_SET = SAFE 
GO 

CREATE AGGREGATE [Const](@input decimal, @constValue decimal) 
    RETURNS decimal 
    EXTERNAL NAME [SqlServer.Clr.Extensions].[Const] -- put the Const class is in the global namespace 
GO 

SELECT dbo.Const(n, 2) from (select 1 n) x 
SELECT dbo.Const(n, 2.5) from (select 1 n) x 
+1

改變@constvalue decimal@constvalue decimal(13,2)我認爲你必須爲你的小數精度。嘗試更改@constValue十進制到@constValue十進制(13,2)在CREATE AGGREGATE [Const](@輸入十進制,@constValue十進制) – 2011-02-27 13:41:53

+0

@Verrigo哦,我的,當然...也許你應該寫你的評論作爲答案,所以我可以接受它? – jeroenh 2011-02-27 18:38:43

回答

1

你有

Create aggregate [const](@input decimal, @constvalue decimal)