web-dev-qa-db-ja.com

データベーステーブルスキーマを使用して.netで空のデータテーブルを取得する必要があります

SQLサーバーテーブルのスキーマを使用して空のDataTableオブジェクトを作成するための最良の方法は何ですか?

19
Ronnie Overby

言及する価値があると思うステートメントは SET FMTONLY

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

SET FMTONLYがオンになっているときの要求のため、行は処理されず、クライアントに送信されません。

これが便利な理由は、任意のクエリ/ストアドプロシージャを指定して、結果セットのメタデータのみを返すことができるためです。

10
AdaTheDev

これらのソリューションはすべて正しいですが、このシナリオで合理化された純粋なコードソリューションが必要な場合。

CommandBehavior.SchemaOnlyがExecuteReader関数で指定されているため、このソリューションではデータは返されません( コマンド動作ドキュメント

CommandBehavior.SchemaOnlyソリューションは、SET FMTONLYONを追加します。クエリが実行される前の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;
}
16
Richard R

試してください:SELECT TOP 0 * FROM [TableName]

sQLDataAdapterを使用してDataSetに入力し、そのDataSetからテーブルを取得します。

9
Shoaib Shaikh

これを実行したい時点でコピーしたいテーブルを含むSQLデータベースに接続できると仮定すると、従来の結果セットからデータテーブルへの変換を使用できます。

select * from <tablename> where 1=2

ソースクエリとして。

これにより、ソーステーブルの構造を含む空の結果セットが返されます。

4
Ed Harper

これが私がしたことです:

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に感謝します。

2
Ronnie Overby
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
1
Sayak

これは機能します:

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
0
stentor

これは古い質問であり、SQLServerに固有のものであることを私は知っています。ただし、さまざまなデータベースで機能する汎用ソリューションを探している場合は、Richardのソリューションを使用しますが、"SELECT * FROM {0} WHERE 1=0"を使用するように変更し、汎用ADO.NetタイプIDataReader、IDbCommandなどを使用するようにタイプを変更します。

最新のリレーショナルデータベースのほとんどは、1 = 0の条件を識別するのに十分インテリジェントであり、通常のテーブルスキャンクエリのように実行されません。私はこれをSQLServerで試しましたが、OracleとDB2のテーブルには1億件のレコードもあります。すべてが数ミリ秒で空の結果を返します。

0
askids

これが私がしたことで、すぐに使える空の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 ();
0
bob number 2