2

過去に同様の質問があったことは知っていますが、それでも私の場合の適切な解決策は得られていません。

varchar値の列を持つデータベーステーブル(サードパーティ)がありdatetimeます。

次の形式の日付が含まれています。

  11181980 
  8 18 1960 
  10/01/1960 
  04-12-1953 
  041371 
  7/29/44
  Empty String 
  NULL

mm/dd/yyyyこの列を選択するとき、利用可能な場合は標準形式(たとえば)またはNULLで日付を表示したいと思います。

これを行う関数しか考えられませんが、変換しようとしたときにエラーが発生しないようにする必要があるため、UDFは実行したくありません。UDFにはtry/catchはありません。避けたいのですが、CLR関数を実行してより強力な.net機能を利用することができます。

SQL Serverでこの変換を処理する他のより良い方法はありますか?また、SQLで可能であれば、この変換をどのように行う必要がありますか。

4

4 に答える 4

2

あなたが説明した潜在的なフォーマットのセットについて:

DECLARE @x TABLE(y VARCHAR(32))

INSERT @x VALUES
('11181980'),
('8 18 1960'),
('10/01/1960'),
('04-12-1953'), 
('041371'),
('7/29/44'),
(''), 
(NULL);

SET DATEFORMAT MDY;

SELECT CONVERT(DATETIME, CASE WHEN y LIKE '%/%' THEN y
 WHEN LEN(RTRIM(y)) = 0 THEN NULL
 WHEN LEN(RTRIM(y)) IN (6,8) AND ISNUMERIC(y) = 1 THEN
 STUFF(STUFF(y,3,0,'/'),6,0,'/') END)
FROM (SELECT y = REPLACE(REPLACE(y, ' ', '/'), '-', '/') FROM @x) AS x;

これは、サーバー設定に基づいてではなく、7/29/44として解釈されます。すべての日付が過去のものであることを確認するには、次のようにします。20441944

SELECT y = DATEADD(YEAR, CASE WHEN y > GETDATE() THEN -100 ELSE 0 END, y) 
FROM
(
  SELECT y = CONVERT(DATETIME, CASE WHEN y LIKE '%/%' THEN y
   WHEN LEN(RTRIM(y)) = 0 THEN NULL ELSE
   STUFF(STUFF(y, 3, 0, '/'),6, 0, '/') END)
  FROM (SELECT y = REPLACE(REPLACE(y, ' ', '/'), '-', '/') FROM @x) AS x
) AS z;

これは、日付にマッサージできないガベージデータがないことにも依存します。とにかく、どのようなシステムがこの種の一貫性のないナンセンスに入りますか?

SQL Server 2012では、TRY_PARSEまたはTRY_CONVERTを使用できますが、そのようなフォーマットの混乱がある場合でも、意味のある結果を得るには、マッサージを行う必要があります。

于 2012-08-30T16:00:02.557 に答える
0

データベースを所有しているが変更できない場合は、すべての値を1つの共通形式にサニタイズするストアドプロシージャを実行し、その形式のエントリのみを挿入/更新できるようにします。CRUD操作を制御できない場合は、「日付」をそのままフェッチしてDateTime、BLレイヤーでaへの変換を実行します。

おそらくあなたの質問に対する答えではありませんが、個人的には、変換やその他のロジックをデータベースの外部に保持することで、すべてのクエリをできるだけ単純にするのが好きです。

于 2012-08-30T15:40:51.117 に答える
0

次のことをお勧めします。

  1. そのテーブルを設計した人を見つけて撃つ
  2. おそらく正規表現パターン マッチングを使用して、値を日付に解析する CLR 関数を記述します。
  3. すべて同じ列を返すビューを作成しますが、varchar フィールドの代わりに関数の結果を返します

正直なところ、データはゴミのように見えますが、まったく信頼できるとは思えません。次のような値が存在する可能性があります。

  • 11190
  • 1111990

これらは 1990-11-01 または 1990-01-11 である必要がありますか? CLR 関数は、最も安定した方法で最も多くのデータを取得できると思います。

于 2012-08-30T15:53:44.953 に答える