Cannot open the properties tab in SSMS for Managed Instance Database - sql-server

I am using Azure Managed Instance for some migration tasks. I have multiple databases in that all are working fine.
But when I try to open the properties for a database named GCDCalculation, I am getting the following error:-
And the whole error is:-
Cannot show requested dialog.
===================================
Cannot show requested dialog. (SqlMgmt)
------------------------------
Program Location:
at Microsoft.SqlServer.Management.SqlMgmt.DefaultLaunchFormHostedControlAllocator.AllocateDialog(XmlDocument initializationXml, IServiceProvider dialogServiceProvider, CDataContainer dc)
at Microsoft.SqlServer.Management.SqlMgmt.DefaultLaunchFormHostedControlAllocator.Microsoft.SqlServer.Management.SqlMgmt.ILaunchFormHostedControlAllocator.CreateDialog(XmlDocument initializationXml, IServiceProvider dialogServiceProvider)
at Microsoft.SqlServer.Management.SqlMgmt.LaunchForm.InitializeForm(XmlDocument doc, IServiceProvider provider, ISqlControlCollection control)
at Microsoft.SqlServer.Management.SqlMgmt.LaunchForm..ctor(XmlDocument doc, IServiceProvider provider)
at Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer.ToolMenuItemHelper.OnCreateAndShowForm(IServiceProvider sp, XmlDocument doc)
at Microsoft.SqlServer.Management.SqlMgmt.RunningFormsTable.RunningFormsTableImpl.ThreadStarter.StartThread()
===================================
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. (.Net SqlClient Data Provider)
------------------------------
For help, click: https://learn.microsoft.com/sql/relational-databases/errors-events/mssqlserver-512-database-engine-error
------------------------------
Server Name: my-project-database.database.windows.net, 3342
Error Number: 512
Severity: 16
State: 1
Line Number: 7
------------------------------
Program Location:
at Microsoft.SqlServer.Management.SqlManagerUI.DBPropGeneralData.InitProp()
at Microsoft.SqlServer.Management.SqlManagerUI.DBPropGeneralData..ctor(CDataContainer context)
at Microsoft.SqlServer.Management.SqlManagerUI.DBPropGeneral..ctor(CDataContainer dataContainer, DatabasePrototype prototype)
at Microsoft.SqlServer.Management.SqlManagerUI.DBPropSheet.Init(CDataContainer dataContainer)
at Microsoft.SqlServer.Management.SqlManagerUI.DBPropSheet..ctor(CDataContainer context)
All other Databases are working fine.
Added to this, I want to know that, is there specific query is triggered in the backend when we try to open the properties tab (Or any other tab).

Finally, one I can answer. Kollira is on the right track with this, the reason you get the error is that backupset contains records linking more than one database to the same ID. This happens because the DB was probably brought into SQL MI via the migration tool which creates the backupset with a GUID instead of the database name. When you do your own copy-only backup to URL, it creates a new backupset with the real name. This is not an optimised query to prove it but here goes.
select db_id(database_name),database_name, [type], max(backup_finish_date) as latest from msdb..backupset where ([type] = 'D' or [type] = 'L' or [type]='I') and db_id(database_name) = (select database_id from sys.databases where name = 'Your_Database') group by database_name, [type]
Then we can see there is more than one DB listed, you can probably see the wrong one as it was created just when you backed up. So with this list of probably 2 DBs
Select * from msdb..backupset where database_name in('DB1', 'DB2')
We can see conflicting backupsets. In my case the one with the real name was actually the new one that I wanted to remove, the other was a GUID I assume from my migration. So I just deleted the backupset as there were no backups associated. So simply:
Delete from msdb.dbo.backupset where database_name = 'TheDatabaseName'
Boom, now properties rendered, and the original backup chain was still correct.
I am not a SQL pro, so use at your own risk. Also, since this is no longer a Managed instance unique problem, maybe a SQL pro can advise a better solution.

