搜尋
首頁資料庫mysql教程如何将数据导入到 SQL Server Compact Edition 数据库中(三)

系列文章导航: 如何将数据导入到 SQL Server Compact Edition 数据库中(一) 如何将数据导入到 SQL Server Compact Edition 数据库中(二) 摘要:时隔近半年了,不知道大家是否还记得,我在本系列的第一篇文章的总结中提到,创建 SQL Server CE 数据库表

系列文章导航:
如何将数据导入到 SQL Server Compact Edition 数据库中(一)
如何将数据导入到 SQL Server Compact Edition 数据库中(二)

摘要:时隔近半年了,不知道大家是否还记得,我在本系列的第一篇文章的总结中提到,创建 SQL Server CE 数据库表结构的 SQL 语句是可以自动生成的。那么本系列的第三篇文章就向大家介绍一种比较简单的方法。

ADO.NET 中的 IDataReader.GetSchemaTable 方法可以返回一个 DataTable,它描述了 IDataReader 查询结果中各列的元数据。列的元数据包含了列的名称、数据类型、大小、是否为主键字段、是否为自动增长字段……等等。有了这些元数据,我们就可以通过编写几段 C#/VB.NET 代码,实现创建 SQL Server CE 数据库表结构的 SQL 语句的自动生成。以下方法是生成创建表 SQL 语句的主要代码:

/// 


/// 生成创建数据库表结构的 SQL 语句。
/// 
private static string GenerateTableSchemaSql(IDbConnection connection, string queryString)
{
    StringBuilder tableSql 
= new StringBuilder(); 

    IDbCommand command 
= connection.CreateCommand();
    command.CommandText 
= queryString; 

    
try
    {
        
/* 获取查询结果各列的元数据 */
        DataTable schemaTable 
= null;
        
using (IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo))
        {
            schemaTable 
= reader.GetSchemaTable();
        } 

        
/* 生成创建表定义语句 */
        
string tableName = schemaTable.Rows[0]["BaseTableName"].ToString();
        tableSql.Append(
"CREATE TABLE [").Append(tableName).AppendLine("] ("); 

        
/* 生成各列的定义语句 */
        
string columnName;
        
string allowDBNull;
        DataRow row;
        
bool hasKey = false;
        StringBuilder sbPKFields 
= new StringBuilder();
        
for (int i = 0; i  schemaTable.Rows.Count; i++)
        {
            
if (i != 0) tableSql.AppendLine(","); 

            row 
= schemaTable.Rows[i];
            columnName 
= (string)row["ColumnName"];
            allowDBNull 
= ((bool)row["AllowDBNull"== true ? "NULL" : "NOT NULL"); 

            
if ((bool)row["IsKey"])
            {
                sbPKFields.AppendFormat(
"[{0}],", columnName);
                hasKey 
= true;
            }
            tableSql.AppendFormat(
"  [{0}] {1} {2}", columnName, GetSqlCeDataType(row), allowDBNull);
        } 

        
/* 生成主键约束语句 */
        
if (hasKey)
        {
            
string pkFields = sbPKFields.ToString().TrimEnd(',');
            tableSql.AppendLine(
",");
            tableSql.Append(
"  CONSTRAINT PK_").Append(tableName.Replace(" ", "_")).Append(" PRIMARY KEY(").Append(pkFields).AppendLine(")");
        }
        tableSql.AppendLine(
");");
    }
    
catch (Exception ex)
    {
        Debug.WriteLine(ex);
    } 

    
return tableSql.ToString();
}

同样的,该方法也使用了 ADO.NET 的接口类,不依赖于具体的数据库类型。该方法的核心就是通过 IDataReader.GetSchemaTable 方法获取查询结果各列元数据,相关代码如下:

IDbCommand command = connection.CreateCommand();
command.CommandText 
= queryString;
DataTable schemaTable 
= null;
using (IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
    schemaTable 
= reader.GetSchemaTable();
}

首先,IDbCommand 的 CommandText 属性一般是针对一个表的 SELECT 查询语句,如:SELECT * FROM Customers。其次,IDbCommand.ExecuteReader 方法必须传入 CommandBehavior.KeyInfo 参数,这样才能获取到列的主键元数据。最后,通过 IDataReader.GetSchemaTable 方法返回一个包含查询结果所有列的元数据的 DataTable。关于 IDataReader.GetSchemaTable 方法的详细使用说明,请阅读《HOW TO:使用 DataReader GetSchemaTable 方法和 Visual C# .NET 检索列架构》

IDataReader.GetSchemaTable 返回的 SchemaTable 对列数据类型的描述是用相应的 .NET 数据类型,如 SQL Server CE 的 int 类型对应的是 .NET 的 System.Int32 类型。另外需要注意的是,由于 Windows Mobile 只支持 Unicode 编码,因此 SQL Server CE 只支持 NChar, NVarChar 和 NText 等 Unicode 字符数据类型,而不支持 Char, VarChar 和 Text 等非 Unicode 字符数据类型。所以,我们需要编写一个方法,它根据列的 .NET 数据类型找到对应的 SQL Server CE 数据类型。这个方法的代码如下所示:

