使用sql server表的模式创建Empty DataTable对象的最佳方法是什么?
答案 0 :(得分:15)
所有这些解决方案都是正确的,但是如果您想要一个为此方案简化的纯代码解决方案。
由于在ExecuteReader函数(Command Behavior Documentation)上指定了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;
}
答案 1 :(得分:10)
我认为值得一提的是SET FMTONLY:
SET FMTONLY ON;
SELECT * FROM SomeTable
SET FMTONLY OFF;
当SET FMTONLY打开时,由于请求而没有处理或发送到客户端的行。
这可以派上用场的原因是因为您可以提供任何查询/存储过程并仅返回结果集的元数据。
答案 2 :(得分:9)
尝试:
SELECT TOP 0 * FROM [TableName]
并使用SQLDataAdapter填充DataSet,然后从该DataSet中获取Table。
答案 3 :(得分:4)
假设您可以连接到包含要在其执行此操作时复制的表的SQL数据库,可以使用传统结果集进行数据表转换,使用
select * from <tablename> where 1=2
作为您的来源查询。
这将返回一个带有源表结构的空结果集。
答案 4 :(得分:2)
这就是我的所作所为:
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();
运作良好。谢谢AdaTheDev。
答案 5 :(得分:1)
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
答案 6 :(得分:0)
这有效:
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
答案 7 :(得分:0)
我知道这是一个古老的问题,特定于SQL Server。但是,如果您正在寻找适用于不同数据库的通用解决方案,请使用Richard的解决方案,但将其修改为使用 CONVERT(UNHEX('C38EC2B2') USING utf8mb4) = 'β' (Greek beta)
CONVERT(CONVERT(UNHEX('C38EC2B2') USING latin1) USING utf8mb4) = 'β'
并更改类型以使用通用ADO.Net类型IDataReader,IDbCommand等。
大多数现代关系数据库足够智能,可以识别1 = 0条件,并且不会像常规tablescan查询那样运行它。我已经在SQL Server,Oracle和DB2上尝试过此操作,并且表也有几亿条记录。都在几毫秒内返回空结果。
答案 8 :(得分:0)
这就是我所做的,它提供了一个可供使用的空白DataTable:
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 ();
答案 9 :(得分:-1)
您可以随时创建自己的:
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)));
显而易见的缺点是,只要数据库架构发生变化,您就必须更新代码。