How to disable NetBios in C# in SQL Server communication - c#

I have a problem with my connection to SQL Server in a C# application.
After Open(), I see a NetBios request, but the server does not respond and after a few seconds, the connection is closed:
https://photos.app.goo.gl/mut3srWNxKXRUYDcA
After 2-3 attempts, the connection is established, but it takes around 10 seconds.
On the client side, we don’t use SQL NetBios but instead pipe connection type only - something like that (with Windows authentications):
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = “SERVER=1.2.3.4;DATABASE=dbName;POOLING=true;Connect Timeout=30;Integrated Security=SSPI”;
conn.Open();
SqlCommand command = new SqlCommand("SELECT [ColumnName] FROM TableName", conn);
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(dt);
conn.Close();
da.Dispose();
}
How to enable respond for this NBSTAT packets on server side or disable it on application side in C# code (but not disabled NetBios itself).

Related

Can't access my SQL Server without SQL Engine

I have two computers. One is running SQL Server, and I can access the server using SQL authentication from the 2nd PC using SSMS.
I have created a C# Windows Forms application that connects to the database. However, I couldn't access my server from the application.
I disabled the firewall, allowed remote control, and allowed mixed mode authentication. I also forwarded required ports to my IP in my router settings.
I tried both these connecting strings, but they didn't help:
"Persist Security Info = False; User ID = gues; Password=gues;Initial Catalog = CoronaNurse; Server=" + server;
"Data Source=" + server + ";Initial Catalog=CoronaNurse;Integrated Security=false;UID=gues;Password=gues";
(server is a string that have IP of my server)
(gues is a login in my Server)
The weird thing is when I login as gues in SSMS from my 2nd computer I can access the server in the first computer.
The question is, how do I access my server from a computer that doesn't have SSMS or any specific Login?
I need my application to be able to connect to my server without anything else installed, but I can't find where my problem is.
Adding from comments:
Im using the connecting to get a con string from my DB depends on the table i get with my gue.login function SqlDataAdapter
adapter = new SqlDataAdapter("select * from gue.login('" + textBox1.Text.Trim() + "', '" + textBox2.Text.Trim() + "', '" + server + "')", conn);
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
DataSet ds = new DataSet();
adapter.Fill(ds);
string connection;
connection = ds.Tables[0].Rows[0][0].ToString();
Unless you haven't posted up all of your code, you don't appear to be controlling your SQL connection and I would strongly suggest that you use a parameterised call to protect against SQL injection from using direct text entry field values e.g.:
var dataset = new DataSet();
using (var connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
var command = new SqlCommand("GetAll", connection);
command.CommandType = CommandType.StoredProcedure;
var adapter = new SqlDataAdapter(command);
adapter.Fill(dataset);
...
}
The SQL is wrong, and the connection strings look a little off. You might also need an instance name as part of the server. For example, instead of just localhost or 192.168.0.20, you might need localhost\SQLExpress or 192.168.0.20\..
One way you can find the connection string for sure is to use Visual Studio instead of SSMS to connect to the database. The Visual Studio Database Tools has a similar connection window as SSMS, and you can use it to show you the actual connection string it used.
When you've figured that out, try something more like this:
var connString = $"Server={server};Database=CoronaNurse;User Id=gues;Password=gues";
var sql = "select * from gue.login WHERE username = #username AND pHash = #pHash";
var ds = new DataSet();
using (var conn = new SqlConnection(connString))
using (var cmd = new SqlCommand(sql, conn))
using (var adapter = new SqlDataAdapter(cmd))
{
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 50).Value = textBox1.Text.Trim();
cmd.Parameters.Add("#pHash", SqlDbType.Char, 60).Value = BCrypt.Net.BCrypt.HashPassword(textBox2.Text.Trim());
adapter.Fill(ds);
var connection = ds.Tables[0].Rows[0].Items[0].ToString();
}
Note the use of both parameterized queries and BCrypt (you can add BCrypt via NuGet). There are a few things in database development that are too important to do wrong, even for proof-of-concept and learning projects. One of these is SQL Injection. Another is password handling. What I posted still isn't quite right for password handling (you should instead retrieve the stored hash and use the Verify() method), but it's close enough to set you on the right path.
Someone has told me that I can't access my online SQL Server DB from a client PC that doesn't have a Local DB.
I guess that explains my problem perfectly!
I never knew that, in my case, that is my problem right?

