Чем дальше в лес, тем толще партизаны.
Ситуация: есть некий MS SQL Server 2000, в нем есть база, в ней таблица F, хранимая процедура H и две вьюшки A и B.
Есть программа, которая на сервер отправляет запрос, который вызывает хранимую процедуру, которая вызывает вьюшки.
Эта программа, а следовательно запрос, процедура и вьюшки прекрасно себя чувствовали до ноября месяца, но, сейчас запрос перестал работать.
Выяснилось: Запрос передает в процедуру 4 параметра: дату начала операции, дату конца операции, параметр отвечающий за сортировку и параметр отвечающий за выбор по какой-то конкретной компании.
Сейчас эта процедура работает при некоторых значениях даты начала и конца операции, а при некоторых выдает ошибку
Сообщение 242, уровень 16, состояние 3, процедура H, строка 5
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
Гугленье привело к возможным вариантам решения проблемы:
1) возможно перепутан месяц и день при разборе передаваемой даты, нужно установить dateformat DMY или сделать Convert на передающихся данных чтобы они были в формате MDY
( dateformat добавляла в хранимую процедуру, но не помогло. С convertом вообще ничего не получилось, как только я переставила день и месяц с помощью него местами, так запрос стал работать неправильно. кроме сервер корректно ищет по некоторым другим датам с идентичным переданным параметром, отличающимся только числом, да и переданный параметр находится в виде близком к mdy, а не к dmy)
2)возможно был изменен язык для учетных записей на сервере, попробовать установить другой
(изменила для sa язык, под которым проверяла работоспособность программы, но это вообще никак не сказалось на выполнении запроса)
3) возможно неправильно записались некоторые даты в саму таблицу F. я посмотрела, но не нашла в том поле в разных записях (на которых запрос работает и на которых нет) хотя бы какой-то разницы в виде даты.
Что удалось выяснить:
1) на сервер параметры даты-времени передаются как строка вида
'Nov 1 2011 12:00:00:000AM'
На сервере, в поле по которому производится сравнение, дата-время хранится например так:
2011-11-1 23:28:00.000
Я проверяла потом корректно ли сервер переводит время из той строки, которую получает, в формат даты-времени, получила параметр типа datetime такого же вида как и поле по которому идет сравнение.
2) Если вызывать хранимую процедуру с теми же параметрами на самом сервере, то я получаю ту же ошибку.
Но, если вызвать не хранимую процедуру (которая вызывает вьюшки), а просто создать запрос с selectом к таблице F, таким же как и select в хранимой процедуре, на котором происходит ошибка, то никаких ошибок нет.
выглядит этот select в процедуре так:
select * into #t from вьюшка_A where FTime>=@datebeg and FTime<@dateend - есть ошибка.
select * from таблица_F where FTime>=@datebeg and FTime<@dateend - нет ошибки.
Помогите разобраться пожалуйста, я уже двое суток ничего понять не могу, а пользователи сделать свою работу ;(
Примечание:
*второй select не в процедуре, просто решила выполнить такой запрос и посмотреть что будет.
Примечание:
Pinnekjot
просто объявляются две переменные @datebeg и @dateend обе типа datetime, в которые передаются данные в виде строки. Да там в одной из вьюшек по-хитрому как-то прибавляются минуты и еще много чего происходит, но я не нашла там какого-то конвертирования этих переменных. Правда я еще не совсем "докурила" эти вьюшки, они как я уже говорила несколько.. запутаны((
Если нужен текст вьюшек и процедуры, то впринципе я могу его привести, но они достаточно большие и запутанные.
Примечание:
k_max
вот как я это сделаю? у меня за одни сутки предположим около 100 записей. я знаю на каких днях оно сломалось, я смотрела уже записи из этих дней и сравнивала их с теми на которых не ломаются - не обнаружила хотя бы каких-то различий.
я могу привести текст вьюшек конечно. может быть кому-то удастся понять что там творится, я так до конца и не понимаю как это вообще работает.
вьюшка 1
USE [isg1]
GO
/****** Объект: View [dbo].[PDSA_FI_List] Дата сценария: 11/30/2011 12:15:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER VIEW [dbo].[PDSA_FI_List]
AS
select dbo.PDSA_FlightGroup(f.type,f.tws,f.Is_Helic,f.tvyl)as prisn
,f.Number as number
,f.tws,f.nws,f.rtimep,f.ftp,f.rtimev,f.ftimev,f.type
,pass=isnull(l.ad_y,0)+isnull(l.chd_y,0)+isnull(l.inf,0)
,cargo=isnull(l.cargo,0)+isnull(l.bag,0),l.post
,RegFlight=f.IsNotDelayOut
,NotRegFlight=f.IsDelayOut
,cdIn=case when f.codep is not null then f.codep else case when f.statep=3 then 'РЕГ' end end
,cdOut1=case when d1.delycod is not null then d1.delycod else case when f.statev=3 then 'РЕГ' end end
,tdOut1=case when f.tvyl<>0 then f.timedp end
,cdOut2=d2.delycod,tdOut2=f.lendel
,numAct=a.Number
,Guilty=rtrim((select top 1 o.Guilty from PDSA_DelayedOffice o where o.Flight_id=f.flight_id order by RecordID))
,f.flight_id,f.Parn_Flight_id,f.carrier
,f.tvyl,f.statev,f.carrierName
,f.lendel_asDateTime,f.timedp_asDateTime
,isExec=case when f.ftimev is not null then 1 end
,isDelMeteo=case when (substring(d1.delycod,1,1)='М' or (substring(d2.delycod,1,1)='М') and f.lendel_asDateTime>f.timedp_asDateTime ) then 1 end
,isDelPPS=case when d1.delycod='ППС' and (d2.delycod is null or (d2.delycod is not null and f.timedp_asDateTime>=f.lendel_asDateTime)) then 1 end
,isDelPPSmeteo=case
when f.tvyl=1 and substring(f.codep,1,1) ='М' and d1.delycod='ППС' and (d2.delycod is null or (d2.delycod is not null and f.timedp_asDateTime>=f.lendel_asDateTime)) then 1
when f.tvyl=2 and substring(f.Parn_CodeP,1,1)='М' and d1.delycod='ППС' and (d2.delycod is null or (d2.delycod is not null and f.timedp_asDateTime>=f.lendel_asDateTime)) then 1
end
,isDelAct=case when a.Number is not null then 1 end
,FlightTime=ftimev
,cdOut=isnull(d2.delycod,d1.delycod)
from PDSA_FlightCard f
left join PDSA_otpr l on l.flight_id=f.flight_id
left join flightDelay d1 on d1.Flight_id=f.Flight_id and d1.tvyl=2 and d1.npp=1
left join flightDelay d2 on d2.Flight_id=f.Flight_id and d2.tvyl=2 and d2.npp=2
left join PDSA_ActDelay a on a.flight_id=f.flight_id
where f.tvyl<>0 and f.statev<>5 and f.ftimev is not null
Примечание:
вьюшка 2
USE [isg1]
GO
/****** Объект: View [dbo].[PDSA_FlightCard] Дата сценария: 11/30/2011 12:37:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER VIEW [dbo].[PDSA_FlightCard]
AS
select f.*
,allin_bk,allin_rb,allin_pm,allin_bag,allin_post,allin_cargo
,in_bk,in_rb,in_pm,in_bag,in_post,in_cargo
,out_bk,out_rb,out_pm,out_bag,out_post,out_cargo
,trans_bk=allin_bk-in_bk,trans_rb=allin_rb-in_rb,trans_pm=allin_pm-in_pm,trans_bag=allin_bag-in_bag,trans_post=allin_post-in_post,trans_cargo=allin_cargo-in_cargo
, dbo.FactLoading(f.flight_id) AS FactLoad
,MarshCod=dbo.Marshrut(f.flight_id,1),MarshCity=dbo.Marshrut(f.flight_id,0)
,tav.is_Helic
,pr.Number as Parn_Number
,pr.nws as Parn_Nws,pr.codep as Parn_CodeP,pr.flight_id as Parn_Flight_id
,Parn_time=pr.ftimep+isnull(tavPar.rulep,'')
,isDelayOut= convert(bit,case when f.tvyl<>0 and f.statev<>5 and (f.statev<>3 and (f.ftimev-isnull(tav.rulev,'')) > f.rtimev) then 1 else 0 end )
,isNotDelayOut=convert(bit,case when f.tvyl<>0 and f.statev<>5 and (f.statev = 3 or (f.ftimev-isnull(tav.rulev,''))<=f.rtimev) then 1 else 0 end )
,ftp=f.ftimep+isnull(tav.rulep,''),ftv=f.ftimev-isnull(tav.rulev,'')
,TimeSt=dbo.DateTimeToTime( f.rtimev-f.rtimep,null)
,timedp=dbo.DateTimeToTime(case when f.statep<>3 then
Примечание:
case
when f.tvyl=0 and (f.ftimep+isnull(tav.rulep,''))-f.rtimep>'00:10' then (f.ftimep+isnull(tav.rulep,''))-f.rtimep
when f.tvyl=1 and d.delycod is not null and (f.ftimep+isnull(tav.rulep,''))-f.rtimep>'00:10' then (f.ftimep+isnull(tav.rulep,''))-f.rtimep
when f.tvyl=2 and d.delycod is not null and pr.Flight_id is not null and (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep>'00:10' then (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep
end end
,null)
,timer=case
when f.tvyl=1 then case when f.rtimep>(f.ftimep+isnull(tav.rulep,'')) or (f.ftimep+isnull(tav.rulep,''))-f.rtimep<='00:10' then f.rtimep
else (f.ftimep+isnull(tav.rulep,'')) end+(f.rtimev-f.rtimep)
when f.tvyl=2 then case when pr.Flight_id is not null then
case when pr.rtimep>(pr.ftimep+isnull(tavPar.rulep,'')) or (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep<='00:10' then pr.rtimep
else (pr.ftimep+isnull(tavPar.rulep,'')) end+pr.timestPar
else f.rtimev end
end+'00:15'
--,f.tvyl as ftvyl, f.rtimep as ftimer,(f.ftimep+isnull(tav.rulep,'')) as q,(f.rtimev-f.rtimep) as q1,f.rtimev as frtimev, f.rtimep as frtimep
,lendel=dbo.DateTimeToTime(case when f.statev<>3 then f.ftimev-
(case
when f.tvyl=1 then case when f.rtimep>(f.ftimep+isnull(tav.rulep,'')) or (f.ftimep+isnull(tav.rulep,''))-f.rtimep<='00:10' then f.rtimep
else (f.ftimep+isnull(tav.rulep,'')) end+(f.rtimev-f.rtimep)
when f.tvyl=2 then case when pr.Flight_id is not null then
case when pr.rtimep>(pr.ftimep+isnull(tavPar.rulep,'')) or (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep<='00:10' then pr.rtimep
else (pr.ftimep+isnull(tavPar.rulep,'')) end+pr.timestPar
else f.rtimev end
end+'00:15') end
,null)
,lendel_asDateTime=f.ftimev-
(case
when f.tvyl=1 then case when f.rtimep>(f.ftimep+isnull(tav.rulep,'')) or (f.ftimep+isnull(tav.rulep,''))-f.rtimep<='00:10' then f.rtimep
else (f.ftimep+isnull(tav.rulep,'')) end+(f.rtimev-f.rtimep)
when f.tvyl=2 then case when pr.Flight_id is not null then
case when pr.rtimep>(pr.ftimep+isnull(tavPar.rulep,'')) or (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep<='00:10' then pr.rtimep
else (pr.ftimep+isnull(tavPar.rulep,'')) end+pr.timestPar
else f.rtimev end
end+'00:15')
,timedp_asDateTime=case when f.statep<>3 then
case
when f.tvyl=0 and (f.ftimep+isnull(tav.rulep,''))-f.rtimep>'00:10' then (f.ftimep+isnull(tav.rulep,''))-f.rtimep
when f.tvyl=1 and d.delycod is not null and (f.ftimep+isnull(tav.rulep,''))-f.rtimep>'00:10' then (f.ftimep+isnull(tav.rulep,''))-f.rtimep
when f.tvyl=2 and d.delycod is not null and pr.Flight_id is not null and (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep>'00:10' then (pr.ftimep+isnull(tavPar.rulep,''))-pr.rtimep
end end
,CarrierName=PDSP.dbo.Organization.name,d.delycod,pr.Flight_id as prFlight_id
,ActNum=a.number
from flight f
left join PDSP.dbo.TAV tav on TAV.tws=f.tws
left join FlightCard_Loading l on l.Flight_id=f.flight_id
left join ParnFlightAll pr on pr.flightOut=f.Flight_id
left join PDSP.dbo.TAV tavPar on tavPar.tws = pr.tws
left join PDSP.dbo.Organization on orgcod = f.carrier
left join flightDelay d on d.Flight_id=f.Flight_id and d.tvyl=2 and d.delycod='ППС' and d.npp=1
left join PDSA_ActDelay a on a.Flight_id=f.flight_id
Примечание:
k_max
нет, руки не дошли пока до всех этих прибавлений минут. фокус весь в том, что эта процедура не работала только 8 дней и только в одном месяце. в остальных случаях она работала и работает сейчас.
Примечание:
Иероним Босх (Иероним Босх)
афигенный ответ.. вот как я без вашей помощи до этого жила, понять не могу.