Usuário com melhor resposta
Troubleshooting Exceptions: System.Data.SqlClient.SqlException

Pergunta
-
Respostas
-
-
Diogo,
Esta exception ocorre no momento que vc acessa o banco de dados, neste caso o SQL Server; por isso, vc deve verificar em qual linha do seu código está gerando o erro para fazer a correção.
Normalmente em cada bloco de código utiliza-se o try catch.
Dentro do catch vc consegue pegar exatamente o motivo do erro e tratá-lo.
A classe Exception ou SqlException tem vários métodos que identificam o motivo do erro.
por exemplo:
try
{
//Codigo
}
catch (System.Data.SqlClient.SqlException ex){
throw new System.Data.SqlClient.SqlException(ex.Message);}
-
Neste exemplo que vc passou, vc nao esta abrinco a conexão (sqlconnection.open) e nem executando o sqlcommand.
Tente fazer assim:
{
SqlConnection cn = "string d e conexão com seu banco" try{
cn = AbrirBanco();
SqlCommand command = new SqlCommand(strQuery, cn);AbrirBanco();
SqlDataReader reader = command.ExecuteReader(); DataTable table = new DataTable();table.Load(reader);
return table;}
finally{
FecharBanco(cn);
}
}
Duvidas poste ai..
[]´s
-
public DataTable Listagem() {
try
{
DataTable Tabela = new DataTable(); SqlDataAdapter da = new SqlDataAdapter("select * from Clientes", Dados.StringDeConexao);da.Fill(Tabela);
return Tabela;}
catch (Excpetion ex)
{
throw new Excpection(ex.ToString());
}
}
Faz esta alteração, coloca o break point no catch e verifica qual erro aparece no Exception.
Uma sugestão.
No código de insert
Code Snippetcmd.Connection = cn;
cmd.CommandText = "insert into Clientes(nome,email,telefone) values(@nome,@email,@telefone); select @@IDENTITY;";
vc deveria trocar o @@IDentity por SCOPE_IDENTITY( )
Se duas pessoas simultaneamente realizarem o insert, pode ocorrer de inverter os Id gerados, pois o Identity retorna o ultimo valor identity inserido na tabela, enqto o scope fica restrito a sua sessão.
Abraços...
Todas as Respostas
-
-
Diogo,
Esta exception ocorre no momento que vc acessa o banco de dados, neste caso o SQL Server; por isso, vc deve verificar em qual linha do seu código está gerando o erro para fazer a correção.
Normalmente em cada bloco de código utiliza-se o try catch.
Dentro do catch vc consegue pegar exatamente o motivo do erro e tratá-lo.
A classe Exception ou SqlException tem vários métodos que identificam o motivo do erro.
por exemplo:
try
{
//Codigo
}
catch (System.Data.SqlClient.SqlException ex){
throw new System.Data.SqlClient.SqlException(ex.Message);}
-
-
-
Mas entaum eu pedi pra debugar, a única q ocorre eh esta excessão...meu aplicativo como eu disse na resposta ao nosso amigo Nelson, ele executa normalmente sem erro...só q quando eu clico no menu cadastro clientes, pra xamar o formulário de clientes, ele pára a execução, e me mostra a excessão dentro do método Listagem, q está localizado na classe ClientesDAL...eu vo te passar o código q eu implementei dentro deste método, indicando qual linha ele acusa essa excessão
da.Fill(Tabela); //É exatamente nesta linha q pára a execução
return Tabela;}
-
Neste exemplo que vc passou, vc nao esta abrinco a conexão (sqlconnection.open) e nem executando o sqlcommand.
Tente fazer assim:
{
SqlConnection cn = "string d e conexão com seu banco" try{
cn = AbrirBanco();
SqlCommand command = new SqlCommand(strQuery, cn);AbrirBanco();
SqlDataReader reader = command.ExecuteReader(); DataTable table = new DataTable();table.Load(reader);
return table;}
finally{
FecharBanco(cn);
}
}
Duvidas poste ai..
[]´s
-
Entaum cara, na verdade eu naum passei a conexão ai, pq eu fiz assim eu criei uma classe somente pra armazenar a minha string de conexão...e uma DAL para cada classe de negócio...mas deixa eu ver se eu tendi oq vc me disse...cada método q eu for usar a conexão com o banco eu vo ter q usar a string de conexão q eu defini na outra classe!?
-
Entendi.
Bom vamos lá as considerações;
A string de conexão é apenas um caminho para chegar no banco. O objeto SqlConnection recebe essa string e faz o controle de conexões com o banco, como abrir..fechar e etc.
Quando vc utiliza o DataReader, vc precisa abrir uma conexão com o banco, executar o comando que deseja, pegar os resultados e armazenar em algum lugar e depois trabalhar eles.
No código que te passei é exatamente isso, veja que no seu código vc em nenhum momento esta executando a string mas esta aplicando o método fill em um objeto null, por isso esta gerando a exception.
Entendeu ?
Att
-
Diogo Vicente wrote: deixa eu ver se eu tendi oq vc me disse...cada método q eu for usar a conexão com o banco eu vo ter q usar a string de conexão q eu defini na outra classe!? Olá Diogo,
Em realidade, o ideal é ter sua string de conexão definida no arquivo de configuração da aplicação (App.config / Web.config), e ler essa string de conexão sempre que precisar, lá na sua camada de acesso à dados (DAL).
O tópico abaixo explica em mais detalhes:
Criar arquivo XML para guardar configurações do banco!!
http://forums.microsoft.com/msdn-br/ShowPost.aspx?PostID=4261669&SiteID=21Abraços,
Caio Proiete
Caio Proiete
http://www.caioproiete.com -
Opaa blz Caio!?
Então rapaz esta sugestão até jah havia comentado com meu líder de célula, parece fantástico isso...ele tinha ficado de me mandar um artigo falando sobre isso, deve ter esquecido...agradeço por ter me enviado
-
Olá Diogo, tudo ótimo e você?
Sim, o tópico acima explica como você faz para criar o arquivo de configuração, armazenar a string de conexão, e ler o seu conteúdo quando precisar.
Recomendo ler o tópico completo para um entendimento completo, mas a quarta resposta provavelmente é o que mais te interessa.
Abraços,
Caio Proiete
Caio Proiete
http://www.caioproiete.com -
Bom Caio, eu fiz uma vista grossa, pelo menos por enquanto, como eh criado esse tal arquivo de configuração, mas como a estrutura deste software jah foi toda montada sem utiliza-la, veja uma das classes DAL q eu criei...pra vc tender como eu to fazendo ela...qm sabe isto ajude vc a me explicar oq eu devo fazer pra solucionar este problema ok!?
using
System;using
System.Collections.Generic;using
System.Text;using
Loja.Modelos;using
System.Data.SqlClient;using
System.Data;namespace
Loja.DAL{
public class ClientesDAL{
public void Incluir(ClienteInformation cliente) { //conexo SqlConnection cn = new SqlConnection(); try{
cn.ConnectionString =
Dados.StringDeConexao; //command SqlCommand cmd = new SqlCommand();cmd.Connection = cn;
cmd.CommandText =
"insert into Clientes(nome,email,telefone) values(@nome,@email,@telefone); select @@IDENTITY;";cmd.Parameters.AddWithValue(
"@nome", cliente.Nome);cmd.Parameters.AddWithValue(
"@email", cliente.Email);cmd.Parameters.AddWithValue(
"@telefone", cliente.Telefone);cn.Open();
cliente.Codigo =
Convert.ToInt32(cmd.ExecuteScalar());}
catch (SqlException ex){
throw new Exception("Servidor SQL Erro:" + ex.Message);}
catch (Exception e){
throw new Exception(e.Message);}
finally {cn.Close();
}
}
public void Alterar(ClienteInformation cliente) { //Conexo SqlConnection cn = new SqlConnection(); try{
cn.ConnectionString =
Dados.StringDeConexao; //command SqlCommand cmd = new SqlCommand();cmd.Connection = cn;
cmd.CommandType =
CommandType.Text;cmd.CommandText =
"update Clientes set nome = @nome, email = @email, telefone = @telefone where codigo = @codigo";cmd.Parameters.AddWithValue(
"@codigo", cliente.Codigo);cmd.Parameters.AddWithValue(
"@nome", cliente.Nome);cmd.Parameters.AddWithValue(
"@email", cliente.Email);cmd.Parameters.AddWithValue(
"@telefone", cliente.Telefone);cn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException ex){
throw new Exception("Servidor SQL Error:" + ex.Message);}
catch (Exception e){
throw new Exception(e.Message);}
finally {cn.Close();
}
}
public void Excluir(int codigo) { //Conexo SqlConnection cn = new SqlConnection(); try{
cn.ConnectionString =
Dados.StringDeConexao; //Command SqlCommand cmd = new SqlCommand();cmd.Connection = cn;
cmd.CommandText =
"delete from Clientes where codigo = " + codigo;cn.Open();
int resultado = cmd.ExecuteNonQuery(); if (resultado != 1){
throw new Exception("No foi possvel excluir o cliente: " + codigo);}
}
catch (SqlException ex){
throw new Exception("Servidor SQL Error: " + ex.Message);}
catch (Exception e){
throw new Exception(e.Message);}
finally {cn.Close();
}
}
public DataTable Listagem() { DataTable Tabela = new DataTable(); SqlDataAdapter da = new SqlDataAdapter("select * from Clientes", Dados.StringDeConexao);da.Fill(Tabela);
return Tabela;}
}
}
Bom, como vc msm pode perceber, estou mandando a implementação justamente da classe a qual citei q está dando problema
Abraços!!!
Ps: Qlq coisa se naum for encomodar...deixe seu messenger
-
public DataTable Listagem() {
try
{
DataTable Tabela = new DataTable(); SqlDataAdapter da = new SqlDataAdapter("select * from Clientes", Dados.StringDeConexao);da.Fill(Tabela);
return Tabela;}
catch (Excpetion ex)
{
throw new Excpection(ex.ToString());
}
}
Faz esta alteração, coloca o break point no catch e verifica qual erro aparece no Exception.
Uma sugestão.
No código de insert
Code Snippetcmd.Connection = cn;
cmd.CommandText = "insert into Clientes(nome,email,telefone) values(@nome,@email,@telefone); select @@IDENTITY;";
vc deveria trocar o @@IDentity por SCOPE_IDENTITY( )
Se duas pessoas simultaneamente realizarem o insert, pode ocorrer de inverter os Id gerados, pois o Identity retorna o ultimo valor identity inserido na tabela, enqto o scope fica restrito a sua sessão.
Abraços...
-
Cara eu tentei aquele código q vc me passou, mas veja a mensagem q ele dah na excessão...
System.Data.SqlClient.SqlException: Login failed for user ''. The user is not associated with a trusted SQL Server connection.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.Common.DbDataAdapter.QuietOpen(IDbConnection connection, ConnectionState& originalState)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
at Loja.DAL.ClientesDAL.Listagem() in C:\Desenvolvimento\Aplicações\Loja\DAL\DAL\ClientesDAL.cs:line 118Ah tbm fiz a alteração no código insert, troquei aquelas duas "@" q vc me disse por SCOPE_IDENTITY
-
Fala Diogo..
Agora melhorou..rs...
O erro está na string de conexão, por algum motivo na sua aplicação, qdo a string é montada, não está sendo informado o usuário.
Verifica a string de conexão que tá la o problema..
caso queira fazer um teste extra, experimente colocar no codigo a string correta.
-
O erro está na string de conexão. O usuário está vazio.. por isso do erro.
Verifica em modo debug se realmente a string de conexao é montada.o problema está lá.
se quiser fazer um teste para validar o método, apenas troque a string pela chamada direta..com certeza vai funcionar.
tipo
public DataTable Listagem() {
try
{
DataTable Tabela = new DataTable();
String strCon = "coloca a string aqui";
SqlDataAdapter da = new SqlDataAdapter("select * from Clientes", strCon);
da.Fill(Tabela);
return Tabela;
}
catch (Excpetion ex)
{
throw new Excpection(ex.ToString());
}
}
-
Lele, eu atualizei minha string de conexão, colocando o nome de usuário, mas a excessão continua acontecendo...tipo quando eu acesso o banco através do sql management, eu faço via Windows Authentication, portanto naum insiro senha alguma, isso pode tah fazendo diferença??Como eu faço neste caso??
-
Diogo,
Segue exemplo, substituir os nomes NOMEDABASE,NOMEDOSERVIDOR.
public
DataTable Listagem(){
try{
DataTable Tabela = new DataTable(); string conn = "DataBase = NOMEDABASE; Server=NOMEDOSERVIDOR; Integrated Security=true";System.Data.SqlClient.
SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter("select * from Clientes", conn);da.Fill(Tabela);
return Tabela;}
catch (Exception ex){
throw new Exception(ex.Message);}
}
Se este exemplo funcionar, vc realizar manutenção no seu dbConection, pois é lá o problema.
Abraços...
-
Diogo, eu acabei fazendo o código e esqueci de responder a sua dúvida,
Code SnippetLele, eu atualizei minha string de conexão, colocando o nome de usuário, mas a excessão continua acontecendo...tipo quando eu acesso o banco através do sql management, eu faço via Windows Authentication, portanto naum insiro senha alguma, isso pode tah fazendo diferença??Como eu faço neste caso??
neste caso, vc precisa apenas garantir que o seu usuário do AD tem privilégio para se conectar no banco de dados, se tiver a string de conexao mais simples seria "DataBase = NOMEDABASE; Server=NOMEDOSERVIDOR; Integrated Security=true". Quando vc escolhe realizar conexao pelo usuário do AD vc não precisa informar a senha na string de conexão, apenas qdo for usuário do SQL.
No exemplo que eu fiz no post anterior eu rodei namáquina e funcionou, caso não funcione aí.. tdo indica que o seu usuário do AD não tem permissão no BD.
Faça o teste lá e post os resultados aqui...
Abraços...
-
Lele eu fiz a alteração q vc me disse, coloquei a string de conexão dentro da implementação do método Listagem() da classe ClienteDAL
agora ele acusa uma excessão assim no codebehind do formulário de clientes...
Object reference not set to an instance of an object.
e o código tah assim...
{
//Comunicao com a Camada BLL ClientesBLL objCliente = new ClientesBLL();clientesDataGridView.DataSource = objCliente.Listagem();
//Atualizando os objetos TextBoxcodigoTextBox.Text = clientesDataGridView[0, clientesDataGridView.CurrentRow.Index].Value.ToString();//aponta aki a excessão
nomeTextBox.Text = clientesDataGridView[1, clientesDataGridView.CurrentRow.Index].Value.ToString();
telefoneTextBox.Text = clientesDataGridView[2, clientesDataGridView.CurrentRow.Index].Value.ToString();
emailTextBox.Text = clientesDataGridView[3, clientesDataGridView.CurrentRow.Index].Value.ToString();
}
-
Code SnippetLele eu fiz a alteração q vc me disse, coloquei a string de conexão dentro da implementação do método Listagem() da classe ClienteDAL
A alteração com a string de conexão dentro do método foi somente um exemplo para mostrar que o método funciona qdo a string de conexão é passada corretamente.
Code Snippetagora ele acusa uma excessão assim no codebehind do formulário de clientes...
Object reference not set to an instance of an object.
Neste caso, algum objeto não foi instanciado, por isso está acusando o erro, neste método a minha sugestão é vc colocar o bloco try catch e verificar o pq da exceção,
Também seria interessante abrir outro post de dúvida para análise deste erro apresentado, uma vez que o erro principal (que era na chamada da string de conexão) foi resolvido.
Abraços...