まず第一に、あなたはそれらなしではできませんよね?
SQLデータ変換、より具体的には、データ型変換は、データベース開発者またはDBAの通常のプログラミング作業の重要な部分です。
では、上司が他の会社と契約を結び、SQLServerデータベースからのテキスト形式のファイルを提供するとしたらどうでしょうか。
これはエキサイティングな挑戦のように聞こえます!
しかし、日付から文字列、数値から文字列、およびその他のSQLデータ変換の束を処理する必要があることがわかりました。あなたはまだ挑戦に挑戦していますか?
データ変換のトリックの武器がないわけではありません!
すぐに利用できるものは何ですか?
T-SQLプログラミングを最初に始めたとき、変換の目的に合ったものを最初に見たのは、変換でした。 ()関数。
その上、「変換する」という言葉がありますよね?
これは本当かもしれませんが、これはこの仕事を実行する4つの方法の1つにすぎません。そして、私はそれを私のSQLデータ変換のほとんどすべてに使用していました。それをはるかに超えてよかったです。 4つのメソッドがコード内で独自の位置を占めることを知ったからです。
投稿の主題に入る前に、SQLデータ変換を実行するための4つのすぐに使える方法を紹介しましょう:
- キャスト ()
- 変換 ()
- 解析 ()
- TRY_CAST ()、 TRY_CONVERT ()、 TRY_PARSE ()
以下の各セクションは次のようになります。
- それが何であるかを説明する
- いつ使用するかを教えてください(ユースケース)
- 制限を提示する
- 例を挙げて説明します
この記事で紹介するものはすべて、可能な限りわかりやすくシンプルな英語で書かれています。投稿全体を読み終えるまでに、特定の状況に適した方法がわかります。
それで、これ以上面倒なことはせずに、飛び込みましょう。
1。 CAST()を使用したSQLデータ変換
表示されるすべてのメソッドでデータ型を変換できますが、変換の最初の選択肢は間違いなく CASTである必要があります。 ()。
理由は次のとおりです。
- これは、すべての中で最も高速に実行される変換機能です。これについては、この投稿の後半で証明しようとします。
- SQL-92言語仕様標準に含まれています。したがって、コードをMySQLなどの他のSQL製品に移植する必要がある場合は、この関数も使用できます。
CASTの非常に単純な構文は次のとおりです。 ():
CAST( <expression> AS <data_type>[(length)] )
まず、構文を調べてみましょう:
- <式>は、ターゲットデータ型に変換できる値をもたらす有効な式です。
- < data_type >はターゲットデータ型です。
- 長さ オプションであり、データのサイズに関係します。
いつ使用するか
必要なのが値を別のデータ型に変換することだけである場合は、キャスト ()はまさにあなたが必要とするものです。
制限
マイナス面として、キャスト ()は、フォーマットされた日付と時刻の値のように、すぐにフォーマットされた出力を提供することはできません。
例
A。文字列を日付に変換する:
SELECT CAST('09/11/2004 4:30PM' as datetime2)
上記のステートメントを実行すると、次のようになります。
B。数値を文字列に変換します:
SELECT CAST(10.003458802 as varchar(max))
そして、上記の変換の結果は次のとおりです。
変換されたデータのフォーマットなど、他の方法が必要な場合は、次の方法が役立ちます。
2。 CONVERT()を使用したSQLデータ変換
データ変換の次のオプションは、 CONVERTを使用することです。 ()。前にも言ったように、これは私が以前最もよく使っていたものです。
構文は次のとおりです。
CONVERT( <data_type>[(length)], <expression> [, <style>])
上記の構文から、<スタイルに注意してください。>パラメータはオプションです。また、指定しない限り、機能は CASTと同様になります。 ()。
ここから、SQLを初めて使用したときに混乱が始まりました。
いつ使用するか
インスタント形式でデータを変換する場合は、変換 () あなたの友だちです。つまり、<スタイルを扱うということです>パラメータを正しく設定してください。
制限
- キャスト ()は変換よりも高速です ()、したがって、データを変換するだけでよい場合は、 CASTを使用します ()。出力をフォーマットする必要がある場合は、 CONVERTを使用します ()。
- 変換 ()はSQL-92標準ではないため、他のRDBMSに移植する必要がある場合は、使用しないでください。
例
A。日付を文字列形式に変換する yyyymmdd
次の例では、サンプルデータベース AdventureWorksを使用します [ StartDateを変換します ]列からyyyymmdd :
USE AdventureWorks
GO
SELECT
[BillOfMaterialsID]
,CONVERT(varchar(10), [StartDate],112) as StartDate
FROM [Production].BillOfMaterials]
GO
スタイル112は、日付を yyyymmddにフォーマットするために使用されることに注意してください。 。
B。数値を小数点の左側の3桁ごとにコンマを含む文字列に変換します。
同様に、次の例は AdventureWorksを示しています サンプルデータベース。数値はコンマと小数点以下2桁でフォーマットします。
USE AdventureWorks
GO
SELECT
[TransactionID]
,[ProductID]
,CONVERT(varchar(10),[TransactionDate] ,112) as StartDate
,[Quantity]
,CONVERT(varchar(10),[ActualCost],1) as ActualCost
FROM [Production].TransactionHistory
GO
フォーマット1は[ActualCost]に使用されることに注意してください ]。そしてCONVERTに感謝します ()、これらの列を瞬時にフォーマットできます。
ただし、より長い日付式を変換する必要がある場合はどうなりますか? 変換します ()その場合は動作しますか?次の方法について学ぶために読んでください。
3。 PARSE()を使用したSQLデータ変換
次に検討する方法は、 PARSEです。 ()。
構文を確認してください:
PARSE( <string value> AS <datatype> [USING <culture>])
いつ使用するか
- 特定のカルチャを使用して文字列を日付または数値に変換する。
- CASTを使用して文字列を日付または数値に変換できない場合 ()または変換 ()。詳細については、例を参照してください。
制限
- 変換は、文字列から日付および文字列から数値に対してのみ可能です
- サーバー上の.NetFramework共通言語ランタイム(CLR)の存在に依存します。
- SQL-92標準仕様には含まれていないため、他のRDBMSへの移植には問題があります。
- 文字列の解析に関しては、パフォーマンスのオーバーヘッドがあります。
例
A。長い日付文字列の変換
SELECT PARSE('Monday, June 8, 2020' as datetime USING 'en-US')
上記の例は、 datetimeに変換される長い日付文字列です。 米国の英語文化を使用した価値。そして、これが PARSEの場所です ()は最善を尽くします。
これは、 CAST を使用すると、上記のコードが失敗するためです。 ()または変換 ()。
B。通貨記号を使用して金額を変換する
SELECT PARSE('€1024,01' as money using 'de-DE')
次に、 CASTを使用して変換を実行してみます ()および変換 ()
SELECT CONVERT(money,'€1024,01')
SELECT CAST('€1024,01' as money)
ステートメントはエラーをスローしませんが、それでも、この予期しない結果を見てください:
その結果、値は1024.01ではなく102401.00に変換されました。
これまでのところ、最初の3つの方法は、チェックしない限りエラーが発生しやすいことがわかりました。それでも、4番目の方法が誤った結果の解決策になる可能性があります。
4。 TRY_CAST()、TRY_CONVERT()、またはTRY_PARSE()を使用したSQLデータ変換
最後に、SQLデータ変換の最後の方法は、最初の3つのバリアントを使用しますが、プレフィックスはTRY_です。
それでも、違いは何ですか?
これらは、TRY_プレフィックスなしで前の3つと同じパラメーターを持っています。ただし、違いは、 NULLを返すことです。 値を変換できない場合。これで、値を3つのいずれかで明示的に変換できない場合、エラーが発生します。理解を深めるには、以下の例を参照してください。
いつ使用するか
CASEのような条件ステートメントで3つのいずれかを使用できます いつ またはIIF エラーをテストします。
制限
そのうちの3つには、変換できない値を除いて、TRY_プレフィックスがないものと同じ制限があります。
例
A。 TRY_CAST()を使用して、IIFを使用して変換が成功するかどうかをテストします。
SELECT IIF(TRY_CAST('111b' AS real) IS NULL, 'Cast failed', 'Cast succeeded') AS Result
「111b」は実際のに変換できないため、上記のコードは「CastFailed」を返します。 。値から「b」を削除すると、「キャスト成功」が返されます。
B。特定の形式の日付でTRY_CONVERT()を使用する
SET DATEFORMAT dmy;
SELECT TRY_CONVERT(datetime2, '12/31/2010') AS Result
これにより、 NULLが返されます フォーマットはdmyを使用するため または日-月-年。そして、 TRY_CONVERTの入力式 ()は mdyの形式です または月-日-年。月の値が31であるため、エラーがトリガーされました。
C。ランタイムエラーを生成するTRY_PARSE()を使用する
SELECT
CASE WHEN TRY_PARSE('10/21/2133' AS smalldatetime USING 'en-US') IS NULL
THEN 'True'
ELSE 'False'
END AS Result
このコードは、以下に示すようにランタイムエラーを生成します:
SQLデータ変換の4つのすぐに使用できるメソッドについては以上です。しかし、まだまだあります。
暗黙的な変換を使用したSQLデータ変換はどうですか?
次に、暗黙の変換について考えてみましょう。これはサイレントメソッドです。
なぜ沈黙するのですか?
あなたはすでにそれをしているかもしれませんが、あなたはそれに気づいていないからです。または、少なくとも、それが起こっていることは知っていますが、それを無視しています。
つまり、これはSQLが関数なしで自動的に実行するタイプの変換です。
例を挙げましょう:
DECLARE @char CHAR(25)
DECLARE @varchar VARCHAR(25)
DECLARE @nvarchar NVARCHAR(25)
DECLARE @nchar NCHAR(25)
SET @char = 'Live long and prosper'
SET @varchar = @char
SET @nvarchar = @varchar
SET @nchar = @nvarchar
SELECT @char AS [char], @varchar AS [varchar], @nvarchar AS [nvarchar], @nchar AS [nchar]
上記のコードは正常に実行されます。自分で試してみると、以下のような結果になります。
日付でこれを試してみましょう:
DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2
SET @datetime = '12/31/2050 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime
SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]
予想どおり、これにより成功した結果が得られます:
今回は数字で試してみましょう:
DECLARE @int int
DECLARE @real real
DECLARE @decimal decimal
DECLARE @float float
SET @int = 1701
SET @real = @int
SET @decimal = @real
SET @float = @decimal
SELECT @int as [int], @real as [real], @decimal as [decimal], @float as [float]
それでも成功ですよね?
これまで、かなり類似したタイプのデータに適した単純な値を使用してきました。次のレベル、つまり数字から文字列に移りましょう。
DECLARE @number int
DECLARE @string varchar(5)
SET @number = 1701
SET @string = @number
SELECT @number as [number], @string as [string]
以下の結果からわかるように、これは正常に変換されます。
SQLServerがデータの変換方法を「推測」しようとする例は他にもたくさんあります。このリファレンスからわかるように、明示的な変換が必要なインスタンスと比較して、多くのインスタンスがあります。
SQL Serverはこれを許可しているので、これはコード全体でこれを自由に実行できることを意味しますか?
暗黙的な変換の警告
一つには、それは便利かもしれません。ただし、各データ型の制限に達すると、チェックを外したままにすると、暗黙的な変換が少し危険であることがわかります。
以下の例を考えてみましょう:
DECLARE @char char(25)
DECLARE @varchar varchar(25)
DECLARE @nvarchar nvarchar(25)
DECLARE @nchar nchar(25)
SET @nvarchar = N'I ❤ U!'
SET @nchar = @nvarchar
SET @char = @nchar
SET @varchar = @nchar
SELECT @char as [char], @varchar as [varchar], @nvarchar as [nvarchar], @nchar as [nchar]
絵文字の値を見ましたか?これはUnicode値としてカウントされます。
上記のすべてのステートメントは正常に実行されますが、 varcharのような非Unicodeタイプの変数 およびchar 予期しない結果になります。以下の結果を参照してください:
それでも、問題はそれだけではありません。値が範囲外になると、エラーが表示されます。日付の例を考えてみましょう:
DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2
SET @datetime = '12/31/2374 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime
SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]
日時の割り当て smalldatetimeの値 以下に示すように、変数はエラーをトリガーします:
ただし、暗黙の変換を処理するときにも注意する必要があるもう1つの注意点があります。それは、パフォーマンスのオーバーヘッドです。これがホットなトピックであることを考えると、別のセクションを設ける価値があります。
さまざまなSQLデータ変換方法のパフォーマンスへの影響
信じられないかもしれませんが、SQLデータ変換方法が異なれば、実際の状況ではパフォーマンスが異なります。また、パフォーマンスの落とし穴を回避できるように、少なくともこれに注意する必要があります。
CAST()、CONVERT()、およびPARSE()のパフォーマンス
まず、キャストの方法を見てみましょう。 ()、変換 ()、および PARSE ()どちらが速いかを比較することにより、自然条件下で実行します。ここから取った例の概念を適応させて証明します。以下のコードを検討してください:
USE AdventureWorks
GO
SET STATISTICS TIME ON
SELECT CAST([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SELECT CONVERT(int,[NationalIDNumber]) FROM [HumanResources].[Employee]
SELECT PARSE([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SET STATISTICS TIME OFF
GO
それでは、 AdventureWorksを使用するコードを調べてみましょう。 Microsoftのデータベース:
- 統計時間をオンに設定 各SELECTのCPU時間と経過時間を出力します ステートメント
- 次に、デモンストレーション目的で変換するために選択した列は[ NationalIDNumber ]、タイプは nvarchar(15) 。
- また、変換は文字列から整数になります: nvarchar(15) int 。
- 最後に、 SET STATISTICS TIMEを復元します 以前の値に
メッセージの出力に注意してください クエリ結果のタブ:
この例を使用して考え出したものは次のとおりです。
- CASTであることを証明します ()は最速(1ミリ秒)で PARSE ()は最も遅い(318ミリ秒)を実行します。
- データの変換に使用する関数を決定するときは、この優先順位に従います:( 1 )キャスト ()( 2 )変換 ()( 3 ) PARSE ()。
- 各関数が関連する場合は覚えておいて、使用する関数を決定する際には制限を考慮してください。
暗黙的な変換の実行方法
この時点で、CAST()などの関数を使用してデータを変換することをお勧めしていることがわかります。このセクションでは、その理由がわかります。
WideWorldImportersを使用してこのクエリを検討してください Microsoftのデータベース。実行する前に、実際の実行プランを含めるを有効にしてください SQL Server Management Studio 。
USE WideWorldImporters
GO
SELECT
[CustomerID]
,[OrderID]
,[OrderDate]
,[ExpectedDeliveryDate]
FROM [Sales].[Orders]
WHERE [CustomerID] like '487%'
上記のクエリでは、[ CustomerIDを使用して販売注文の結果をフィルタリングします ]「487%」のように。これは、 intの暗黙的な変換がどのような影響を与えるかを示すためだけのものです。 データ型はvarcharにあります 。
次に、以下の実行計画を検討します。
ご覧のとおり、 SELECTに警告があります アイコン。したがって、マウスにカーソルを合わせるとツールチップが表示されます。次に、警告メッセージ、つまり CONVERT_IMPLICITに注目してください。 。
続行する前に、この CONVERT_IMPLICIT 警告は、SQLServerの暗黙的な変換を実行する必要がある場合に発生します。問題を詳しく見てみましょう。以下に説明するように、警告には2つの部分があります。
- CONVERT_IMPLICIT クエリプランの選択で「CardinalityEstimate」に影響を与える可能性があります。
- CONVERT_IMPLICIT クエリプランの選択で「SeekPlan」に影響を与える可能性があります。
どちらも、クエリの実行が遅くなることを示しています。もちろん、その理由はわかっています。 LIKE を使用して、意図的に暗黙的な変換を強制します 整数値の演算子。
そのポイントは何ですか?
- データの暗黙的な変換により、SQLServerはCONVERT_IMPLICITを使用します 、クエリの実行が遅くなります。
- この問題を修正するには、暗黙的な変換の使用を排除します。この例では、[ CustomerID ]いいね 「487%」、[ CustomerID を変更することで修正できます ] =487。クエリを修正すると、クエリ実行プランが変更され、以前に警告が削除され、インデックススキャン演算子がインデックスシークに変更されます。最終的に、パフォーマンスが向上します。
ハッピーエンド?はい!
要点
示されているように、SQLServerに暗黙の変換を使用して変換を実行させることはできません。データを変換するときに何を使用するかを決定する際は、優先順位に従うことをお勧めします。
- まず、そのまま変換する必要がある場合は、キャストを使用します ()。他のRDBMへの移植に関しては、より標準化された機能です。
- 次に、フォーマットされたデータが必要な場合は、変換を使用します ()。
- 第3に、両方がキャストの場合 ()および変換 ()仕事に失敗した場合は、 PARSEを使用してください ()。
- 最後に、変換時のエラーをテストするには、 TRY_CASTを使用します ()、 TRY_CONVERT ()、または TRY_PARSE ()。
さて、今のところこれですべてです。これがあなたの次のコーディングの冒険に役立つことを願っています。足を折る!
MicrosoftからのSQLデータ変換のトピックの詳細については、以下を参照してください。
- キャストと変換
- PARSE
- TRY_CAST、TRY_CONVERT、およびTRY_PARSE