SERVERPROPERTY('SERVERNAME') v/s 'localhost' - sql-server

I am using SQL Server 2008 R2.
I have created an SQL Job that fetches data from database tables and writes it to output file i.e. CSV on specific location.
For this I am using bcp and xp_cmdshell.
In bcp I need to pass the server name. Upto this I was using 'localhost' as server name, but by running this on another PC I have came to know that the 'localhost' login is not working on it so that the output files are not getting generated.
I searched about it and got another command that returns the server name along with server instance. i.e. SERVERPROPERTY('ServerName')
Now I am confused for using it. It is running OK with my local PC and Another PC also but my question is - Is it always run safely without any error if I put it on any other Server or PC? Which one of this is advisable to be used?

I think you're getting confused about the term "LocalHost". This is just an alias (aka loopback) that points back to the machine originating the connection.
For example, if my machine was named MYMACHINE and I was running a default instance on it, I could connect to the database either by specifying LocalHost or MYMACHINE and I would connect. If someone else was trying to connect from machine YOURMACHINE, they would only be able to connect to my database if they specified MYMACHINE. If they entered LOCALHOST it would try to connect to YOURMACHINE as that is where the connection is originating.
Back to your question now, yes, it is safe to get the servername value from SERVERPROPERTY('ServerName') as it will always report the correct and current network name of the server. This is not the case with ##SERVERNAME, so you should shy away from that for your purposes.
LocalHost: https://en.wikipedia.org/wiki/Localhost
##ServiceName (last paragraph of remarks section is important): http://msdn.microsoft.com/en-us/library/ms187944.aspx
P.S. I apologize for not adding a comment to the question, but my reputation is not currently high enough to do so.

Related

Connecting to SQL Server in a remote server from Access