How can this be the same sql connection?

"select LAST_INSERT_ID()" is related to the connection. So i test in Mariadb 5.5.25, code as below:
string strConn = "server=localhost;userid=root;password=admin;database=changde2018;charset=utf8;Allow Zero Datetime=True";
using (MySqlConnection connection = new MySqlConnection(strConn))
{
connection.Open();
MySqlCommand cmd = MySqlCommand("insert into t_data (gid) values(665)", connection);// gid is a autoincrease value
cmd.ExecuteNonQuery();
connection.Close();
}
using (MySqlConnection connection = new MySqlConnection(strConn))
{
DataTable dt2 = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter("select LAST_INSERT_ID()", connection);
da.Fill(dt2);
Console.WriteLine(dt2.Rows[0][0].ToString());//expect 0, but it's as same as the last inserted value
}
I query in navicat by 'show status like 'Threads%''. After exe code above, the 'threads_connected' only increased one. This proves Mariadb does treat them as the same connection. Can this be why, I use two different MySqlConnection objects, is it because of the same connection string?
As mysqlconnector.Net documentation says on connection pooling (highlighting is mine):
The MySQL Connector/Net supports connection pooling for better
performance and scalability with database-intensive applications. This
is enabled by default. You can turn it off or adjust its performance
characteristics using the connection string options Pooling,
Connection Reset, Connection Lifetime, Cache Server Properties, Max
Pool Size and Min Pool Size. See Section 5.1.1, “Creating a
Connector/Net Connection String” for further information.
Connection pooling works by keeping the native connection to the
server live when the client disposes of a MySqlConnection.
Subsequently, if a new MySqlConnection object is opened, it will be
created from the connection pool, rather than creating a new native
connection. This improves performance.
Since connection pooling is turned on by default, the database connection was not closed when you closed and disposed of the first mysqlconnection object and was reused by the next section of the code.
You can fully verify this using the connection_id() function in sql.

How to connect an application to a SQL Server using IP Adress in C#?

