Aqui, experimente isto (este é apenas um pseudocódigo)
using System;
using System.Data;
using System.Data.SqlClient;
publicclassPullDataTest
{// your data tableprivate DataTable dataTable = new DataTable();
publicPullDataTest(){
}
// your method to pull data from database to datatable publicvoidPullData(){
string connString = @"your connection string here";
string query = "select * from table";
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();
}
}
O datatablecampo deve ser inicializado antes da chamadada.Fill(dataTable)
Dabblernl
@ yonan2236 Que tal ter o parâmetro de saída de t sql ao lado da tabela de dados? como obter o parâmetro de saída também? É possível? Amostra?
Ahmad Ebrahimi
1
Este código está sujeito a erros e não é recomendável usar os recursos disponíveis desta forma. Por favor, veja a resposta de @Tim Rogers para a solução limpa.
Xan-Kun Clark-Davis
Além disso, dê uma olhada no LINQ (se ainda não o fez), pois ele pode realmente fazer alguma mágica aqui :-)
Xan-Kun Clark-Davis
Embora esse código funcione, ele não utiliza o try/catchou o using()para tratar o erro.
Si8 01 de
78
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
@ Xan-KunClark-Davis: O código na resposta aceita vaza recursos se uma exceção for lançada. Você pode não desprezarusing tanto se compreender seu equivalente completo.
Ben Voigt
@ Xan-KunClark-Davis Por que você desprezaria Using?? Isso é como desprezar Withou Try-Catch. Eu sou o reverso; Fico desapontado quando não é suportado por uma classe.
SteveCinq de
12
De muitas maneiras.
Use ADO.Net e preencha o adaptador de dados para obter uma DataTable:
using (SqlDataAdapter dataAdapter
= new SqlDataAdapter ("SELECT blah FROM blahblah ", sqlConn))
{
// create the DataSet
DataSet dataSet = new DataSet();
// fill the DataSet using our DataAdapter
dataAdapter.Fill (dataSet);
}
Você pode então obter a tabela de dados do conjunto de dados.
Nota no conjunto de dados de resposta votada não é usado, (apareceu após minha resposta)
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
O que é preferível ao meu.
Eu recomendaria fortemente olhar para a estrutura de entidade embora ... usar datatables e datasets não é uma boa ideia. Não há segurança de tipo neles, o que significa que a depuração só pode ser feita em tempo de execução. Com coleções fortemente tipadas (que você pode obter usando LINQ2SQL ou estrutura de entidade), sua vida será muito mais fácil.
Edit: Talvez eu não tenha sido claro: Datatables = good, datasets = evil. Se você estiver usando ADO.Net, poderá usar ambas as tecnologias (EF, linq2sql, dapper, nhibernate ou orm of the month), visto que geralmente ficam sobre ado.net. A vantagem que você obtém é que pode atualizar seu modelo com muito mais facilidade à medida que seu esquema muda, desde que você tenha o nível certo de abstração, aproveitando a geração de código.
O adaptador ado.net usa provedores que expõem as informações de tipo do banco de dados, por exemplo, por padrão, ele usa um provedor de servidor sql, você também pode conectar - por exemplo - o provedor de postgress devart e ainda obter acesso às informações de tipo que então permitem que você, conforme descrito acima, use sua orma de escolha (quase sem dor - existem algumas peculiaridades) - acredito que a Microsoft também oferece um provedor oracle. O propósito INTEIRO disso é abstrair da implementação do banco de dados, quando possível.
Conjuntos de dados digitados têm segurança de tipo e coleções fortemente tipadas, assim como EF. Mas esses são apenas para quando seu aplicativo está totalmente acoplado ao banco de dados. Se você está escrevendo uma ferramenta que precisa funcionar com muitos bancos de dados diferentes, a segurança de tipo é um desejo impossível.
Ross Presser,
1
Conjuntos de dados digitados em .net são uma criação horrível de xml loucura e desgraça. Eu nunca trabalhei em um lugar que está disposto a aceitar a sobrecarga de manter tudo isso para conjuntos de dados digitados em microsofts. Eu não acho que mesmo a Microsoft sugere que seja sensato hoje em dia. Quanto à segurança de tipos com vários bancos de dados, é claro que você pode obtê-la - a questão é que você a converta em uma coleção digitada o mais rápido possível e a transmita para restringir os problemas de tipo a um local específico. Orms ajudará com isso e funcionará perfeitamente bem com vários bancos de dados. Se você não gosta de EF, use algo mais leve como dapper.
John Nicholas
1
Você não me entendeu. Se você está escrevendo uma ferramenta de propósito geral que não tem ideia de que tipo de banco de dados vai se conectar, então a segurança de tipo é um desejo impossível.
Ross Presser
1
Sql é fornecido. Além disso, se você não sabe que tipo de banco de dados, então por que precisa ser um banco de dados? Qual seria a aplicação de tal ferramenta genérica? Se você precisar se conectar a bancos de dados que são realmente tão radicalmente diferentes, você abstrairá dele atrás de um padrão de repositório e, dentro dele, você precisaria de adaptadores de banco de dados especializados diferentes e, nesse ponto, você saberia sobre os detalhes. O fato é que o código de consumo tem expectativas de tipo -> afirmações de tipo no adaptador. Sua restrição significa que você não tem ideia sobre a linguagem do banco de dados e, portanto, não pode consultar.
John Nicholas
3
Suponha que você estivesse escrevendo um clone do SSMS.
Ross Presser
9
Versão independente do fornecedor, depende exclusivamente de interfaces ADO.NET; 2 maneiras:
public DataTable Read1<T>(string query) where T : IDbConnection, new()
{
using (var conn = new T())
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.ConnectionString = _connectionString;
cmd.Connection.Open();
var table = new DataTable();
table.Load(cmd.ExecuteReader());
return table;
}
}
}
public DataTable Read2<S, T>(string query) where S : IDbConnection, new()
where T : IDbDataAdapter, IDisposable, new()
{
using (var conn = new S())
{
using (var da = new T())
{
using (da.SelectCommand = conn.CreateCommand())
{
da.SelectCommand.CommandText = query;
da.SelectCommand.Connection.ConnectionString = _connectionString;
DataSet ds = new DataSet(); //conn is opened by dataadapter
da.Fill(ds);
return ds.Tables[0];
}
}
}
}
Fiz alguns testes de desempenho e a segunda abordagem sempre superou a primeira.
Read1parece melhor aos olhos, mas o adaptador de dados tem melhor desempenho (para não confundir que um banco de dados superou o outro, as consultas eram todas diferentes). A diferença entre os dois dependia da consulta. A razão pode ser que Loadvárias restrições sejam verificadas linha por linha da documentação ao adicionar linhas (é um método ativado DataTable) enquanto Fillestá em DataAdapters que foram projetados apenas para isso - criação rápida de DataTables.
Você precisa cercar DataTable.Load()com .BeginLoadData()e .EndLoadData()atingir a mesma velocidade que com DataSet.
Nikola Bogdanović de
1
Modelo centralizado: você pode usá-lo de qualquer lugar!
Você só precisa chamar Below Format de sua função para esta classe
DataSet ds = new DataSet();
SqlParameter[] p = new SqlParameter[1];
string Query = "Describe Query Information/either sp, text or TableDirect";
DbConnectionHelper dbh = new DbConnectionHelper ();
ds = dbh. DBConnection("Here you use your Table Name", p , string Query, CommandType.StoredProcedure);
É isso aí. é um método perfeito.
publicclassDbConnectionHelper{
public DataSet DBConnection(string TableName, SqlParameter[] p, string Query, CommandType cmdText) {
string connString = @ "your connection string here";
//Object Declaration
DataSet ds = new DataSet();
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
SqlDataAdapter sda = new SqlDataAdapter();
try {
//Get Connection string and Make Connection
con.ConnectionString = connString; //Get the Connection Stringif (con.State == ConnectionState.Closed) {
con.Open(); //Connection Open
}
if (cmdText == CommandType.StoredProcedure) //Type : Stored Procedure
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = Query;
if (p.Length > 0) // If Any parameter is there means, we need to add.
{
for (int i = 0; i < p.Length; i++) {
cmd.Parameters.Add(p[i]);
}
}
}
if (cmdText == CommandType.Text) // Type : Text
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = Query;
}
if (cmdText == CommandType.TableDirect) //Type: Table Direct
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = Query;
}
cmd.Connection = con; //Get Connection in Command
sda.SelectCommand = cmd; // Select Command From Command to SqlDataAdaptor
sda.Fill(ds, TableName); // Execute Query and Get Result into DataSet
con.Close(); //Connection Close
} catch (Exception ex) {
throw ex; //Here you need to handle Exception
}
return ds;
}
}
Respostas:
Aqui, experimente isto (este é apenas um pseudocódigo)
using System; using System.Data; using System.Data.SqlClient; public class PullDataTest { // your data table private DataTable dataTable = new DataTable(); public PullDataTest() { } // your method to pull data from database to datatable public void PullData() { string connString = @"your connection string here"; string query = "select * from table"; SqlConnection conn = new SqlConnection(connString); SqlCommand cmd = new SqlCommand(query, conn); conn.Open(); // create data adapter SqlDataAdapter da = new SqlDataAdapter(cmd); // this will query your database and return the result to your datatable da.Fill(dataTable); conn.Close(); da.Dispose(); } }
fonte
datatable
campo deve ser inicializado antes da chamadada.Fill(dataTable)
try/catch
ou ousing()
para tratar o erro.var table = new DataTable(); using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string")) { da.Fill(table); }
fonte
using
tanto se compreender seu equivalente completo.Using
?? Isso é como desprezarWith
ouTry-Catch
. Eu sou o reverso; Fico desapontado quando não é suportado por uma classe.De muitas maneiras.
Use ADO.Net e preencha o adaptador de dados para obter uma DataTable:
using (SqlDataAdapter dataAdapter = new SqlDataAdapter ("SELECT blah FROM blahblah ", sqlConn)) { // create the DataSet DataSet dataSet = new DataSet(); // fill the DataSet using our DataAdapter dataAdapter.Fill (dataSet); }
Você pode então obter a tabela de dados do conjunto de dados.
Nota no conjunto de dados de resposta votada não é usado, (apareceu após minha resposta)
// create data adapter SqlDataAdapter da = new SqlDataAdapter(cmd); // this will query your database and return the result to your datatable da.Fill(dataTable);
O que é preferível ao meu.
Eu recomendaria fortemente olhar para a estrutura de entidade embora ... usar datatables e datasets não é uma boa ideia. Não há segurança de tipo neles, o que significa que a depuração só pode ser feita em tempo de execução. Com coleções fortemente tipadas (que você pode obter usando LINQ2SQL ou estrutura de entidade), sua vida será muito mais fácil.
Edit: Talvez eu não tenha sido claro: Datatables = good, datasets = evil. Se você estiver usando ADO.Net, poderá usar ambas as tecnologias (EF, linq2sql, dapper, nhibernate ou orm of the month), visto que geralmente ficam sobre ado.net. A vantagem que você obtém é que pode atualizar seu modelo com muito mais facilidade à medida que seu esquema muda, desde que você tenha o nível certo de abstração, aproveitando a geração de código.
O adaptador ado.net usa provedores que expõem as informações de tipo do banco de dados, por exemplo, por padrão, ele usa um provedor de servidor sql, você também pode conectar - por exemplo - o provedor de postgress devart e ainda obter acesso às informações de tipo que então permitem que você, conforme descrito acima, use sua orma de escolha (quase sem dor - existem algumas peculiaridades) - acredito que a Microsoft também oferece um provedor oracle. O propósito INTEIRO disso é abstrair da implementação do banco de dados, quando possível.
fonte
Versão independente do fornecedor, depende exclusivamente de interfaces ADO.NET; 2 maneiras:
public DataTable Read1<T>(string query) where T : IDbConnection, new() { using (var conn = new T()) { using (var cmd = conn.CreateCommand()) { cmd.CommandText = query; cmd.Connection.ConnectionString = _connectionString; cmd.Connection.Open(); var table = new DataTable(); table.Load(cmd.ExecuteReader()); return table; } } } public DataTable Read2<S, T>(string query) where S : IDbConnection, new() where T : IDbDataAdapter, IDisposable, new() { using (var conn = new S()) { using (var da = new T()) { using (da.SelectCommand = conn.CreateCommand()) { da.SelectCommand.CommandText = query; da.SelectCommand.Connection.ConnectionString = _connectionString; DataSet ds = new DataSet(); //conn is opened by dataadapter da.Fill(ds); return ds.Tables[0]; } } } }
Fiz alguns testes de desempenho e a segunda abordagem sempre superou a primeira.
Stopwatch sw = Stopwatch.StartNew(); DataTable dt = null; for (int i = 0; i < 100; i++) { dt = Read1<MySqlConnection>(query); // ~9800ms dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms dt = Read1<SQLiteConnection>(query); // ~4000ms dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms dt = Read1<SqlCeConnection>(query); // ~5700ms dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms dt = Read1<SqlConnection>(query); // ~850ms dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms dt = Read1<VistaDBConnection>(query); // ~3900ms dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
Read1
parece melhor aos olhos, mas o adaptador de dados tem melhor desempenho (para não confundir que um banco de dados superou o outro, as consultas eram todas diferentes). A diferença entre os dois dependia da consulta. A razão pode ser queLoad
várias restrições sejam verificadas linha por linha da documentação ao adicionar linhas (é um método ativadoDataTable
) enquantoFill
está em DataAdapters que foram projetados apenas para isso - criação rápida de DataTables.fonte
DataTable.Load()
com.BeginLoadData()
e.EndLoadData()
atingir a mesma velocidade que comDataSet
.Modelo centralizado: você pode usá-lo de qualquer lugar!
Você só precisa chamar Below Format de sua função para esta classe
DataSet ds = new DataSet(); SqlParameter[] p = new SqlParameter[1]; string Query = "Describe Query Information/either sp, text or TableDirect"; DbConnectionHelper dbh = new DbConnectionHelper (); ds = dbh. DBConnection("Here you use your Table Name", p , string Query, CommandType.StoredProcedure);
É isso aí. é um método perfeito.
public class DbConnectionHelper { public DataSet DBConnection(string TableName, SqlParameter[] p, string Query, CommandType cmdText) { string connString = @ "your connection string here"; //Object Declaration DataSet ds = new DataSet(); SqlConnection con = new SqlConnection(); SqlCommand cmd = new SqlCommand(); SqlDataAdapter sda = new SqlDataAdapter(); try { //Get Connection string and Make Connection con.ConnectionString = connString; //Get the Connection String if (con.State == ConnectionState.Closed) { con.Open(); //Connection Open } if (cmdText == CommandType.StoredProcedure) //Type : Stored Procedure { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = Query; if (p.Length > 0) // If Any parameter is there means, we need to add. { for (int i = 0; i < p.Length; i++) { cmd.Parameters.Add(p[i]); } } } if (cmdText == CommandType.Text) // Type : Text { cmd.CommandType = CommandType.Text; cmd.CommandText = Query; } if (cmdText == CommandType.TableDirect) //Type: Table Direct { cmd.CommandType = CommandType.Text; cmd.CommandText = Query; } cmd.Connection = con; //Get Connection in Command sda.SelectCommand = cmd; // Select Command From Command to SqlDataAdaptor sda.Fill(ds, TableName); // Execute Query and Get Result into DataSet con.Close(); //Connection Close } catch (Exception ex) { throw ex; //Here you need to handle Exception } return ds; } }
fonte