We have a Server A and a Server B.
In Server A we have our ERPs made in Access and VBA.
In Server B we have an instance of SQL Server that needs to stay in that server.
Some Access databases need to link to some tables from that SQL Server instance and I don't want the password to be stored in the MSysObjects table, so I cannot manually link the tables checking the save the connection option.
I saved the connection string in a table with password obfuscation. With that connection string I re-link the tables on startup.
The instance is accessed through it's IP, not the name of the instance. If I use the name of the instance it doesn't work.
It works for me but not for other users except one.
The SQL Server instance has been properly configured to allow remote connections, the ports have been opened and rules added to firewall. If it wasn't properly configured it wouldn't work for me and the other user, so I'm pretty confident in that. The same with the connection string and the methods to stablish the connection in Access.
What I've tried:
Installing the SQL Native Client 11.0.
Installing a full SQL Server Express.
Configured the SQL Browser service to star automatically instead of being disabled.
Step 1 did not work for any user. Step 2 did work for one user but not for the rest. Step 3 did not had any effect. For me I had it installed in my machine since forever, so it doesn't apply.
If I try to do the same with a SQL Server instance in our LAN it works for every user, but not when the instance is in a remote server.
Note I have limited knowledge. Maybe I say something that does not make sense.
Ok, a few things:
Installing the SQL Native Client 11.0.
Ok, then you have to re-link the tables - choose the new driver. A refresh of the linked tables is NOT sufficent. And this ALSO means that each work station ALSO now must have native 11 instlled. And if you say decide to link using native 17 (a much newer odbc driver), then AGAIN YOU must install this native driver on each work station. While you can install multiple sql drivers on each workstation, the driver you used to link the tables MUST ALSO be installed and exist on each work station.
Installing a full SQL Server Express.
Why? What would installing a copy of sql server have to do with OTHER sql servers on other machines that you are attempting to connect to? You think installing sql server on a machine effects the sql server running say on amazon.com? So, this move makes no sense at all.
You are attempting to connect to some instance of sql server running on some other computer. Makes no sense nor will it help to install some copy of sql server that you not using, not connecting to, and that has zero to do with this issue.
Configured the SQL Browser service to star automatically instead of being disabled.
Where? The browser service is set to run and startup on the server and SAME machine where sql server is installed and running. So, yes, without question, those two sql servers A, and B most certainly MUST have the sql browser service running. That service is what allows the client computers to connect to that running instance of sql server. In the past, older (previous) versions of sql server would allow a default connection, but now in near all cases, you MUST ensure that the sql browser service is running on that computer that also has the database you are attempting to connect to.
it's worth to note that the instance is accessed through it's IP, not the name of the instance.
No, you likly have this incorrect. There are two part.
The server name - and then the "instance" of sql server running.
While you can swap out (not use) the server name, you STILL WILL NEED to specify the sql server instance.
So, you can use this format:
myservername\SQLEXPRESS
Or, you can replace the server with a IP address, but you STILL NEED the sql server instance. (by default, it is SQLEXPRESS - but you have to check what the instance of sql server database is).
192.168.1.30\SQLEXPRESS
So while you can use IP or server name - it is often more reliable to use the IP address, but that does NOT get you off the hook from having to specify the sql instance you connect to. Again, previous editions of sql server often allowed a "default" instance, and you did not in general have to specify the "instance", but now you do. And to be double clear, when using such a instance, that sql server needs to be running the sql browser service. (in fact, the browser service is what translates the incoming request to the given and correct instance of sql server).
I DON'T want the password to be stored in the MSysObjects table,
You don't have to, and in fact should NOT include the uid/password in your connection string. And in fact ZERO reason exists to do so.
What you do is execute a one time logon, and THEN link the tables without UID/password. This is not only a great idea, but it also means that your uid/password is not included in the connection strings, but also means users can't get at, or even by accident see/get the uid/password.
It also means that say someone where to launch a copy of access, and import the linked tables from this applcation. When they attempt to use the linked tables, they will NOT work.
So, then how do linked tables work without a password? (and this ALSO by the way saves you from having to re-link tables on startup!!!).
The way this works, is you in code execute a one time logon to the server on startup. That means you can either:
Prompt the user for their sql UID/password.
or
Have in code, the uid/password. (or perhaps in a text file y ou read on startup. You can thus hide, or encrypt or whatever for that uid/passwords.
Then in your startup code, you execute a one time logon. Once you done this, then all linked tables will now work - and work without having uid/password.
since you have two servers then you need to execute two logons, one for server A, and one for server B. But, once again, as long as the linked tables exist, then they will work.
Now, there are "longer" articles on how to use this logon idea, and then not have to include, or re-link your tables for the SQL uid/password.
The basic code to execute a logon is like this:
Function TestLogin(strCon As String) As Boolean
On Error GoTo TestError
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("")
qdf.connect = strCon
qdf.ReturnsRecords = False
'Any VALID SQL statement that runs on server will work below.
' this does assume user has enough rights to query built in
' system tables
qdf.sql = "SELECT 1 "
qdf.Execute
TestLogin = True
Exit Function
TestError:
TestLogin = False
Exit Function
End Function
Keep in mind, that ONCE you acheived a legal logon, then EVEN addtional logon attempts will return true.
Not usually a big deal, but this means you supply a valid connection to above, and if it logs on and works - then now all your linked tables (without uid/password) will work.
I note the above issue that ONCE you done the logon, then all 2nd or more times running the above will work (even if bad or incorrect!!! - DO NOT forget this tip!!!). (this can confuse the daylights out of a developer, since they execute logon, (or open a table). Then they test above routine with a BAD uid/passwords, and it works!!!
So, you have to EXIT access to clear out the password cache - no other way.
So, keep the above tips in mind.

Check if a named SQL Server Instance is running on local computer or not

You might find the question duplicate to these 2 links (Link1 and Link2) but they haven't been answered correctly. Let me brief you the question what i really want.
Looking For
I am looking for a way through which we can check if the provided SQL Instance Name is locally available or is residing on another remote computer.
My local SQL Server Instance name is Office-PC\SQLEXPRESS
Solutions i found which didn't work
1) Source : When i use the below code it says remote while the specified instance is present local.
SELECT Case when HOST_NAME()=SERVERPROPERTY('Office-PC\SQLEXPRESS') then 'local' else 'remote' end
2) I tried using the below code suggested in many comments on different websites. But it is showing incorrect output.
print HOST_NAME() //OUTPUT : Office-PC
print ##SERVERNAME //OUTPUT : HOME\SQLEXPRESS
3) Some people suggested to use the below command to get instance name which works perfectly but it doesn't tell us which of the instance is locally available.
SQLCMD -L
4) I also read somewhere (can't find the link) that we can get the Instance name from Registry itself.
That is all i could find.
If anyone has any other ways to find if the provided named SQL Instance is locally available, then please let me know.
This is a little more complicated than I'd like, but HOST_NAME() or the server machine name aren't reliable, the following should do:
SELECT CASE
WHEN client_net_address IN ('<local machine>', '<named pipe>', local_net_address) THEN 'local'
ELSE 'remote'
END AS [ConnectionType]
FROM sys.dm_exec_connections
-- The parent_connection_id check covers MARS
WHERE session_id = ##SPID AND parent_connection_id IS NULL
Disclaimer: not thoroughly tested with all possible transports. This works against local memory connections, LocalDB instances and TCP/IP connections, but it may not work correctly if you use the (rare) remote named pipes or VIA transports. These are disabled by default.
You can use SERVERPROPERTY like this:
SELECT CASE WHEN HOST_NAME()=SERVERPROPERTY('MachineName') THEN 'local' ELSE 'remote' END
MachineName
Windows computer name on which the server instance is running.
For a clustered instance, an instance of SQL Server running on a
virtual server on Microsoft Cluster Service, it returns the name of
the virtual server.

How do I setup OLEDB to connect to a remote database?

I am locally running an Oracle 11g database. I have a small program connecting to it in code via OLEDB in VC++ (It only runs some database tests, I'm making sure I have all the basics down before I go into the real thing.) The connection information in code only includes the provider, instance name, user name, and password. All this aspect works fine.
//For example, both these ways of connecting work:
result = dataSource.Open(DATABASE_PROVIDER, DATABASE_NAME,
DATABASE_USER_NAME, DATABASE_USER_PASSWORD);
result = dataSource.OpenFromInitializationString(L"Provider=OraOLEDB.OracleDataSource=orcl;User ID=SYSTEM;Password=admin;");
I now want to send this program to other computers in my network and run it from there, connecting to my database on my local machine.
How would I go about connecting the other computers to my database in a way that the code will understand?
I have been trying to connect locally via IP instead of "localhost", figuring I could then simply use the same code and client. In that regard, I have tried a few things without success:
-I have tried modifying the connection string to change "Data Source" to my IP, but it could not connect.
-I have tried adding some parameters from other connection string examples I had seen, but they were not for Oracle and were ignored.
-I have also tried modifying tnsnames.ora and listener.ora to change local host to an IP address, but I know that didn't work, as it would still connect if I entered rubbish.
Anyone has the knowledge to help out?
For an Oracle db, you should set up a new tnsnames entry on their individual machines that points to your local db. Then use that new tns name as the datasource. You'll also need to make sure that your local db instance is accessible to them in the first place. (This is not enabled by default in Oracle Express, by the way.)
I've also generally had more success using msdaora as the data provider instead of OraOLEDB.

Mirroring in SQL Server 2008

I'm trying to set up mirroring between two sql 2008 databases on different servers in my internal network, as a test run before doing the same thing with two live servers in different locations.
When I actually try and switch the mirroring on the target DB (with
ALTER DATABASE testdb SET PARTNER = N'TCP://myNetworkAddress:5022') I'm getting an error telling me that the server network address can not be reached or does not exist. A little research suggests this is a fairly unhelpful message that pops up due to a number of possible causes, some of which are not directly related to the server existing or otherwise.
So far I've checked and tried the following to solve this problem:
On the target server, I've verified that in SQL Configuration Manager that "Protocols for SQLEXPRESS" (my local installation is labelled SQLEXPRESS for some reason, even though querying SERVERPROPERTY('Edition') reveals that it's 64-bit Enterprise), and Client Protocols for SQL Native Client 10 all have TCP/IP enabled
I'm using a utility program called CurrPorts to verify that there is a TCP/IP port with the same number specified by the mirroring setup (5022) is open and listening on my machine. Netstat verifies that both machines are listening on this port.
I've run SELECT type_desc, port FROM sys.tcp_endpoints; and
SELECT state_desc, role FROM sys.database_mirroring_endpoints to ensure that everything is set up as it should be. The only thing that confused me was the "role" returns 1 .. not entirely sure what that means.
I've tried to prepare the DB correctly. I've taken backups of the database and the log file from the master DB and restored them on the target database with NORESTORE. I've tried turning mirroring on both while leaving them in the NORESTORE state and running an empty RESTORE ... neither seems to make much difference. Just as a test I also tried to mirror an inactive, nearly empty database that I created but that didn't work either.
I've verified that neither server is behind a firewall (they're both on the same network, although on different machines)
I've no idea where to turn next. I've seen these two troubleshooting help pages:
http://msdn.microsoft.com/en-us/library/ms189127.aspx
http://msdn.microsoft.com/en-us/library/aa337361.aspx
And as far as I can tell I've run through all the points to no avail.
One other thing I'm unsure of is the service accounts box in the wizard. For both databases I've been putting in our high-level access account name which should have full admin permissions on the database - I assumed this was the right thing to do.
I'm not sure where to turn next to try and troubleshoot this problem. Suggestions gratefully received.
Cheers,
Matt
I think that SQL Express can only act as a witness server with this SQL feature, you might get better mileage on ServerFault though.
Mike.
Your network settings might be OK. We got quite non-informative error messages in MS SQL - the problem might be an authorization issue and the server still will be saying "network address can not be reached".
By the way, how the authentication is performed? A MSSQL service (on server1) itself must be runned as a valid db user (on server2, and vice versa) in order to make the mirroring work.

