SQL Server trigger - connection info - sql

is it possible to get MSSQL connection info?not onli SUSER_ID(), SUSER_NAME(), ORIGINAL_LOGIN(), BUT other like:
IP
Connection string
ect..

You can get some more information from sys.dm_exec_connections:
e.g.
SELECT *
FROM sys.dm_exec_connections
WHERE session_id = ##SPID
This will get the connection info available for the current process (SPID).
This doesn't give the full connection string, but does give some more info like IP address (client_net_address).
This will work for SQL Server 2005 and above.

You didn't mention the version of SQL Server that you're using, but this should work for SQL 2005 and above. You can change the ##SPID as needed.
SELECT
conn.session_ID as SPID,
conn.client_net_address as IPAddress,
sess.host_name as MachineName,
sess.program_name as ApplicationName,
login_name as LoginName
FROM
sys.dm_exec_connections conn
INNER JOIN sys.dm_exec_sessions sess ON
conn.session_ID = sess.session_ID
WHERE
conn.session_ID = ##SPID

Related

Drop Database Error For Azure Synapse Database

When I try to drop a database in my builtin synapse pool, I'm getting the following error:
Cannot drop database "database name" because it is currently in use.
I've tried in both SSMS and Studio Synapse Studio and both returned errors.
I made sure there's no external datasources and file formats in the database.
The SSMS command I used was:
DROP DATABASE [database name]
Set Single_use mode doesn't work either. If you try this:
ALTER DATABASE [Database Name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
You'll get this:
SINGLE_USER is not supported for ALTER DATABASE.
What blocks a database from being dropped in synapse?
Thanks.
What worked for me is:
Run this in master
select DB_NAME(database_id), 'kill '+cast(session_id as varchar(10)), *
from sys.dm_exec_sessions
where DB_NAME(database_id) NOT IN ('master')
order by 1
Kill all sessions (active as well as sleeping) for the database you want to delete using the kill command returned by the query above. Run it in master:
kill 82
Drop the database from Synapse Studio, not from SSMS
Were you connected to MASTER?
Assuming there were no users connected, that is the only reason I can think it would be blocked.
Make sure to kill all the sessions manually.
One of the reasons why you could get this error is that there is an active connection via SSMS/ADS/Synapse Studio/Power BI or some other tool which is using that database at the moment.
When you close all the sessions, you should be able to delete the database successfully.
Here is the procedure for SQL serverless pool (aka SQL on-demand).
Step 1: Find the session which you want to kill using query bellow.
SELECT
'Running' as [Status],
Transaction_id as [Request ID],
'SQL serverless' as [SQL Resource],
s.login_name as [Submitter],
s.Session_Id as [Session ID],
req.start_time as [Submit time],
req.command as [Request Type],
SUBSTRING(
sqltext.text,
(req.statement_start_offset/2)+1,
(
(
CASE req.statement_end_offset
WHEN -1 THEN DATALENGTH(sqltext.text)
ELSE req.statement_end_offset
END - req.statement_start_offset
)/2
) + 1
) as [Query Text],
req.total_elapsed_time as [Duration]
FROM
sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) sqltext
JOIN sys.dm_exec_sessions s ON req.session_id = s.session_id
Step 2: Use the value in the Session ID column to kill the process which you want to. For example, if the Session ID is 81 then execute the following command
kill 81
Here is the procedure for SQL dedicated pool (aka SQL DW).
Step 1: Find the session which you want to kill using the bellow query
SELECT * FROM sys.dm_pdw_exec_sessions
where [status] = 'Active' and not sql_spid = ##SPID
GO
Step 2: Use the value in the [session_id] column to kill the process which you want to. for example if the session_id is 'SID210' then execute the following command
kill 'SID210'
GO

SQL server 2008 r2 Last database user date and time

How to find last database users date and time sql server 2008 r2?
You can try this:
SELECT accdate, name FROM master.dbo.syslogins
or use
select max (login_time), login_name
from sys.dm_exec_sessions
group by login_name;
You could set up a so-called logon trigger.
Example:
USE master;
GO
CREATE LOGIN login_test WITH PASSWORD = '3KHJ6dhx(0xVYsdf' MUST_CHANGE,
CHECK_EXPIRATION = ON;
GO
GRANT VIEW SERVER STATE TO login_test;
GO
CREATE TRIGGER connection_limit_trigger
ON ALL SERVER WITH EXECUTE AS 'login_test'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN()= 'login_test' AND
(SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND
original_login_name = 'login_test') > 3
ROLLBACK;
END;
Example taken from https://msdn.microsoft.com/en-us/library/bb326598(v=sql.105).aspx

How do you reference a second SQL Server

How can I reference a second server in SQL.
SELECT A.datasetid,
A.dsdate,
B.datasetid AS Expr1,
B.dsdate AS Expr2
FROM we_ci_db.tblopportunitydatasets AS A
INNER JOIN we_ci_db.tblopportunitydatasets AS B
ON A.datasetid = B.datasetid
Assume that table 'B' is on a different server, what would the syntax be. I've tried putting the server name before the schema, but it doesn't recognise it
You must configure a linked server. Once that is configured, the linked server may be referenced as
server.database.schema.object
You'll first need to create a Linked Server by running the addlinkedserver stored procedure:
USE [master]
GO
EXEC master.dbo.sp_addlinkedserver
#server = N'SRVR002\ACCTG',
#srvproduct=N'SQL Server' ;
GO
After that, you can refer to the linked server with the syntax:
select *
from [SRVR002\ACCTG].[database name].[owner name].[table name]
More Info

