Ошибка преобразования при преобразовании даты и / или времени из строки символов - PullRequest
2 голосов
/ 13 июля 2011

Я получаю эту ошибку: Conversion failed when converting date and/or time from character string при попытке выполнить следующий запрос в SQL Server 2008 R2:

    DECLARE @Time datetime = N'7/13/2011'
    DECLARE @str as varchar(100) = '2011_07_13_DM_VT_I2_Data'
    DECLARE @TestTime datetime =  cast(replace (left (left(@str, len(@str) - len('_data')), 10), '_', '') as datetime)
    DECLARE @r int = datediff(d, @TestTime, @Time)

    SELECT t.name FROM
    (
    SELECT 
         name
    FROM 
        sysobjects 
    WHERE 
        (type = 'U') AND ((name LIKE '%[_]I2[_]Data') or (name LIKE '%[_]R4[_]Data') or (name LIKE '%[_]R8[_]Data'))
    ) t

    WHERE
        datediff(DAY, cast(replace (left (left(t.name, len(t.name) - len('_data')), 10), '_', '') as datetime), @Time) <= 1

    ORDER BY 
        cast(replace (left (left(t.name, len(t.name) - len('_data')), 10), '_', '') as datetime) desc

Этот запрос работает нормально, если я закомментирую WHERE datediff(DAY, cast(replace (left (left(t.name, len(t.name) - len('_data')), 10), '_', '') as datetime), @Time) <= 1, тогда мне интересно, если это проблема функции cast. Но таблица t будет иметь имена таблиц, такие как '2011_07_13_DM_VT_I2_Data', которые вы можете видеть в @TestTime, функция cast прекрасно работает с этим форматом. Я не знаю, что не так с условием WHERE.

Спасибо за любую помощь.

1 Ответ

1 голос
/ 13 июля 2011

Вам нужно разделить ваш запрос на два, потому что похоже, что оптимизатор запросов решил применить предложение where из внешнего запроса, прежде чем он отфильтровывает строки из системных объектов в подзапросе.

Вы можете попробовать что-то вроде этого.

DECLARE @Time datetime = N'7/13/2011'
DECLARE @str as varchar(100) = '2011_07_13_DM_VT_I2_Data'
DECLARE @TestTime datetime =  cast(replace (left (left(@str, len(@str) - len('_data')), 10), '_', '') as datetime)
DECLARE @r int = datediff(d, @TestTime, @Time)

SELECT name INTO #TMP
FROM 
    sysobjects 
WHERE 
    (type = 'U') AND ((name LIKE '%[_]I2[_]Data') or (name LIKE '%[_]R4[_]Data') or (name LIKE '%[_]R8[_]Data'))

SELECT *
FROM #TMP as t
WHERE
    datediff(DAY, cast(replace (left (left(t.name, len(t.name) - len('_data')), 10), '_', '') as datetime), @Time) <= 1

ORDER BY 
    cast(replace (left (left(t.name, len(t.name) - len('_data')), 10), '_', '') as datetime) desc

DROP TABLE #TMP
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...