SQL Server 2008 resolving localhost to a computer name

We're in the process of switching from Windows Server 2003 to Windows Server 2008, and we've encountered a frustrating problem:
In the old environment, some developers used sql server 2005 and others used sql server 2008. No problems. Our connection strings all pointed to: localhost/sqlserver. Now, on the new Server 2008 environment, Sql Server 2008 is occasionally resolving the "localhost" which immediately causes the thing to throw an exception.
In sys.servers we've changed the entry to point to localhost/sqlserver using:
exec sp_dropserver 'buckaroo-banzai\sqlserver'
exec sp_addserver 'localhost\sqlserver', local
exec sp_serveroption 'localhost\sqlserver', 'data access', TRUE
and the most frequent offending sql statements look like this (I know it's deprecated form) (note: they aren't the only offenders, just the most common ones):
[localhost\sqlserver].[database].[table].exec sp_executesql blahblah; exec sp_another_sp
The error I'm getting from those is:
Server buckaroo-bonzai\sqlserver not found in sys.servers
switching my sys.servers entry back to buckaroo-bonzai\sqlserver gets this error:
Server localhost-bonzai\sqlserver not found in sys.servers
If everything refers to the sql server as buckaroo-bonzai\sqlserver everything works, but for development, this just isn't an option.
For the record, this hasn't happened before on our windows server 2003 environments, just the new server 2008 environments; any ideas?
possible workarounds I've thought of:
remove the app.config and web.config files from version control (yech)
laboriously keep different connection strings in version controlled files (double yech)
version control the files, but somehow have some unified way of referring to an sql server on a local host (localhost maybe? )= )
Actually figure out why sql server 2008 is resolving localhost and stop it dead. (yay!)
Check the hosts file for redirection
Does it work any better if you use "." instead of "localhost", as in ".\sqlserver"? A single period refers to the local machine, but there's obviously no way to do a DNS lookup on it, so I doubt SQL Server would try.
It's not DNS or HOST file: the 4 part object name can't resolve because of no sys.servers entry.
You might be able to workaround with sp_addlinkedserver
EXEC sp_addlinkedserver
'buckaroo-banzai\sqlserver',
N'SQL Server',
#datasrc = 'localhost\sqlserver'
Now, this may fail (I can't test) because the "data_source" in sys.servers would be duplicated with "localhost\sqlserver". However, you can change this to something like "127.0.0.1\sqlserver" or "actualservername\sqlserver" to remove the duplicate.
I'm sure I did this some time ago...
Edit, after comment: The error might be related to Behaviour change in SQL 2008 for loopback linked servers. Sorry, i did't know about this.
sp_addserver is only useful for changing local server name (that is ##servername).
Well, sounds like a DNS issue. Not sure why it would have problems referring to itself as "localhost", but you might want to check your system HOSTS file, to make sure that hasn't been changed somehow.
The order of resolution for a DNS query is as follows:
The host first determines whether the name in question is its own name. It should take its actual name, as well as localhost, to be valid. If this isn't happening, it may not think it is who YOU think it is.
A Hosts file, located on each host, is queried. This file will override any external DNS.
DNS Servers are queried. If it can't find any information locally, it will ask someone, and that answer may not be correct, depending on how your DNS is configured.
As a last result, a host can use NetBIOS to try and find a host. This is bound to cause issues somewhere. Not a good thing to depend on, because often things will seem to just work, but then unexpected behaviour crops up, and it's hard to diagnose.

Resources