How to find the number of concurrent SQL Server connections

I have a SQL Server that is reaching the max limit of concurrent connections. I have many different servers & services connecting to one SQL Server at the same time.
I did find another query that seems to work:
SELECT DB_NAME(dbid) AS DBName,
COUNT(dbid) AS NumberOfConnections,
loginame AS LoginName,
nt_domain AS NT_Domain,
nt_username AS NT_UserName,
hostname AS HostName
FROM sys.sysprocesses
WHERE dbid > 0
GROUP BY dbid,
hostname,
loginame,
nt_domain,
nt_username
ORDER BY NumberOfConnections DESC;
However, this gives me the number of connections which is good. How do i further dig down this to find to see the each connection and what action they are doing?
the sql command "sp_who" which provides information about current users, sessions, and processes in an instance of the Microsoft SQL Server Database Engine (MSDN) From here, you should be able to send the results into a temp table and group them by servername.
such as the following...
CREATE TABLE #tbl (
spid int
, ecid int
, status varchar(50)
, loginame varchar(255)
, hostname varchar(255)
, blk varchar(50)
, dbname varchar(255)
, cmd varchar(255)
, request_id varchar(255)
)
GO
INSERT INTO #tbl EXEC sp_who
SELECT COUNT(0), hostname FROM #tbl group by hostname
DROP TABLE #tbl
GO
Are you talking about how to check the connections that are reaching your SQL Server instance? How about some DOS commands? try to search for the port 1433 or for the PID of your SQL Server process.
netstat -nao | find "1433"
To find the PID (process identifier) that you are looking for, just go to your task manager and customize the processes view, mode details here:
http://www.mydigitallife.info/how-to-get-and-view-process-identifier-process-id-or-pid-on-windows/

Particular query causes ADO Recordset to fail with E_FAIL

i'm trying to run (two) queries against SQL Server 2005 using ADO:
SELECT
sp.nt_username AS NTUsername,
sp.hostname AS HostName
FROM sys.dm_tran_locks tl
INNER JOIN master.dbo.sysprocesses sp
ON tl.request_session_id = sp.spid
WHERE tl.resource_type = N'APPLICATION'
AND tl.resource_database_id = (
SELECT dbid
FROM master.dbo.sysprocesses
WHERE spid = ##spid)
and the SQL Server 2000 compatible version:
SELECT
sp.nt_username AS NTUsername,
sp.hostname AS HostName
FROM master.dbo.syslockinfo sli
INNER JOIN master.dbo.sysprocesses sp
ON sli.req_spid = sp.spid
WHERE rsc_type = 10 --10=Appliction
AND rsc_dbid = (
SELECT dbid
FROM master.dbo.sysprocesses
WHERE spid = ##spid)
The query executes fine:
IRecordset rs =new Recordset();
rs.CursorLocation = adUseClient; //the default for a Recordset is adUseServer (Connection.Execute's default is adUseClient)
rs.CursorType := adOpenForwardOnly; //the default
rs.Open(szQuery, conn.ConnectionObject,
adOpenForwardOnly, //CursorType
adLockReadOnly, //LockType
adCmdText);
But then checking the status of BOF or EOF:
if (rs.EOF) then
triggers an exception:
HRESULT: 0x80004005 (Unspecified error)
Error message: "Data provider or other service returned an E_FAIL status"
What is about this query that causes ADO to fail so miserably?
Note: There really is a matching row:
The provider i'm using in the connection string is Provider=SQLOLEDB.
Bonus Chatter:
sysprocesses
nt_username nchar(128)
hostname nchar(128)
and querying for both - but one at a time - works, e.g.:
SELECT
sp.nt_username AS NTUsername
and
SELECT
sp.hostname AS HostName
work. Querying for both fail.
i found the problem. It's a known issue with SQL Server 2005 and ADO:
Even though nt_username and hostname already are nchar(128), you need to manually cast them to nchar(128)
SELECT
CAST(sp.nt_username AS nchar(128)) AS NTUsername,
CAST(sp.hostname AS nchar(128)) AS HostName
FROM sys.dm_tran_locks tl
INNER JOIN master.dbo.sysprocesses sp
ON tl.request_session_id = sp.spid
WHERE tl.resource_type = N'APPLICATION'
AND tl.resource_database_id = (
SELECT dbid
FROM master.dbo.sysprocesses
WHERE spid = ##spid)
There is also a known bug with SQL Server 2005 and ADO and the use of ##spid in a query; you cannot do it. Fortunately i can, in this case, use DB_ID():
SELECT
CAST(sp.nt_username AS nchar(128)) AS NTUsername,
CAST(sp.hostname AS nchar(128)) AS HostName
FROM sys.dm_tran_locks tl
INNER JOIN master.dbo.sysprocesses sp
ON tl.request_session_id = sp.spid
WHERE tl.resource_type = N'APPLICATION'
AND tl.resource_database_id = DB_ID()
Bada-bing.
SQL Server 2005 bug.
It might still exist in SQL Server 2008, SQL Server 2008 R2, SQL Server 2012