需要在.net中使用数据库表模式获取空数据表

发布于 2024-08-22 23:36:13 字数 50 浏览 2 评论 0原文

使用 sql server 表的架构创建空 DataTable 对象的最佳方法是什么?

What is the best way to create an Empty DataTable object with the schema of a sql server table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

一枫情书 2024-08-29 23:36:13

所有这些解决方案都是正确的,但如果您想要一个针对此场景简化的纯代码解决方案。

由于在 ExecuteReader 函数上指定了 CommandBehavior.SchemaOnly,因此此解决方案中未返回任何数据(命令行为文档)

CommandBehavior.SchemaOnly 解决方案将添加 SET FMTONLY ON; sql 在为您执行查询之前,这样可以保持代码干净。

public static DataTable GetDataTableSchemaFromTable(string tableName, SqlConnection sqlConn, SqlTransaction transaction)
{
    DataTable dtResult = new DataTable();

    using (SqlCommand command = sqlConn.CreateCommand())
    {
        command.CommandText = String.Format("SELECT TOP 1 * FROM {0}", tableName);
        command.CommandType = CommandType.Text;
        if (transaction != null)
        {
            command.Transaction = transaction;
        }

        SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly);

        dtResult.Load(reader);

    }

    return dtResult;
}

All of these solutions are correct, but if you want a pure code solution that is streamlined for this scenario.

No Data is returned in this solution since CommandBehavior.SchemaOnly is specified on the ExecuteReader function(Command Behavior Documentation)

The CommandBehavior.SchemaOnly solution will add the SET FMTONLY ON; sql before the query is executed for you so, it keeps your code clean.

public static DataTable GetDataTableSchemaFromTable(string tableName, SqlConnection sqlConn, SqlTransaction transaction)
{
    DataTable dtResult = new DataTable();

    using (SqlCommand command = sqlConn.CreateCommand())
    {
        command.CommandText = String.Format("SELECT TOP 1 * FROM {0}", tableName);
        command.CommandType = CommandType.Text;
        if (transaction != null)
        {
            command.Transaction = transaction;
        }

        SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly);

        dtResult.Load(reader);

    }

    return dtResult;
}
-黛色若梦 2024-08-29 23:36:13

尝试:
SELECT TOP 0 * FROM [TableName]

并使用 SQLDataAdapter 填充数据集,然后从该数据集中获取表。

Try:
SELECT TOP 0 * FROM [TableName]

and use SQLDataAdapter to fill a DataSet, then get the Table from that DataSet.

葬花如无物 2024-08-29 23:36:13

我认为值得一提的声明是 SET FMTONLY

SET FMTONLY ON;
SELECT * FROM SomeTable
SET FMTONLY OFF;

当 SET FMTONLY 打开时,不会因为请求而处理任何行或将其发送到客户端。

这很方便的原因是您可以提供任何查询/存储过程并仅返回结果集的元数据。

A statement I think is worth mentioning is SET FMTONLY:

SET FMTONLY ON;
SELECT * FROM SomeTable
SET FMTONLY OFF;

No rows are processed or sent to the client because of the request when SET FMTONLY is turned ON.

The reason this can be handy is because you can supply any query/stored procedure and return just the metadata of the resultset.

世态炎凉 2024-08-29 23:36:13

假设您可以连接到包含要在您想要执行此操作时复制的表的 SQL 数据库,则可以使用传统结果集到数据表的转换,用作

select * from <tablename> where 1=2

源查询。

这将返回一个具有源表结构的空结果集。

Assuming that you can connect to the SQL database which contains the table you want to copy at the point it time you want to do this, you could use a conventional resultset to datatable conversion, using

select * from <tablename> where 1=2

as your source query.

This will return an empty result set with the structure of the source table.

醉生梦死 2024-08-29 23:36:13

这就是我所做的:

var conn = new SqlConnection("someConnString");
var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM MyTable; SET FMTONLY OFF;",conn); 
var dt = new DataTable();
conn.Open();
dt.Load(cmd.ExecuteReader());
conn.Dispose();

效果很好。谢谢阿达德夫。

Here's what I did:

var conn = new SqlConnection("someConnString");
var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM MyTable; SET FMTONLY OFF;",conn); 
var dt = new DataTable();
conn.Open();
dt.Load(cmd.ExecuteReader());
conn.Dispose();

Works well. Thanks AdaTheDev.

白况 2024-08-29 23:36:13
Class BlankTableWithSourceTableSchema
    Inherits DataTable
    Public Sub New(ByVal connstr As String, ByVal sourcetable As String)
        Try
            Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr)
                Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection)
                adapter.TableMappings.Add("Table", "ABlankTable")
                adapter.FillSchema(Me, SchemaType.Mapped)
            End Using
        Catch ex As Exception
        End Try
    End Sub
End Class
Class BlankTableWithSourceTableSchema
    Inherits DataTable
    Public Sub New(ByVal connstr As String, ByVal sourcetable As String)
        Try
            Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr)
                Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection)
                adapter.TableMappings.Add("Table", "ABlankTable")
                adapter.FillSchema(Me, SchemaType.Mapped)
            End Using
        Catch ex As Exception
        End Try
    End Sub