/// 


/// 从 .NET 数据类型获取对应的 SQL Server CE  类型名称。
/// 
private static string GetSqlCeNativeType(Type systemType)
{
    
string typeName = systemType.ToString();
    
switch (typeName)
    {
        
case "System.Boolean":
            
return "bit";
        
case "System.Byte":
            
return "tinyint";
        
case "System.Byte[]":
            
return "image";
        
case "System.DateTime":
            
return "datetime";
        
case "System.Decimal":
            
return "numeric";
        
case "System.Double":
            
return "float";
        
case "System.Guid":
            
return "uniqueidentifier";
        
case "System.Int16":
            
return "smallint";
        
case "System.Int32":
            
return "integer";
        
case "System.Int64":
            
return "bigint";
        
case "System.Single":
            
return "real";
        
case "System.String":
            
return "nvarchar";
        
default:
            
throw new ApplicationException(string.Format("找不到 {0} 类型对应的 SQL Server CE 数据类型。", typeName));
    }
}

当然,仅仅知道列的数据类型还不够,我们需要为某些列的数据类型加上长度、精度或小数位数等列大小信息。可以通过下面的方法实现:

/// 


/// 从 ColumnSchemaRow 获取 SQL Server CE 数据类型。
/// 
private static string GetSqlCeDataType(DataRow columnSchemaRow)
{
    Type type 
= columnSchemaRow["DataType"as Type;
    
string dataType = GetSqlCeNativeType(type);
    
switch (dataType)
    {
        
case "numeric":
            Int16 precision 
= (Int16)columnSchemaRow["NumericPrecision"];
            Int16 scale 
= (Int16)columnSchemaRow["NumericScale"];
            Int32 colsize 
= (Int32)columnSchemaRow["ColumnSize"];
            
if (precision != 0 && scale != 0 && scale != 255)
            {
                dataType 
= string.Format("{0}({1},{2})", dataType, precision, scale);
            }
            
else if (scale == 255 && colsize == 8)
            {
                dataType 
= "money";
            }
            
break;
        
case "nvarchar":
            
int columnSize = (int)columnSchemaRow["ColumnSize"];
            
if (columnSize > 4000)
            {
                dataType 
= "ntext";
            }
            
else
            {
                dataType 
= string.Format("{0}({1})", dataType, columnSize);
            }
            
break;
    }
    
return dataType;
}

关于 SQL Server 2005 Compact Edition 数据类型的描述,详细请参考联机丛书。使用上面的几段代码,对 SQL Server 2000 自带的 Northwind 数据库的 Customers 表生成创建数据库表的 SQL 语句,生成结果如下:

CREATE TABLE [Customers] (
  
[CustomerID] nvarchar(5NOT NULL,
  
[CompanyName] nvarchar(40NOT NULL,
  
[ContactName] nvarchar(30NULL,
  
[ContactTitle] nvarchar(30NULL,
  
[Address] nvarchar(60NULL,
  
[City] nvarchar(15NULL,
  
[Region] nvarchar(15NULL,
  
[PostalCode] nvarchar(10NULL,
  
[Country] nvarchar(15NULL,
  
[Phone] nvarchar(24NULL,
  
[Fax] nvarchar(24NULL,
  
CONSTRAINT PK_Customers PRIMARY KEY([CustomerID])
);

对于 SQL Server 2000,我们可以从信息架构视图查询 INFORMATION_SCHEMA.TABLES 出数据库有哪些表,并一次性对所有表进行生成。以下是 INFORMATION_SCHEMA.TABLES 视图各列的说明:

列名 数据类型 说明
TABLE_CATALOG nvarchar(128) 表限定符。
TABLE_SCHEMA nvarchar(128) 包含该表的架构的名称。
TABLE_NAME sysname 表名。
TABLE_TYPE varchar(10) 表的类型。可以是 VIEW 或 BASE TABLE。

我们可以通过以下方法获得 Northwind 数据库所有用户表名的数组:

/// 


/// 从一个打开的 SQL Server 数据库连接获取数据库的表名数组。
/// 
private static string[] GetTableNames(IDbConnection connection)
{
    IDbCommand command 
= connection.CreateCommand(); 

    
// 从 SQL Server 信息架构视图获取 Northwind 数据库所有表的名称
    command.CommandText = @"SELECT * FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE='BASE TABLE' AND TABLE_CATALOG='Northwind'
"

    List
string> tableNames = new Liststring>();
    
using (IDataReader reader = command.ExecuteReader())
    {
        
while (reader.Read())
        {
            tableNames.Add(reader[
"TABLE_NAME"].ToString());
        }
    }
    
return tableNames.ToArray();
}

有了 GetTableNames 方法,我们就可以一次性对 Northwind 数据库的所有用户表生成相应的创建 SQL Server CE 数据库表结构的 SQL 语句。

static void Main(string[] args)
{
    
string connectionString = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=True";
    IDbConnection connection 
= new SqlConnection(connectionString);
    connection.Open(); 

    
string[] tableNames = GetTableNames(connection); 

    
string queryString, createTableSql;
    
foreach (string tableName in tableNames)
    {
        queryString 
= string.Format("select * from [{0}]", tableName);
        createTableSql 
= GenerateTableSchemaSql(connection, queryString); 

        Console.WriteLine(createTableSql);
        Debug.WriteLine(createTableSql);
    } 

    connection.Close();
    Console.Read();
}

示例程序运行效果如下图所示:
如何将数据导入到 SQL Server Compact Edition 数据库中(三)

总结:阅读完本文,相信你已经了解了如何利用 ADO.NET 的 IDataReader.GetSchemaTable 方法获得服务器端数据库表的元数据,并用于生成对应的创建 SQL Server CE 数据库表的 SQL 语句。本系列文章可能还会有更精彩的续篇,我会将平时积累的关于 SQL Server CE 数据导入的一些经验充实到本系列中。

示例代码下载:sqlce_data_import3.rar

更新记录:
2008-2-9 修正对money数据类型的支持,修正对包含空格的表名的支持。

作者:黎波
博客:http://upto.cnblogs.com/
日期:2008年1月31日

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
在MySQL中使用視圖的局限性是什麼?在MySQL中使用視圖的局限性是什麼?May 14, 2025 am 12:10 AM

mysqlviewshavelimitations:1)他們不使用Supportallsqloperations,限制DatamanipulationThroughViewSwithJoinsOrsubqueries.2)他們canimpactperformance,尤其是withcomplexcomplexclexeriesorlargedatasets.3)

確保您的MySQL數據庫:添加用戶並授予特權確保您的MySQL數據庫:添加用戶並授予特權May 14, 2025 am 12:09 AM

porthusermanagementinmysqliscialforenhancingsEcurityAndsingsmenting效率databaseoperation.1)usecReateusertoAddusers,指定connectionsourcewith@'localhost'or@'%'。

哪些因素會影響我可以在MySQL中使用的觸發器數量?哪些因素會影響我可以在MySQL中使用的觸發器數量?May 14, 2025 am 12:08 AM

mysqldoes notimposeahardlimitontriggers,butacticalfactorsdeterminetheireffactective:1)serverConfiguration impactactStriggerGermanagement; 2)複雜的TriggerSincreaseSySystemsystem load; 3)largertablesslowtriggerperfermance; 4)highConconcConcrencerCancancancancanceTigrignecentign; 5); 5)

mysql:存儲斑點安全嗎?mysql:存儲斑點安全嗎?May 14, 2025 am 12:07 AM

Yes,it'ssafetostoreBLOBdatainMySQL,butconsiderthesefactors:1)StorageSpace:BLOBscanconsumesignificantspace,potentiallyincreasingcostsandslowingperformance.2)Performance:LargerrowsizesduetoBLOBsmayslowdownqueries.3)BackupandRecovery:Theseprocessescanbe

mySQL:通過PHP Web界面添加用戶mySQL:通過PHP Web界面添加用戶May 14, 2025 am 12:04 AM

通過PHP網頁界面添加MySQL用戶可以使用MySQLi擴展。步驟如下:1.連接MySQL數據庫,使用MySQLi擴展。 2.創建用戶,使用CREATEUSER語句,並使用PASSWORD()函數加密密碼。 3.防止SQL注入,使用mysqli_real_escape_string()函數處理用戶輸入。 4.為新用戶分配權限,使用GRANT語句。

mysql:blob和其他無-SQL存儲,有什麼區別?mysql:blob和其他無-SQL存儲,有什麼區別?May 13, 2025 am 12:14 AM

mysql'sblobissuitableForStoringBinaryDataWithInareLationalDatabase,而ilenosqloptionslikemongodb,redis和calablesolutionsolutionsolutionsoluntionsoluntionsolundortionsolunsonstructureddata.blobobobissimplobisslowdeperformberbutslowderformandperformancewithlararengedata;

mySQL添加用戶:語法,選項和安全性最佳實踐mySQL添加用戶:語法,選項和安全性最佳實踐May 13, 2025 am 12:12 AM

toaddauserinmysql,使用:createUser'username'@'host'Indessify'password'; there'showtodoitsecurely:1)choosethehostcarecarefullytocon trolaccess.2)setResourcelimitswithoptionslikemax_queries_per_hour.3)usestrong,iniquepasswords.4)Enforcessl/tlsconnectionswith

MySQL:如何避免字符串數據類型常見錯誤?MySQL:如何避免字符串數據類型常見錯誤?May 13, 2025 am 12:09 AM

toAvoidCommonMistakeswithStringDatatatPesInMysQl,CloseStringTypenuances,chosethirtightType,andManageEngencodingAndCollat​​ionsEttingSefectery.1)usecharforfixed lengengtrings,varchar forvariable-varchar forbariaible length,andtext/blobforlargerdataa.2 seterters seterters seterters

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。