The problem is with backups. Run this query and update the database name to the one which is latest.
create table #tempbackup (database_name nvarchar(128), [type] char(1), backup_finish_date datetime)
insert into #tempbackup
select database_name, [type], max(backup_finish_date) from msdb..backupset where [type] = 'D' or [type] = 'L' or [type]='I' group by database_name, [type]
SELECT
(select backup_finish_date from #tempbackup where type = 'D' and db_id(database_name) = dtb.database_id)
AS [LastBackupDate]
FROM
master.sys.databases AS dtb
WHERE
(dtb.name='Your Database Name')
drop table #tempbackup

Related

Get subscriber's name from SSRS database

what I am trying to do is creating a report about failed subscriptions in MS SQL Server Report Server (SSRS). What I have done so far is the following SQL statement:
USE ReportServer
GO
WITH SubscriptionsCTE AS
(
SELECT
c.[Name],
c.[Path],
s.[Description],
s.LastStatus,
s.LastRunTime,
CONVERT(xml, s.ExtensionSettings) AS ExtensionSettings,
s.DeliveryExtension
FROM
dbo.Subscriptions s
INNER JOIN dbo.[Catalog] c ON c.ItemID = s.Report_OID
WHERE
s.LastStatus LIKE 'Failure%'
)
SELECT
[Name],
[Path],
[Description],
LastStatus,
LastRuntime,
CASE
WHEN DeliveryExtension = 'Report Server FileShare' THEN (SELECT e.c.value('(Value/text())[1]', 'nvarchar(max)') FROM ExtensionSettings.nodes('ParameterValues/ParameterValue') e(c) WHERE e.c.value('(Name/text())[1]', 'nvarchar(max)') = 'USERNAME')
WHEN DeliveryExtension = 'Report Server Email' THEN (SELECT e.c.value('(Value/text())[1]', 'nvarchar(max)') FROM ExtensionSettings.nodes('ParameterValues/ParameterValue') e(c) WHERE e.c.value('(Name/text())[1]', 'nvarchar(max)') = 'TO')
ELSE NULL
END AS Subscriber
FROM
SubscriptionsCTE
The problem is that the field Subscriber is encrypted for FileShare subscriptions. I understand that it is for the password... but for the user name? As an administrator I have access to the subscriptions via the GUI, but it is a pain to look into every report's admin panel to find out the user name.
I did something like
CASE WHEN Subscriber = '(some encrypted string)' THEN 'User 1'
WHEN Subscriber = '(some other encrypted string)' THEN 'User 2'
(etc.)
ELSE NULL
END AS Subscriber
But obviously, it is not encrypted in the same way in every record, so 'User 1' has a different encrypted string in every subscription.
Is there any way to decrypt these strings? I have the .snk file from the Report Server certificates backup (and know the password for it). Does this help?
Thanks for helping...
Best wishes
Michael

How to determine who performed DROP/DELETE on Sql Server database objects?

There is always a need to find out details, either intentionally Or mistakenly someone executed DROP/DELETE command on any of following SQL Server database objects.
DROPPED - Table from your database
DROPPED - Stored Procedure from your database
DELETED - Rows from your database table
Q. Is there TSQL available to find db user who performed DELETE/DROP?
Q. What kind of permissions are needed for user to find out these details?
Did you check this ?
Right click on database.
Go to as shown in image :
Solution 2 :
This query gives alot of useful information for a database(apply filter as required) :
DECLARE #filename VARCHAR(255)
SELECT #FileName = SUBSTRING(path, 0, LEN(path)-CHARINDEX('\', REVERSE(path))+1) + '\Log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT gt.HostName,
gt.ApplicationName,
gt.NTUserName,
gt.NTDomainName,
gt.LoginName,
--gt.SPID,
-- gt.EventClass,
te.Name AS EventName,
--gt.EventSubClass,
-- gt.TEXTData,
gt.StartTime,
gt.EndTime,
gt.ObjectName,
gt.DatabaseName,
gt.FileName,
gt.IsSystem
FROM [fn_trace_gettable](#filename, DEFAULT) gt
JOIN sys.trace_events te ON gt.EventClass = te.trace_event_id
WHERE EventClass in (164) --AND gt.EventSubClass = 2
ORDER BY StartTime DESC;

If a table is dropped from pg_class accidentally then how to restore it from backup?

I accidentally dropped a table from pg_class and I have the same table present in a different server inside a schema. How do I restore it?
I have tried this
psql -U {user-name} -d {desintation_db} -f {dumpfilename.sql}`
This is what i'm getting -
ERROR: type "food_ingredients" already exists`
HINT: A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type.`
ERROR: relation "food_ingredients" does not exist`
ERROR: syntax error at or near "19411"`
LINE 1: 19411 10405 2074 45.3333333333 0.17550085492131515 NULL NULL...`
ERROR: relation "food_ingredients" does not exist`
food_ingredients is the table which I dropped from the pg_class.
That's what you get from messing with system catalogs.
The simple and correct answer is “restore from a backup”, but something tells me that that's not the answer you were looking for.
You could drop the type that belongs to the table, all indexes on the table, all constraints, toast tables and so on, but you'd probably forget to drop something or drop something you shouldn't and end up with a bigger mess than before.
Moreover, the table file would be left behind and it would be hard to identify and delete it.
It would be appealing to try and recreate the pg_class row that you dropped, but you wouldn't be able to create it with the correct oid since you cannot directly insert a certain oid or update that column.
You could dump the whole database cluster with pg_dumpall, create a new cluster with initdb and restore the backup there, but this might fail because of the data inconsistencies.
Really, the best thing is to restore a backup.
I was able to perform a partial restore using the pg_dirtyread extension.
Initial situation was:
relation "messed_table" does not exist`
The following query provided me the values I had dropped:
SELECT * FROM pg_dirtyread('pg_class'::regclass)
as t(relname name, relnamespace oid, reltype oid, reloftype oid, relowner oid, relam oid, relfilenode oid, reltablespace oid, relpages integer, reltuples real, relallvisible integer, reltoastrelid oid, relhasindex boolean, relisshared boolean, relpersistence "char", relkind "char", relnatts smallint, relchecks smallint, relhasoids boolean, relhaspkey boolean, relhasrules boolean, relhastriggers boolean, relhassubclass boolean, relrowsecurity boolean, relforcerowsecurity boolean, relispopulated boolean, relreplident "char", relispartition boolean, relfrozenxid xid, relminmxid xid, relacl aclitem[], reloptions text[], relpartbound pg_node_tree)
WHERE relname = 'messed_table';
I used the result for performing an INSERT:
INSERT INTO pg_class
(relname,relnamespace,reltype,reloftype,relowner,relam,relfilenode,reltablespace,relpages,reltuples,relallvisible,reltoastrelid,relhasindex,relisshared,relpersistence,relkind,relnatts,relchecks,relhasoids,relhaspkey,relhasrules,relhastriggers,relhassubclass,relrowsecurity,relforcerowsecurity,relispopulated,relreplident,relispartition,relfrozenxid,relminmxid,relacl,reloptions,relpartbound)
VALUES('messed_table',16447,17863,0,10,0,17861,0,0,0,0,0,false,false,'p','r',78,0,false,false,false,false,false,false,false,true,'d',false,1129231::text::xid,1::text::xid,null,null,null);
At this stage executing a SELECT * from messed_table returned
catalog is missing 78 attribute(s) for relid 26130
So I created a new table messed_table_copy having the same structure of the messed table.
I exported to a file the pg_attribute content for the messed_table_copy table using this query:
Copy (SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid from pg_class WHERE relname LIKE 'messed_table_copy') and attnum > 0) To '/tmp/recover.csv' With CSV DELIMITER ',' HEADER;
I changed the attrelid value to the relid value pointed out in the error message and I imported the data from the file again:
COPY pg_attribute(attrelid,attname,atttypid,attstattarget,attlen,attnum,attndims,attcacheoff,atttypmod,attbyval,attstorage,attalign,attnotnull,atthasdef,attidentity,attisdropped,attislocal,attinhcount,attcollation,attacl,attoptions,attfdwoptions) FROM '/tmp/recover.csv' DELIMITER ',' CSV HEADER;
At this stage SELECT count(*) FROM messed_table worked but a SELECT * FROM messed_table crashed the database with the following error:
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
Performing some queries specifying only a subset of all the available columns I noticed that only selecting certain columns a crash happened. I had been able to recover about 90% of the data, losing the content of some columns. Good luck and remember to never play with the pg_class table again.

Extended Events - building a histogram of servers that connect with a particular Application Name?

I'm trying to build an XE in order to find out which of our internal apps (that don't have app names and thus show up as .Net SQLClient Data Provider) are hitting particular servers. Ideally, I'd like to get the name of the Client and Database , but not sure if I can do that in one XE.
I figured for ease of use, I'd use a histogram/asynchronous_bucketizer, and save counts of what's trying to hit and how often. However, I can't seem to get it work on 2012, much less 2008. If I use sqlserver.existing_connection it works, but only gives me the count when it connects. I want to get counts during the day and see how often it occurs from each server, so I tried preconnect_completed. Is this the right event?
Also, and part of the reason I'm using XE, is that those servers can get thousands of calls a minute.
Here's what I've come up with thus far, which works but only gives me current SSMS connections that match - obviously, I'll change that to the .Net SQLClient Data Provider.
CREATE EVENT SESSION UnknownAppHosts
ON SERVER
ADD EVENT sqlserver.existing_connection(
ACTION(sqlserver.client_hostname)
WHERE ([sqlserver].[client_app_name] LIKE 'Microsoft SQL Server Management%')
)
ADD TARGET package0.histogram
( SET slots = 50,
filtering_event_name='sqlserver.existing_connection',
source_type=1,
source='sqlserver.client_hostname'
)
WITH(MAX_DISPATCH_LATENCY =1SECONDS);
GO
Aha! It's login, not preconnect_starting or preconnect_completed.
CREATE EVENT SESSION UnknownAppHosts
ON SERVER
ADD EVENT sqlserver.login(
ACTION(sqlserver.client_hostname)
WHERE ([sqlserver].[client_app_name] LIKE 'Microsoft SQL Server Management%')
)
ADD TARGET package0.histogram
( SET slots = 50,
filtering_event_name='sqlserver.login',
source_type=1,
source='sqlserver.client_hostname'
)
WITH(MAX_DISPATCH_LATENCY =1SECONDS);
GO
Then to query it, some awesome code I made horrid:
-- Parse the session data to determine the databases being used.
SELECT slot.value('./#count', 'int') AS [Count] ,
slot.query('./value').value('.', 'varchar(20)')
FROM
(
SELECT CAST(target_data AS XML) AS target_data
FROM sys.dm_xe_session_targets AS t
INNER JOIN sys.dm_xe_sessions AS s
ON t.event_session_address = s.address
WHERE s.name = 'UnknownAppHosts'
AND t.target_name = 'Histogram') AS tgt(target_data)
CROSS APPLY target_data.nodes('/HistogramTarget/Slot') AS bucket(slot)
ORDER BY slot.value('./#count', 'int') DESC

Who was the last to modify a database object?

This article describes how to run a standard report to display recent DDL changes.
If the data is captured, it's probably in a table somewhere. I would like to Trace this location so I can construct my own reports.
Is this possible?
Option #1
select * FROM sys.traces where is_default = 1 ;
This query contains path column. Copy the path of your trace file and now use the below query
SELECT * FROM fn_trace_gettable('Path Column value from sys.traces', default)
Which Table(Object) is modified and Who Modified ?
select ObjectName, LoginName
from ::fn_trace_gettable( 'Path Column value from sys.traces', default)
where EventClass in (46,47,164) and EventSubclass = 0
and DatabaseID = db_id() ;
select ObjectName,
ObjectID,
DatabaseName,
StartTime,
EventClass,
EventSubClass,
ObjectType,
ServerName,
LoginName,
NTUserName,
ApplicationName
from ::fn_trace_gettable( 'Trace File Path', default )
where EventClass in (46,47,164) and EventSubclass = 0 and DatabaseID = db_id();
Option #2
SQL Server – Auditing Schema Changes using DDL Triggers
This approach will tell which column was added, or what command was used to add

Resources