2009年12月26日土曜日

SQL-Serverと.NET Frameworkの型の違いについて

今回の記事では、SQL-Server 2008と、.NET Frameworkの型の違いについて書かせていただきます。

SQL-Server 2008には、(2005の時代からですが)SQL CLRという極めて強力な機能がありますけれど、SQL-Serverと.NET Frameworkという二つの違う環境を結びつける都合上、どうしても「型の違い」という悩みが発生してしまいます。

たとえば、SQL-ServerのFloat型に該当する.NET Framework側の型はDouble型ですし、SQL-ServerのNVarChar型は、.NET Framework側ではString型になりますが、VarChar型も同じString型になってしまいます。

しかもこの型の違いは、単にキャストしてもうまくいかないんで、変換配列みたいなものを作っておいて力技で変換かけてあげないといけない・・・のかな?

今後のために、型の対応表の意味も含めて、変換「用の」配列作成プログラムを書いてみました。
単なる配列データを作るだけで、実際に変換処理をするわけではないです。
この配列を利用して変換処理を別途作成する・・・という材料的なものですね。
SQL CLRでの利用を前提としています。また、ズラズラと長いのでスクリーンショットではなくてテキストで直接記述してます。

まだこの材料を具体的には使ってはいないのですが、SQL CLRでストアドプロシージャを書く時、たとえば・・・そうですね、特に、DataTableオブジェクトの内容をSQL-Serverに返す時なんかは、型の違いを吸収しないといけないので必要かも。

両環境での型の違いを知らないと、ストアドプロシージャではかなり厳しいです。
へたをすると、SqlDataRecordを作れないという事態に発展してしまいます。


//*******************************************************
//* (SQL-Server)SqlDbTypeと(ADO.NET)DbTypeの比較構造体
//*******************************************************
private struct stc_SQLADOTypes
{
public SqlDbType SQL; //SQL型
public DbType ADO; //ADO.NET型
public Int16 STYLE; //文字型スタイル
}

//*******************************************************************************
//* 関数
//*******************************************************************************
private static stc_SQLADOTypes[] fnc_GetSQLADOTypes()
{
stc_SQLADOTypes[] useArr_result = new stc_SQLADOTypes[28];
Int32 i = 0;
try
{
//@@@@@@@@@@[LOOP-START]@@@@@@@@@@
for (i = 0; i < useArr_result.Length-1; i++)
{
switch (i)
{
case 0:
useArr_result[i].SQL = SqlDbType.Binary;
useArr_result[i].ADO = DbType.Binary;
break;
case 1:
useArr_result[i].SQL = SqlDbType.Timestamp;
useArr_result[i].ADO = DbType.Binary;
break;
case 2:
useArr_result[i].SQL = SqlDbType.VarBinary;
useArr_result[i].ADO = DbType.Binary;
break;
case 3:
useArr_result[i].SQL = SqlDbType.Bit;
useArr_result[i].ADO = DbType.Boolean;
break;
case 4:
useArr_result[i].SQL = SqlDbType.TinyInt;
useArr_result[i].ADO = DbType.Byte;
break;
case 5:
useArr_result[i].SQL = SqlDbType.Date;
useArr_result[i].ADO = DbType.Date;
break;
case 6:
useArr_result[i].SQL = SqlDbType.DateTime;
useArr_result[i].ADO = DbType.DateTime;
break;
case 7:
useArr_result[i].SQL = SqlDbType.DateTime2;
useArr_result[i].ADO = DbType.DateTime2;
break;
case 8:
useArr_result[i].SQL = SqlDbType.DateTimeOffset;
useArr_result[i].ADO = DbType.DateTimeOffset;
break;
case 9:
useArr_result[i].SQL = SqlDbType.Decimal;
useArr_result[i].ADO = DbType.Decimal;
break;
case 10:
useArr_result[i].SQL = SqlDbType.Money;
useArr_result[i].ADO = DbType.Decimal;
break;
case 11:
useArr_result[i].SQL = SqlDbType.SmallMoney;
useArr_result[i].ADO = DbType.Decimal;
break;
case 12:
useArr_result[i].SQL = SqlDbType.Float;
useArr_result[i].ADO = DbType.Double;
break;
case 13:
useArr_result[i].SQL = SqlDbType.UniqueIdentifier;
useArr_result[i].ADO = DbType.Guid;
break;
case 14:
useArr_result[i].SQL = SqlDbType.SmallInt;
useArr_result[i].ADO = DbType.Int16;
break;
case 15:
useArr_result[i].SQL = SqlDbType.Int;
useArr_result[i].ADO = DbType.Int32;
break;
case 16:
useArr_result[i].SQL = SqlDbType.BigInt;
useArr_result[i].ADO = DbType.Int64;
break;
case 17:
useArr_result[i].SQL = SqlDbType.Variant;
useArr_result[i].ADO = DbType.Object;
break;
case 18:
useArr_result[i].SQL = SqlDbType.Real;
useArr_result[i].ADO = DbType.Single;
break;
case 19:
useArr_result[i].SQL = SqlDbType.VarChar;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 20:
useArr_result[i].SQL = SqlDbType.Char;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 21:
useArr_result[i].SQL = SqlDbType.NChar;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 22:
useArr_result[i].SQL = SqlDbType.NText;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 23:
useArr_result[i].SQL = SqlDbType.NChar;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 24:
useArr_result[i].SQL = SqlDbType.Text;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 25:
useArr_result[i].SQL = SqlDbType.NVarChar;
useArr_result[i].ADO = DbType.String;
useArr_result[i].STYLE = 1;
break;
case 26:
useArr_result[i].SQL = SqlDbType.Time;
useArr_result[i].ADO = DbType.Time;
break;
case 27:
useArr_result[i].SQL = SqlDbType.Xml;
useArr_result[i].ADO = DbType.Xml;
break;
}
}
//@@@@@@@@@@[LOOP-END ]@@@@@@@@@@
}
catch (System.Exception obj_err)
{
throw obj_err;
}
return useArr_result;
}