In my app the users gets to pick from a list of SQL Server in the network. The thing is I need to know if the chosen instance is a local or remote computer.
Is there a way I can ask that SQL instance what computer is she on? Is there a way a can figure that out?
Edit1: I want to know the host name where the SQL Server is hosted so I can then compare that to System.Environment.MachineName and know for sure is that Sql Server is running on the same machine where my app is running
Edit2: ##servername returned my computername\sqlinstance while SELECT SERVERPROPERTY('MachineName') returns just the computername, which is exactly what I want
Use ##Servername, for example:
SELECT ##servername
Alternately you could do this
SELECT SERVERPROPERTY('MachineName')
From MSDN on the differences between these approaches:
The ServerName property of the
SERVERPROPERTY function and
##SERVERNAME return similar
information. The ServerName property
provides the Windows server and
instance name that together make up
the unique server instance.
##SERVERNAME provides the currently
configured local server name.
The ServerName property and
##SERVERNAME return the same
information if the default server name
at the time of installation has not
been changed.
If the local server name has been
changed from the default server name
at installation time, ##SERVERNAME
returns the new name.
Do you actually have login permissions on all the instance(s) of SQL Server? If so you could execute sp_helpserver or ##servername and compare the name returned with Environment.MachineName.
If you don't have login access, you can write a small C# console program to return the server name of every SQL Server instance on the local network:
using System;
using System.Data.Sql;
class Program
{
static void Main()
{
// Retrieve the enumerator instance and then the data.
SqlDataSourceEnumerator instance =
SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
// Display the contents of the table.
// The first column is the server name.
DisplayData(table);
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
private static void DisplayData(System.Data.DataTable table)
{
foreach ( System.Data.DataRow row in table.Rows )
{
foreach ( System.Data.DataColumn col in table.Columns )
{
Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
}
Console.WriteLine("============================");
}
}
}
sp_who2 returns the hostname
Related
Is there a way to modify the column program_name in table master..sysprocesses?
I have found two methods, but both set the name during the creation of the connection:
Using parameter appname when executing an isql command
Adding parameter APP= in a connection string when opening an ODBC connection.
I am looking for a way to modify it AFTER it has been created.
I tried the following example:
sp_configure "allow updates",1
go
UPDATE master..sysprocesses
SET program_name = 'test'
where hostname = 'server'
and hostprocess = '23240'
go
sp_configure "allow updates",0
go
But failed:
Could not execute statement.
Table 'sysprocesses' can't be modified.
Sybase error code=270
Severity Level=16, State=1, Transaction State=0
Line 4
You can continue executing or stop.
Changes to column sysprocesses.program_name are not allowed after its been created. But there are three columns in sysprocesses which can be changed after creation of the connection
sysprocesses.clientname
sysprocesses.clientapplname
sysprocesses.clienthostname
Exerpt from the Sybase Infocenter website:
Changing user session information
The set command includes options
that allow you to assign each client an individual name, host name,
and application name. This is useful for differentiating among clients
in a system where many clients connect to Adaptive Server using the
same name, host name, or application name.
The partial syntax for the set command is:
set [clientname client_name | clienthostname host_name | clientapplname application_name]
where:
client_name – is the name you are assigning the client.
host_name – is the name of the host from which the client is
connecting.
application_name – is the application that is connecting to Adaptive
Server.
These parameters are stored in the clientname, clienthostname, and
clientapplname columns of the sysprocesses table.
For example, if a user logs in to Adaptive Server as "client1", you
can assign them an individual client name, host name, and application
name using commands similar to:
set clientname 'alison'
set clienthostname 'money1'
set clientapplname 'webserver2'
.
.
.
Use the client’s system process ID to view their connection
information. For example, if the user “alison” described above
connects with a spid of 13, issue the following command to view all
the connection information for this user:
select * from sysprocesses where spid = 13
To view the connection information for the current client connection (for example, if the user “alison” wanted to view her own connection information), enter:
select * from sysprocesses where spid = ##spid
I work with sql server as database in Java NetBeans and I want to create a database from Java, before doing this I need to check if it exists or not, I know that the sql syntax is large different from MySQL syntax so at the begining I did this sql syntax:
CREATE DATABASE IF NOT EXISTS
But it returns error so please can you tell how to check if it exist in this case it will not be created and if not exists how to create one. THANK YOU
One more way is to use DB_ID:
IF DB_ID(N'YourDBName') IS NULL
CREATE DATABASE YourDBName ....;
Returns the database identification (ID) number.
try {
String sql = "SELECT * FROM master.dbo.sysdatabases WHERE name = '"+base+"'";
pstt=conn.prepareStatement(sql);
rs = pstt.executeQuery();
if (rs.next()){
System.out.println("Database exist");
}
else{
String sqll = "CREATE DATABASE "+base;
pstt=conn.prepareStatement(sqll);
pstt.executeUpdate();
}
}
catch(Exception e){
}
i've tried this and it works fine with me, any way thanks for your reply
I'm attempting to gather information about the SQL Server services on remote computers, using SMO thru a Powershell script. My code seems to work fine with multiple instances present on the server when they are the same SQL Server version.
My problem is that when there are two instances installed that are different versions of SQL Server, only one set of services are present in the ManagedComputer object I'm creating.
Specifically, I have an EXPRESS install of SQL Server 2008 R2, as a named instance called 'SQLEXPRESS'. The default instance of SQL Server is 2012. The below code gives the below output, which is missing the 2012 services:
PS C:\od\scripts\Powershell\ServerInventory> [void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement")
PS C:\od\scripts\Powershell\ServerInventory> $s = New-Object -typeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer myComputer
PS C:\od\scripts\Powershell\ServerInventory> $s.services.name
MSSQL$SQLEXPRESS
SQLAgent$SQLEXPRESS
SQLBrowser
PS C:\od\scripts\Powershell\ServerInventory> $s
ConnectionSettings : Microsoft.SqlServer.Management.Smo.Wmi.WmiConnectionInfo
Services : {MSSQL$SQLEXPRESS, SQLAgent$SQLEXPRESS, SQLBrowser}
ClientProtocols : {}
ServerInstances : {MSSQLSERVER, SQLEXPRESS}
ServerAliases : {}
Urn : ManagedComputer[#Name='myComputer']
Name : myComputer
Properties : {}
UserData :
State : Existing
For the ManagedComputer object, I don't see the ability to pass it anything other than the computer name I'm running on, nothing specific to a SQL Server instance.
I'm looking for a way to gather information about both instance's services.
To search network for SQL Server instances I use this script:
clear
#get all servers with SQL Server
$servers = [System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()
#loop through them and get properties
ForEach ($comp in $servers) {
$machine = $comp.ServerName
try {
Get-WmiObject win32_Service -Computer $machine |
where {$_.DisplayName -match "SQL Server \("} |
select SystemName, DisplayName, Name, State, Status, StartMode, StartName, Caption
} catch {
Write-Host("Error retrieving data from $machine")
}
}
Output like:
SystemName : MACHINENAME
DisplayName : SQL Server (INSTANCE1)
Name : MSSQL$INSTANCE1
State : Running
Status : OK
StartMode : Auto
StartName : WORK\USSR$DBEngine
Caption : SQL Server (INSTANCE1)
SystemName : MACHINENAME
DisplayName : SQL Server (INSTANCE2)
Name : MSSQL$INSTANCE2
State : Running
Status : OK
StartMode : Auto
StartName : WORK\USSR$DBEngine
Caption : SQL Server (INSTANCE2)
Error retrieving data from NextMachineName
..etc
As you can see on MACHINENAME there is 2 instances running. We don't have any servers with 2 different versions of SQL Server, so I can not check this issue.
I need to get the folder with full path of my SQL Server instance installed on my machine, using vb code.
For example, I have installed instance MyComputer\MyInstanceName.
I know it is in C:\Program Files (x86)\Microsoft SQL Server\MSSQL.1\MSSQL
but how can I get this path using vb.net code?
Thanks
It's not all that obvious, but you can find everything you're looking for in the registry.
Basically:
you need to inspect the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL subkey to find the installed instances and their "internal" names
with that internal name, you can inspect the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\(internal name)\Setup node to find everything you might want to know about that instance
In C# code (and for a 64-bit OS, with 64-bit versions of SQL Server), this would be:
// open the 64-bit view of the registry, if you're using a 64-bit OS
RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
// find the installed SQL Server instance names
RegistryKey key = baseKey.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
// loop over those instances
foreach (string sqlInstance in key.GetValueNames())
{
Console.WriteLine("SQL Server instance: {0}", sqlInstance);
// find the SQL Server internal name for the instance
string internalName = key.GetValue(sqlInstance).ToString();
Console.WriteLine("\tInternal instance name: {0}", internalName);
// using that internal name - find the "Setup" node in the registry
string instanceSetupNode = string.Format(#"SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup", internalName);
RegistryKey setupKey = baseKey.OpenSubKey(instanceSetupNode, false);
if (setupKey != null)
{
// in the "Setup" node, you have several interesting items, like
// * edition and version of that instance
// * base path for the instance itself, and for the data for that instance
string edition = setupKey.GetValue("Edition").ToString();
string pathToInstance = setupKey.GetValue("SQLBinRoot").ToString();
string version = setupKey.GetValue("Version").ToString();
Console.WriteLine("\tEdition : {0}", edition);
Console.WriteLine("\tVersion : {0}", version);
Console.WriteLine("\tPath to instance: {0}", pathToInstance);
}
}
I have a PostgreSQL database in use for a complex php web site (And VB.Net/C# management applications) which require access to execute stored procedures on a Microsoft SQL Server 2008 database. The method chosen to perform this interaction is to use plperl functions within the PostgreSQL database to wrap access to the MSSQL stored procedures.
We are using the perl DBI module to handle the data retrieval from MSSQL database.
I am a neophyte when it comes to perl in general and specifically when using it with PostgreSQL. I have created the function shown below to return a set of composite type
CREATE TYPE "public"."permissions_return" AS (
"rolename" TEXT,
"roledescription" TEXT,
"permissionname" TEXT,
"permissiondescription" TEXT
);
The stored proc called from within the function works fine and returns data when run through a slightly different perl script run from the command-line, or directly from the MSSQL Server. I have not been able to figure out how to return data from my function when using:
SELECT * FROM fn_perltest(153);
The result is always an empty set.
CREATE FUNCTION fn_perltest(integer) RETURNS SETOF permissions_return AS $$
use strict;
use DBI;
my $data_source = q/dbi:ODBC:Production/;
my $user = q/afunkyusername/;
my $password = q/afunkierpassword/;
my $dbh = DBI->connect($data_source, $user, $password);
my $sth = $dbh->prepare(q/up_DCORsel_getUserPermissionByUserID $1 ;/);
$sth->execute();
while ( defined ( my $row = $sth->fetchrow_array() )) {
return next ({
rolename => $row->{RoleName},
roledescription => $row->{RoleDescription},
permissionname => $row->{PermissionName},
permissiondescription => $row->{PermissionDescription}
});
}
return;
$$ LANGUAGE 'plperlu'
If this helps, Postgres is running on a Fedora 13 server. Access to MSSQL Server is configured using unixODBC with the freetds driver. Access to the MSSQL server has been tested and works fine using the isql command-line tool and a simple perl script.
Any ideas would be greatly appreciated. I'm concerned I may run out of hair to pull out.
Regards
Shane
This doesn't answer your question directly, but I have used dblink when attempting to have one database query data in another database. It seemed to work well. Obvious plperlu has a lot more power than dblink, but I don't have any experience with it (just perl and postgresql :-)
dblink can be found in postgresql's contrib directory.