SQLCLR и DateTime2 - PullRequest
       22

SQLCLR и DateTime2

6 голосов
/ 12 апреля 2010

Использование SQL Server 2008, Visual Studio 2005, .net 2.0 с пакетом обновления 2 (поддерживает новые типы данных SQL Server 2008).

Я пытаюсь написать функцию SQLCLR, которая принимает DateTime2 в качестве входных данных и возвращает другой DateTime2. например :

using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

namespace MyCompany.SQLCLR
{
    public class DateTimeHelpCLR
    {
        [SqlFunction(DataAccess = DataAccessKind.None)]
        public static SqlDateTime UTCToLocalDT(SqlDateTime val)
        {
            if (val.IsNull)
                return SqlDateTime.Null;

            TimeZone tz = System.TimeZone.CurrentTimeZone;
            DateTime res = tz.ToLocalTime(val.Value);

            return new SqlDateTime(res);
        }
    }
}

Теперь вышеприведенное компилируется нормально. Я хочу, чтобы эти SqlDateTimes отображались на DateTime2 SQL Server, поэтому я пытаюсь запустить этот T-SQL:

CREATE function hubg.f_UTCToLocalDT
(
    @dt DATETIME2
)
returns DATETIME2
AS
EXTERNAL NAME [SQLCLR].[MyCompany.SQLCLR.DateTimeHelpCLR].UTCToLocalDT
GO

Это дает следующую ошибку:

Сообщение 6551, Уровень 16, Состояние 2, Процедура f_UTCToLocalDT, строка 1 CREATE FUNCTION для "f_UTCToLocalDT" не удалось, потому что Типы T-SQL и CLR для возвращаемого значения не совпадают.

Использование DATETIME (вместо DATETIME2) работает нормально. Но я бы предпочел использовать DATETIME2 для поддержки повышенной точности. Что я делаю не так, или DateTime2 не (полностью) не поддерживается SQLCLR?

Ответы [ 2 ]

10 голосов
/ 12 апреля 2010

Вам необходимо изменить типы DateTime в подписи вашего Function Function. SQLDateTime сопоставляется с DateTime в базе данных.

System.DateTime является более точным, и можно сопоставить с DateTime2 (но по умолчанию он будет отброшен как DateTime в сценарии развертывания).

[SqlFunction(DataAccess = DataAccessKind.None)]
//OLD Signature public static SqlDateTime UTCToLocalDT(SqlDateTime val) 
public static DateTime UTCToLocalDT(DateTime val) {
   ...
}

Затем вы можете настроить скрипт развертывания для чтения.

CREATE FUNCTION [UTCToLocalDT]
(
    @dt [datetime2]
)
RETURNS [datetime2]
AS
    EXTERNAL NAME [SQLCLR].[MyCompany.SQLCLR.DateTimeHelpCLR].UTCToLocalDT
GO

Запуск вашей функции теперь должен дать вам более точный вывод.

DECLARE @input DateTime2, @output DateTime2
SET @input = '2010-04-12 09:53:44.48123456'
SET @output = YourDatabase.dbo.[UTCToLocalDT](@input)
SELECT @input, @output
0 голосов
/ 13 января 2014

Обратите внимание, что с использованием "DateTime?" по-прежнему всегда выдает ошибки сборки (даже в VS 2013 с sql 2012), хотя, очевидно, результат можно использовать, если выбрать «построить, развернуть», а затем использовать файлы в папке obj, редактируя сгенерированный файл.sql в окне запроса sql (использовать DateTime2 в качестве параметра) перед выполнением, чтобы добавить его на Sql Server.
Ошибка сборки: «SQL46010: неверный синтаксис рядом)». в \ obj \ Debug \ YourPrjName.generated.sql

(Разместил бы как комментарий, если бы мог.)

...