My problem is that I have created a SQL Server database but I access it locally, only from my own computer. What I want to do is to connect the app to a server and to save all the data there.
The code I used to connect to the SQL Server database is:
SqlConnection con = new SqlConnection(#"Data Source=(localdb)\v11.0;AttachDbFilename=C:\Users\donca\Desktop\Memo\Memo\ContNou.mdf;Integrated Security=True");
SqlCommand cmd1 = new SqlCommand("SELECT * FROM [dbo].[Cont] WHERE Nume_utilizator = #Nume_utilizator and Parola = #Parola;", con);
cmd1.Parameters.AddWithValue("#Nume_utilizator", this.Nume_utilizator.Text);
cmd1.Parameters.AddWithValue("#Parola", this.Parola.Text);
cmd1.Connection = con;
con.Open();
My question is: how can I change this to connect and access data from a SQL Server and save data there?
Just change the connection string:
"Data source=ServerName\InstanceName;"
You can use the IP address instead of the servername.
The default instance name is MSSQLSERVER.
Make sure you turn on "Remote connections" on the distant server. You can use Management studio -> Server properties -> connections -> Allow remote connections.
If it dosn't work check that the TCP/IP protocol is activated for you instance.
You can find it in SQl Server Configuration Manager.
You just have to change your connection string. That's all. For an example, if your server name is CORP and the SQL instance name is SQL2012, your connection string will be like this.
SqlConnection con = new SqlConnection(#"Data Source=CORP\SQL2012;Initial Catalog=ContNou;Integrated Security=True");
In case if you cannot find the SQL server by its name, you can use the IP too.
SqlConnection con = new SqlConnection(#"Data Source=10.4.2.208;Initial Catalog=ContNou;Integrated Security=True");

Exception when attempting to connect to SQL Server CE from C#

I'm an newbie who is trying to get learn some web programming. I'm making my site in VS 2012 using C#. I've got a database connected in the App_Data folder, using SQL Server CE 4.0. I'm attempting to connect to it as follows:
SqlCeCommand cmd1 = new SqlCeCommand("SELECT Admin FROM SystemUsers WHERE Email=" + user.Email);
SqlCeDataReader admin = null;
SqlCeConnection conn = new SqlCeConnection();
conn.ConnectionString = "Data Source=MyData.sdf;Persist Security Info=False;";
conn.Open();
admin = cmd1.ExecuteReader();
When I execute this, I get the following error:
An exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll but was not handled in user code
Any thoughts as to what I'm doing wrong? I've been trying to figure this out for hours.
You said that your database is in the APP_Data directory, but your connection string assumes that is in the root directory of your site.
Try with
conn.ConnectionString = #"Data Source|DataDirectory|\MyData.sdf;Persist Security Info=False;";
The |DataDirectory| is a placeholder string that the NET Framework changes to a predefined location where you data files are supposed to stay
And this is how I would change your code
using(SqlCeConnection conn = new SqlCeConnection(#"Data Source|DataDirectory|\MyData.sdf;Persist Security Info=False;"))
using(SqlCeCommand cmd1 = new SqlCeCommand("SELECT Admin FROM SystemUsers WHERE Email=#mail", conn))
{
conn.Open();
cmd1.Parameters.AddWithValue("#mail", user.Email);
SqlCeDataReader admin = cmd1.ExecuteReader();
while(admin.Read())
{
.....
}
}
As you can see, I have made this changes:
Added a using statement around the creation of the connection and of
the command. This will ensure proper closing and disposing of the two
objects.
Added a parameterized query to avoid problems in parsing text strings
and Sql Injections

Is it better to run 1000-10000 of command in single SQLCLR Context Connection?

I am using the JOB to continuously watch the table data. Inside the JOB i am calling the SQLCLR SP. SQLCLR SP will run. Before the while loop i will open the SQL connection. Inside for loop i will access the database 1000-10000 times in only one connection. I wont close the DB connection untill my work is done.
SqlConnection connection = null;
try
{
using (connection = new SqlConnection("context connection=true"))
{
connection.Open();
DataTable dt;
SqlDataAdapter adp=new SqlDataAdapter("select * from tableName",CnStr);
DataSet ds=new DataSet();
adp.Fill(ds,"TableName");
dt= ds[0];
//dt.Rows.count may be range from 1000-10000
for(i=0;i<dt.Rows.count;i++)
{
int id = int.Parse(dt.Rows[i][0].ToString());
SqlCommand command = new SqlCommand("select * from table1 where IsParsed=0 and Id=" + id, connection);
SqlDataReader r1 = command.ExecuteReader();
SqlCommand command = new SqlCommand("Insert into table2 (values)", connection);
int r2 = command.ExecuteNonQuery();
//Always get table1 data which has IsParsed=0. Get those rows manipulate those rows data and
// insert into datatable table2 and update those rows to IsParsed=1
SqlCommand command = new SqlCommand("Update table1 set IsParsed=1 where id=#id", connection);
int r3 = command.ExecuteNonQuery();
// Run the Billing Logic here
// Insert into Billing Table
SqlCommand command = new SqlCommand("Insert into Billing(values)", connection);
int r2 = command.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
}
finally
{
connection.close();
}
Is there any problem with this approach let me know? Is there any issue with using the connection like this? Provide proper suggestion..
I gone through the article
better way to Execute multiple commands in single connection
Here I am using the Context Connection and executing the thousands of command in single connection. Is there any consideration of Connection pool in context connection..? How about the performance of single command execution for each connection vs multiple command execution with single connection?
Also I want to know that in both cases like context connection and regular connection yields to same result? because the SP is deployed in DB itself. If I wrong please correct me.
There is no problem in executing large number of queries over a single connection. Any how you are using a SQL CLR Procedure with context connection. As mentioned in MSDN it states that:
using the context connection typically results in better performance and less resource usage. The context connection is an in-process–only connection, so it can contact the server "directly" by bypassing the network protocol and transport layers to send Transact-SQL statements and receive results. The authentication process is bypassed, as well.
Please refer this link for more information on context and regular connection.
No. It is fine to execute a large number of queries over a single connection.
Your code would likely perform worse if you were to open/close a connection to run those three SQL queries for each of those 1000+ rows.

Categories