Ошибка преобразования типа данных в хранимой процедуре в SQL Server 2008

#sql #sql-server #datetime

#sql #sql-сервер #дата и время

Вопрос:

Может кто-нибудь, пожалуйста, помогите мне устранить эту ошибку.

Структура таблицы:

 DECLARE @TABLE TABLE (MYDATE DATETIME2)


INSERT @TABLE
    SELECT 2016-08-08 10:27:58.0000000 UNION ALL
    SELECT 2016-09-25 16:55:00.0000000 UNION ALL
    SELECT 2016-01-07 10:09:00.0000000 UNION ALL
    SELECT 2016-01-07 10:10:00.0000000 UNION ALL
    SELECT 2016-02-26 16:55:00.0000000
  

У меня нет разрешения на изменение структуры этой таблицы.

Моя хранимая процедура:

 CREATE PROCEDURE dbo.CHECKS 
    @MYDATE DATETIME 
AS
    SELECT 
        *
    FROM       
        TABLE1 t1
    INNER JOIN 
        TABLE2 t2 
    WHERE 
        CONVERT(NVARCHAR(MAX), @MYDATE, 105) = MYDATE
  

Но клиент хочет передать параметр date, например

 EXEC dbo.ComparePrices '25092016'
  

При этом возникает ошибка, подобная

Сообщение об ошибке 8114, уровень 16, состояние 1, сравнительные цены процедур, строка 0
Ошибка преобразования типа данных varchar в datetime.

Пожалуйста, помогите мне.

Спасибо

Комментарии:

1. Почему вы преобразуете параметр datetime в varchar(max)???? И что такое @DTFETCH? Вы должны сохранить тип данных как даты и просто выполнить сравнение.

2. @SeanLange: извините, произошла ошибка с опечаткой, сейчас исправлена

3. @AlexK.: извините, произошла ошибка опечатки, сейчас исправлена

4. convert(nvarchar(MAX) преобразуется в VARCHAR не DATETIME

5. Похоже, ваш актуальный вопрос таков: как я могу преобразовать значение like 08082016 в datetime? В этом случае, пожалуйста, приведите пример с днем выше 12, поскольку вашим примером может быть ddmmyyyyy, а также mmddyyyyy.

Ответ №1:

Вы можете использовать STUFF() для вставки разделителей в правильные позиции. Затем вы можете использовать CONVERT() с соответствующим форматом. В этом случае я вставляю / , чтобы получить формат 103 . Подробности здесь:

 DECLARE @stringdate VARCHAR(100)='30092016';
SELECT CONVERT(DATETIME,STUFF(STUFF(@stringdate,3,0,'/'),6,0,'/'),103)
  

РЕДАКТИРОВАТЬ: с SQL Server < 2008 вы можете достичь того же без STUFF() .

 SELECT CONVERT(DATETIME,LEFT(@stringdate,2) '/' SUBSTRING(@stringdate,3,2) '/' RIGHT(@stringdate,4),103)
  

Обновить

В своем комментарии вы спрашиваете, как это можно сделать как table valued function . Попробуйте что-то вроде этого:

 CREATE FUNCTION dbo.CHECKS
( 
    @DateAsUnseparatedString_DDMMYYYY VARCHAR(8) 
)
RETURNS TABLE
AS
    RETURN
    SELECT 
        *
    FROM       
        TABLE1 t1
    INNER JOIN 
        TABLE2 t2 ON (1=1)
    WHERE 
        CAST(MYDATE AS DATE)=CONVERT(DATETIME,STUFF(STUFF(@DateAsUnseparatedString_DDMMYYYY,3,0,'/'),6,0,'/'),103);
GO
  

И назовите это как

 SELECT * FROM dbo.CHECKS('26092016');
  

Причина, по которой вы ничего не получаете обратно

… совершенно уверен, что вы забыли о временной части. Значение like 2016-08-08 10:27:58.0000000 не равно преобразованной дате DDMMYYYYY like 08082016 . Вот почему я использую CAST(... AS DATE) , чтобы получить голую дату, которую вы можете сравнить с преобразованным значением, которое тоже является голой датой.

Другой подход заключался в использовании

 WHERE MYDATE >= TheConvertedValue AND MYDATE < TheConvertedValue 1;
  

Комментарии:

1. МАТЕРИАЛ был введен в sql 2005, поэтому нет необходимости использовать версию метода string, если они не находятся на 2000 или старше.

2. @RohiniMathur вы выполнили запрос в обратном направлении. Вы хотите преобразовать параметр в datetime. Если вы попытаетесь заполнить свой столбец datetime, он завершится неудачей.

3. @Shnugo: Большое спасибо, Shnugo

4. @Shnugo: я сделал то же самое, и sp успешно выполнен, но когда я выполняю SP, передавая строку, возвращает 0. пожалуйста, любое предложение.

5. Данные в таблице в формате 2016-08-08 10:27:58.0000000