#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