How to ping from within an SSIS package? - sql-server

I'm trying to verify a connection through a firewall, and we are very limited in the access allowed. Ultimately, data will be loaded from an Access database on another server to our SQL Server database using an SSIS package. I can ping that source server from my computer and get a reply -- I want to put that in our SSIS package and see if the destination SQL Server can get a ping reponse.
Right now, the OLE DB source connection fails from both my computer and the server, ping works directly from my computer, and I don't know if it will work from the server or not. SSIS is the only thing I can put and run on the server, and it also what we plan on using for getting data from this other source.
Is there a fairly simple way to use a SSIS package to ping a specific address? I probably don't even need to know anything more than whether it fails or works.
I cannot use sys.sp_comdshell because that is turned off as part of our security configuration for our sql server. I cannot remote to the server and use ping directly.

You could add a Script Task to your Control Flow with some code that does the ping for you. The System.Net.NetworkInformation namespace in .NET 2.0 and up contains a Ping class that can do the work for you. I suspect it might look something like this:
public void Main()
{
using (Ping ping = new Ping())
{
try
{
PingReply reply = ping.Send(url, 100);
if (reply.Status == IPStatus.Success)
{
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
catch
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
}

Related

Deployed package execution in SSISDB shows success but write action never happened

I simplified the issue to a simple write action in C# script task, writing current time stamp into a text file located on the same machine in C:\test\ granted full control to Everyone. The environment is SQL Server 2016, Visual Studio 2015, and Windows Server 2016.
If create a SQL Server Agent job from file system, it updates the text file as expected. If deploy the package into SSISDB and execute, the execution report shows all green and success while the write action never happened. And I was not able to find any clue in system logs.
I will be very grateful to inputs on:
1) What might be wrong in this simple-write test; and
2) How to get more useful log information about this error and possibly other issues.
FYI, Related issues resolved before this post:
SSIS deployed package fails to map drive tag to network shared folder
Code in the simple-write script task.
public void Main()
{
Dts.TaskResult = (int)ScriptResults.Failure;
try
{
// TODO: Add your code here
using (var writer = new StreamWriter("C:\\test\\simple-write.txt", true, Encoding.Unicode))
{
writer.WriteLine(DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK"));
writer.Flush();
}
Dts.TaskResult = (int)ScriptResults.Success;
}catch(Exception ex)
{
Dts.Events.FireError(0, "Simple-Write-Test", ex.ToString(), String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
I got the answer on the following link:
https://social.msdn.microsoft.com/Forums/en-US/6c34874c-03a2-4926-8989-b977c1ec1866/deployed-package-execution-in-ssisdb-shows-success-but-write-action-never-happened?forum=sqlintegrationservices
It seems to be a compatibility issue between the latest version of Management Studio (2017 suite) and SQL Server 2016 database. The script task in the deployed package was silently ignored.

Qt: Low speed when transferring data from remote database

I am using Qt5 on Windows7.
I am writing a Qt app to replace an old C# app (written 7-8 years ago). The goal is to connect and transfer data from some remote databases. The remote DB servers are MS SQL Server 2000.
I already have the app running, but I noticed the data transfer takes much more time comparing to the old C# app...
So, I was just wondering what may cause such a low data transfer rate?
Maybe I forgot something or maybe I am doing something wrong...
Here is the code I am using to connect to the remote database(s):
void RemoteDB::openConnection(const QString & serverIP, const QString & dbName)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(QString("DRIVER={SQL Server};SERVER=%1;DATABASE=%2;").arg(serverIP).arg(dbName));
db.open("user", "password");
}
Query code:
SqlRecord record;
QSqlQuery query(QSqlDatabase::database());
if(query.exec("SELECT * FROM VehicleStatus") == true)
{
while(query.next() == true)
{
record.Vehicle = query.value("Vehicle").toInt();
record.Status = query.value("Status").toInt();
record.AppVersion = query.value("AppVersion").toString();
record.DateTime = query.value("DateTime").toString();
...
}
}
Please help, any idea?
Thanks for your time!
Beside trimming the fat (i.e. only selecting the fields you need instead of *), check that you're using the best ODBC driver possible.
SQL Server has a "ODBC SQL Server Native Client" that you can install and use, it should be faster than the default ODBC driver. It might already be installed on your PC, but not selected for your data source, or you can try to install it from some dusty SQL Server 2000 DVD (or was it CDs back then ? or - not kidding - floppy disks ?), or from a more recent SQL Server version. YMMV.
Not sure about C#, but a C# app has probably access to a fast-line driver that doesn't need ODBC.

Access SQL Server database on another computer

I have created a little tool, which lets me write some data into a database.
This database is located on my laptop and as of until now, that tool was only able to locally access the database. I now need my friend to be able to use that tool to connect to my database from his own PC.
I've read about port-forwarding, opening the firewall, etc., but I've never really gotten the hang of it.
This is what I currently have:
SqlConnection myConnection = new SqlConnection("user id=admin;" +
"password=password;server=myDatabase;" +
"Trusted_Connection=yes;" +
"database=database; " +
"connection timeout=30");
And of course, the usual procedure:
try
{
myConnection.Open();
//Do Stuff
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
Note: I don't really care much about security, since the usage of this tool is only temporary and I doubt that anyone would try to "break in".
Take a look upon activating Remote connections to your SQL Server Instance. As already mentioned, they will not work on Express editions, but since your project is temporary, you may install a trial (lasts for 180 days).

How to simulate a data exception with localdb

I'm using a LocalDB database with EntityFramework on an ASP.NET MVC project.
How can I simulate a connection failure to test the following try...catch block?
try
{
if (ModelState.IsValid)
{
db.Entry(course).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes.");
}
I've tried trying to take the database offline in SQL management studio, but it just hangs. I can't stop the SQL service as LocalDB doesn't run as a service.
Have you tried giving it a non-existing name of LocalDB instance? Just put this in your connection string for this test:
Server=(localdb)\missing_instance`
(if you embed this connection string in code don't forget to escape the \ character :-))
connectionString="Server=(localdb)\\missing_instance;..."
You can stop a LocalDB instance even though it doesn't run as a service, you can use the SQLLocalDB.exe tool to do this:
SqlLocalDB Utility

Is there a jdbc driver for SQL Server that can search for database instances on network?

Is there a jdbc driver for SQL Server that can search for database instances on network?
Just wanting to emulate "OSQL -L" from the JDBC driver. Dont want to have to call OSQL from JNI or something. I also don't want to have to write my own code for scanning a UDP port.
I want my Java application to be able to search for live SQL Servers and prompt me with a list of available servers. Isn't this a reasonable expectation for a JDBC driver? OSQL.exe can do it and so why not the JDBC driver?
The JDBC API doesn't offer any facilities for this. Your best bet is to fall back to low level Java socket programming and test if TCP port 1433 is open or not and then try to connect it.
Socket socket = null;
try {
socket = new Socket("localhost", 1433);
System.out.println("Service is available!");
} catch (Exception e) {
System.out.println("Service is not available.");
} finally {
if (socket != null) try { socket.close(); } catch (IOException logOrIgnore) {}
}
Once confirmed that the service is available, then you can connect it the usual way without database name in URL and get a list of available catalogs (databases) by DatabaseMetaData#getCatalogs().
osql is actually quite stupid when it comes to finding SQL Server instances.
The same technique is used by SSMS, Enterprise Manager etc and it's unreliable if your SQL boxes aren't all in the same room (Ok, slight exaggeration) with default instances.
What you could do is roll your own based on the source code here from SQLPing1.1 and SQLPing.Net... which I've used to good effect before.

Resources