End Class
鹿港小镇 2024-08-29 23:36:13

这有效:

Class BlankTableWithSourceTableSchema
    Inherits DataTable
    Public Sub New(ByVal connstr As String, ByVal sourcetable As String)
        Try
            Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr)
                Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection)
                adapter.TableMappings.Add("Table", "ABlankTable")
                adapter.FillSchema(Me, SchemaType.Mapped)
            End Using
        Catch ex As Exception
        End Try
    End Sub
End Class

this works:

Class BlankTableWithSourceTableSchema
    Inherits DataTable
    Public Sub New(ByVal connstr As String, ByVal sourcetable As String)
        Try
            Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr)
                Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection)
                adapter.TableMappings.Add("Table", "ABlankTable")
                adapter.FillSchema(Me, SchemaType.Mapped)
            End Using
        Catch ex As Exception
        End Try
    End Sub
End Class
白云不回头 2024-08-29 23:36:13

我知道这是一个老问题并且特定于 SQL Server。但是,如果您正在寻找可跨不同数据库工作的通用解决方案,请使用 Richard 的解决方案,但将其修改为使用 "SELECT * FROM {0} WHERE 1=0" 并将类型更改为使用通用ADO.Net 类型 IDataReader、IDbCommand 等。

大多数现代关系数据库都足够智能,可以识别 1=0 条件,并且不会像常规表扫描查询那样运行它。我已经在 SQL Server、Oracle 和 DB2 上尝试过了,表也只有很少的 1 亿条记录。所有这些都会在几毫秒内返回空结果。

I know that this is an old question and specific to SQL Server. But if you are looking for generic solution that will work across different databases, use Richard's solution, but modify it to use "SELECT * FROM {0} WHERE 1=0" and change the types to use generic ADO.Net types IDataReader, IDbCommand etc.

Most modern relational databases are intelligent enough to identify the 1=0 condition and will not run it like a regular tablescan query. I have tried this on SQL Server, Oracle and DB2 with tables have few 100 million records also. All do return empty result back in matter of few milliseconds.

横笛休吹塞上声 2024-08-29 23:36:13

这就是我所做的,它提供了一个可供使用的空白数据表:

SqlConnection _sqlConnection = new SqlConnection ();
_sqlConnection.ConnectionString = @"Data Source=<SQL_Server/Instance>; Initial Catalog=<database_name>; Integrated Security=False; User ID=<user_id>;Password=<passowrd>";
_sqlConnection.Open ();
SqlCommand _sqlCommand = new SqlCommand ( "select * from DatabaseName.dbo.viewName", _sqlConnection ); 
_dataSet = new DataSet ();
_sqlDataAdapter = new SqlDataAdapter ( _sqlCommand );
_sqlDataAdapter.Fill ( _dataSet );
_schemaTable = new DataTable ();
_sqlDataAdapter.FillSchema ( _schemaTable, SchemaType.Source );
dataGridView.DataSource = _schemaTable;
_sqlConnection.Close ();

Here's what I did, which provides a blank DataTable ready to be used:

SqlConnection _sqlConnection = new SqlConnection ();
_sqlConnection.ConnectionString = @"Data Source=<SQL_Server/Instance>; Initial Catalog=<database_name>; Integrated Security=False; User ID=<user_id>;Password=<passowrd>";
_sqlConnection.Open ();
SqlCommand _sqlCommand = new SqlCommand ( "select * from DatabaseName.dbo.viewName", _sqlConnection ); 
_dataSet = new DataSet ();
_sqlDataAdapter = new SqlDataAdapter ( _sqlCommand );
_sqlDataAdapter.Fill ( _dataSet );
_schemaTable = new DataTable ();
_sqlDataAdapter.FillSchema ( _schemaTable, SchemaType.Source );
dataGridView.DataSource = _schemaTable;
_sqlConnection.Close ();
蔚蓝源自深海 2024-08-29 23:36:13

您始终可以创建自己的:

        DataTable table = new DataTable("TableName");

        table.Columns.Add(new DataColumn("Col1", typeof(int)));
        table.Columns.Add(new DataColumn("Col2", typeof(int)));
        table.Columns.Add(new DataColumn("Col3", typeof(string)));
        table.Columns.Add(new DataColumn("Col4", typeof(int)));
        table.Columns.Add(new DataColumn("Col5", typeof(string)));

明显的缺点是每当数据库架构发生更改时您都必须更新代码。

You can always create your own:

        DataTable table = new DataTable("TableName");

        table.Columns.Add(new DataColumn("Col1", typeof(int)));
        table.Columns.Add(new DataColumn("Col2", typeof(int)));
        table.Columns.Add(new DataColumn("Col3", typeof(string)));
        table.Columns.Add(new DataColumn("Col4", typeof(int)));
        table.Columns.Add(new DataColumn("Col5", typeof(string)));

The obvious draw back being that you will have to update your code whenever the database schema changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文