回答:
SQL Server(2005、2000、7.0)には、任意に構造化された日付時刻を文字列形式で取得し、それを日付時刻データ型に変換する柔軟性のある、または柔軟性のない方法さえありません。
「恣意的に」とは、「それを書いた人が、おそらくあなたや私ではなく、地球の反対側にいる誰かが、直感的で完全に明白であると考える形態」を意味します。正直なところ、そのようなアルゴリズムがあるかどうかはわかりません。
9/6/12
したユーザーが2012年9月6日、2012年6月9日、2009年12月6日などを意味するかどうか、Oracleはどのように魔法のように判断しますか?
これを試して
Cast('7/7/2011' as datetime)
そして
Convert(varchar(30),'7/7/2011',102)
詳細については、CASTおよびCONVERT(Transact-SQL)を参照してください。
Cast('2011-07-07' as datetime)
も機能し、月と日の順序のあいまいさを排除することに注意してください。
SET DATEFORMAT dmy
、クエリの前に使用してください
これをクエリプロセッサで実行します。日付や時刻をそのようにフォーマットし、これらの1つがあなたが探しているものを与えるはずです。適応するのは難しくありません:
Declare @d datetime
select @d = getdate()
select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'
SQL Server Denaliでは、探しているものに近づくことができます。しかし、任意に定義された奇抜な日付文字列を渡して、SQL Serverが対応できると期待することはできません。自分の回答で投稿したものを使用した例を1つ示します。FORMAT()関数は、オプションの引数としてロケールを受け入れることもできます。これは.Netの形式に基づいているため、表示されると予想されるほとんどすべてのトークン形式が存在します。
DECLARE @d DATETIME = '2008-10-13 18:45:19';
-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');
-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);
-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);
日付の入力をより細かく制御してサニタイズすることを強くお勧めします。人々がフリーテキストフォームフィールドに好きな形式を使用して日付を入力できるようになった時代は、今ではかなり遅れているはずです。誰かが2011年8月9日と入力した場合、それは8月9日か9月8日ですか?カレンダーコントロールで日付を選択させると、アプリで形式を制御できます。ユーザーの行動をどれほど予測しようとしても、ユーザーは計画していない日付を入力するための気の利いた方法を常に理解します。
しかし、デナリまでは、@ Ovidiuがこれまでのところ最高のアドバイスを持っていると思います...これは、独自のCLR関数を実装することでかなり簡単にすることができます。その後、必要な数の奇抜な非標準形式のケース/スイッチを作成できます。
@dhergertの更新:
SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');
結果:
2008-10-15 22:06:32.000
2008-10-15 22:06:32.000
それでも、他の重要な情報を最初に用意する必要があります。ネイティブT-SQLを使用して、6/9/2012
6月9日か9月6日かを判別することはできません。
やってみませんか
select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY]
select convert(date,'10/15/2011 00:00:00',101)
。docs.microsoft.com/en-us/sql/t-sql/functions/…で
これを理解するのに少し時間がかかったので、誰かを助けるかもしれない場合のためにここにあります:
SQL Server 2012以降では、この関数を使用できます。
SELECT DATEFROMPARTS(2013, 8, 19);
これが、この関数に入れる日付の一部を抽出する方法です。
select
DATEFROMPARTS(right(cms.projectedInstallDate,4),left(cms.ProjectedInstallDate,2),right( left(cms.ProjectedInstallDate,5),2)) as 'dateFromParts'
from MyTable
私はこれがたくさんの答えを持つ邪悪な古い投稿であることを知っていますが、多くの人々は、物事をバラバラにしてそれらを元に戻す必要があると考えるか、OPオリジナルが要求した変換を暗黙的に行う方法はないと主張します。
確認し、同じ質問で他の人に簡単に答えられるようにするために、OPは「10/15/2008 10:06:32 PM」をDATETIMEに変換する方法を尋ねました。現在、SQL Serverには時間変換にいくつかの言語依存関係がありますが、言語が英語またはそれに類似したものである場合、これは簡単な問題になります...変換を実行するだけで、形式について心配する必要はありません。たとえば(そしてCONVERTまたはCASTを使用できます)...
SELECT UsingCONVERT = CONVERT(DATETIME,'10/15/2008 10:06:32 PM')
,UsingCAST = CAST('10/15/2008 10:06:32 PM' AS DATETIME)
;
...そして、それは以下の答えを生み出します。どちらも正しいです。
TVコマーシャルで言うように、「待ってください。まだ注文しないでください。追加費用なしで、さらに多くのことができます!」
DATETIMEを使用した時間変換の本当の力を見て、DATETIME2と呼ばれる誤りを部分的に調べてみましょう。DATETIMEが自動で魔法で処理でき、DATETIME2で処理できない奇抜な形式を確認してください。次のコードを実行してください...
--===== Set the language for this example.
SET LANGUAGE ENGLISH --Same a US-English
;
--===== Use a table constructor as if it were a table for this example.
SELECT *
,DateTimeCONVERT = TRY_CONVERT(DATETIME,StringDT)
,DateTimeCAST = TRY_CAST(StringDT AS DATETIME)
,DateTime2CONVERT = TRY_CONVERT(DATETIME2,StringDT)
,DateTime2CAST = TRY_CAST(StringDT AS DATETIME2)
FROM (
VALUES
('Same Format As In The OP' ,'12/16/2001 01:51:01 PM')
,('Almost Normal' ,'16 December, 2001 1:51:01 PM')
,('More Normal' ,'December 16, 2001 01:51:01 PM')
,('Time Up Front + Spaces' ,' 13:51:01 16 December 2001')
,('Totally Whacky Format #01' ,' 16 13:51:01 December 2001')
,('Totally Whacky Format #02' ,' 16 December 13:51:01 2001 ')
,('Totally Whacky Format #03' ,' 16 December 01:51:01 PM 2001 ')
,('Totally Whacky Format #04' ,' 2001 16 December 01:51:01 PM ')
,('Totally Whacky Format #05' ,' 2001 December 01:51:01 PM 16 ')
,('Totally Whacky Format #06' ,' 2001 16 December 01:51:01 PM ')
,('Totally Whacky Format #07' ,' 2001 16 December 13:51:01 PM ')
,('Totally Whacky Format #08' ,' 2001 16 13:51:01 PM December ')
,('Totally Whacky Format #09' ,' 13:51:01 PM 2001.12/16 ')
,('Totally Whacky Format #10' ,' 13:51:01 PM 2001.December/16 ')
,('Totally Whacky Format #11' ,' 13:51:01 PM 2001.Dec/16 ')
,('Totally Whacky Format #12' ,' 13:51:01 PM 2001.Dec.16 ')
,('Totally Whacky Format #13' ,' 13:51:01 PM 2001/Dec.16')
,('Totally Whacky Format #14' ,' 13:51:01 PM 2001 . 12/16 ')
,('Totally Whacky Format #15' ,' 13:51:01 PM 2001 . December / 16 ')
,('Totally Whacky Format #16' ,' 13:51:01 PM 2001 . Dec / 16 ')
,('Totally Whacky Format #17' ,' 13:51:01 PM 2001 . Dec . 16 ')
,('Totally Whacky Format #18' ,' 13:51:01 PM 2001 / Dec . 16')
,('Totally Whacky Format #19' ,' 13:51:01 PM 2001 . Dec - 16 ')
,('Totally Whacky Format #20' ,' 13:51:01 PM 2001 - Dec - 16 ')
,('Totally Whacky Format #21' ,' 13:51:01 PM 2001 - Dec . 16')
,('Totally Whacky Format #22' ,' 13:51:01 PM 2001 - Dec / 16 ')
,('Totally Whacky Format #23' ,' 13:51:01 PM 2001 / Dec - 16')
,('Just the year' ,' 2001 ')
,('YYYYMM' ,' 200112 ')
,('YYYY MMM' ,'2001 Dec')
,('YYYY-MMM' ,'2001-Dec')
,('YYYY . MMM' ,'2001 . Dec')
,('YYYY / MMM' ,'2001 / Dec')
,('YYYY - MMM' ,'2001 / Dec')
,('Forgot The Spaces #1' ,'2001December26')
,('Forgot The Spaces #2' ,'2001Dec26')
,('Forgot The Spaces #3' ,'26December2001')
,('Forgot The Spaces #4' ,'26Dec2001')
,('Forgot The Spaces #5' ,'26Dec2001 13:51:01')
,('Forgot The Spaces #6' ,'26Dec2001 13:51:01PM')
,('Oddly, this doesn''t work' ,'2001-12')
,('Oddly, this doesn''t work' ,'12-2001')
) v (Description,StringDT)
;
したがって、そうです... SQL Serverには、実際にはあらゆる種類の奇妙な一時形式を処理する非常に柔軟な方法があり、特別な処理は必要ありません。24時間に追加された「PM」を削除する必要すらありませんでした。それは「PFM」(Pure Freakin 'Magic)です。
言語によって多少異なりますが、サーバーに選択した言語ですが、大部分はどちらの方法でも処理されます。
そして、これらの「自動マジック」変換は新しいものではありません。彼らは本当に長い道のりを戻ります。
SQL Serverに試行錯誤させたい場合は、CAST CAST( 'whatever' AS datetime)を使用します。ただし、これは一般的に悪い考えです。出てくる国際的な日付の問題があります。そのため、これらの問題を回避するために、ODBCの正規形式の日付を使用したいことがわかりました。つまり、フォーマット番号120、20は2桁の年のフォーマットです。SQL Serverには、ユーザーが指定した形式を提供できる組み込み関数はないと思います。自分で作成することもできますが、オンラインで検索すると見つけられる場合もあります。
暗黙的にMSSQLで文字列を日時に変換する
create table tmp
(
ENTRYDATETIME datetime
);
insert into tmp (ENTRYDATETIME) values (getdate());
insert into tmp (ENTRYDATETIME) values ('20190101'); --convert string 'yyyymmdd' to datetime
select * from tmp where ENTRYDATETIME > '20190925' --yyyymmdd
select * from tmp where ENTRYDATETIME > '20190925 12:11:09.555'--yyyymmdd HH:MIN:SS:MS
dateadd(day,0,'10/15/2008 10:06:32 PM')