Why does ALTER INDEX block system tables? - sql-server

When I run a simple alter non clustered column stored index query on table dbo.SampleDataTable (>50 million records):
ALTER INDEX CCI_SampleDataTable
ON dbo.SampleDataTable REBUILD
it blocks system tables INFORMATION_SCHEMA.ROUTINES and INFORMATION_SCHEMA.PARAMETERS.
The problem is our Reporting Server - Tableau Server. When user runs Tableau Report which uses a stored procedure in the database as a data source, Tableau Server sends this query to the database:
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES R
JOIN INFORMATION_SCHEMA.PARAMETERS P ON R.SPECIFIC_SCHEMA = P.SPECIFIC_SCHEMA
AND R.SPECIFIC_NAME = P.SPECIFIC_NAME
AND R.ROUTINE_TYPE = 'PROCEDURE'
AND R.ROUTINE_SCHEMA <>'SYS'
and this query will be blocked when the ETL Process run ALTER INDEX QUERY.
Because that is the internal query from Tableau, I can't modify it with NOLOCK.
As far as I know, when ALTER INDEX runs, the system tables will be updated in real time therefore it will be blocked.
This problem of the system tables is very bad for us because the user can't access to report sometime.
Can you please help me with this problem? What should I do?
The stored procedure which is used by Tableau Report is very simple:
CREATE PROCEDURE SelectAllCustomers
#CustName VARCHAR(MAX)
AS
SELECT *
FROM dbo.SampleDataTable
WHERE CustName =#CustName
GO;

Related

Remote Call Compiles SPROC differently to local, causes error

I have a stored proc that returns details of SQL Agent Jobs on the local server. There is a master script that calls this proc, using OPENQUERY, against every SQL server in the ecosystem. In pseudocode, the master script looks something like this:
FOR EACH #LinkedServer in the list
SET #SQL = 'INSERT #Results SELECT * FROM OPENQUERY(' + #LinkedServer + ',''EXEC ScriptToGetAgentJobInfo'')'
EXEC sp_executesql #SQL
NEXT #LinkedServer
Some of the agent jobs are created from SSRS report subscriptions, so they have horrible looking names. In order to replace them with the name of the report that is the target of the subscription, I appeal to the ReportServer database on the #LinkedServer, as part of the ScriptToGetAgentJobInfo.
However, not every server contains a ReportServer database, so sometimes this appeal would fail. To get round that failure, I have the following lines of script:
DECLARE #Reports TABLE
( AgentJob SYSNAME
,Reportname NVARCHAR(128));
IF EXISTS(SELECT 1 FROM [master].[dbo].sysdatabases WHERE [name] = 'ReportServer')
BEGIN;
INSERT #Reports(AgentJob,Reportname)
SELECT Job.job_id, Report.[Name]
FROM
ReportServer.dbo.ReportSchedule AS ReportSched
INNER JOIN dbo.sysjobs AS Job ON CONVERT(SYSNAME,ReportSched.ScheduleID) = Job.[name]
INNER JOIN ReportServer.dbo.Subscriptions AS Subscription ON ReportSched.SubscriptionID = Subscription.SubscriptionID
INNER JOIN ReportServer.dbo.[Catalog] AS Report ON Subscription.report_oid = Report.itemid;
END;
The idea is that if the reportserver database doesn't exist, I can avoid any calls to it, which would error, but if it does, I can get data from it. I then join the #Reports table to my SQL Agent job query with a LEFT JOIN to show the name of the relevant report if there is one.
All this works fine when I run the script locally, but when it is called through the master procedure, I get an error saying Invalid object name 'ReportServer.dbo.ReportSchedule'.
I can get round this problem by making the reportserver select statement "dynamic" (although it is totally static) and calling it with another sp_executesql call, but I really hate doing this!
So my question is this: Why does the error only occur when calling the script remotely and how can I avoid it without recourse to dynamic sql?
The master script is written and run in SQL Server 14.0, while the linked server that is causing the problem is only on SQL Server 10.50.

How to find/see tempdb in SQL Server

Should I expect to be able to see tempdb tables in SSMS?
e.g. If I run this code, should I expect to be able to see the table in SSMS?
-- Drop the table if it already exists
IF (SELECT OBJECT_ID('tempdb..#TempPasswords')) IS NOT NULL
DROP TABLE #TempPasswords
CREATE TABLE #TempPasswords (
MemberNo INT,
Password nvarchar(120),
NewPassword varbinary(MAX)
)
Only if you run your code snippet in SSMS. In that session you will be able to execute
T-SQL that include your temp table.
In order to see temp tables globally use two hashes ##.
It is possible to see the temp DB but the name only. To see temp DB follow the instruction as per the image. After running the query right click on the Temporary Tables and Refresh .

Where did my new table go

I have a database called mbt. I wanted to write some data from temporary table to real table.
--I used this query.
SELECT * INTO new_table FROM #tmp
when i runned the query it returned normal message.
15813 row(s) affected
After that i checked my tables in mbt database, but i couldn't see 'new_table'
how could such a thing be, where the table might have gone.
I may have forgotten to use 'use MBT' statment at the beginning of the query. Does it make problem
I'm using ms sql server 2014(SP2)(KB3171021)-12.0.5000.0(X64)
ANSWER
It gone to Master DB
select 'master' as DatabaseName,
T.name collate database_default as TableName
from master.sys.tables as T
It Will create a new table on your database. but you did not use so it will store in master database on your server.
Run the query below to find databases which have the object new_table:
sp_MSForEachDB 'Use [?] IF EXISTS (SELECT 1 FROM sys.objects WHERE name= ''new_table'')
SELECT DB_NAME()'
I had the same problem. What i did is, I rewrite the statement of use Database and then refresh the database browser after that i got Result. You can try it. may be it will help you.
Always use command "USE db_name" to make sure that you are querying right database.
Below command will show all databases available on the server.
SHOW DATABASES;
If you are using GUI tool to connect DB server, there is a possibility that at the time of connection you got connected to different DB. If you executed the query to create table and inserted record. These records are inserted in new table in different DB than mbt.

Create table across all schemas at once

Is it possible to create a table across every schema in your database?
Specifically in Oracle.
I do not want to run the exact same query for all existing schemas.
Solution i have been using is,
Use below query to get all schema names,
select distinct owner FROM all_tables;
Get the result and use regular expression to append/prepend your table creation query.
^ - create table
$ - .tablename \( column1 varchar2(10)\);
run all the resulting queries in oracle work sheet.
You can use a bit of PL/SQL and execute immediate to do this.
For example you can create a table in all schemas if you connect as SYS User and execute the following Script:
begin
for cUsers in (select * from dba_users where account_status ='OPEN')
loop
execute immediate 'create table '||cUsers.username||'.myTable ( id number )';
end loop;
end;

How to load a temporary table from SQL Server or Tableau Desktop?

I have three SQL queries results saved in batch in three temporary tables in a SQL Server database but these temp table seems to be not available in tableau while connecting to the database from tableau.
For example:
Create a temp table #p
CREATE TABLE #p
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
Insert values into #p from main table
insert into #p
select *
from Persons
where PersonID in (1, 2, 3);
After connecting to the SQL Server data source in tableau the #p temp table is not showing up in the table list. Is there any possible way I can use the temp table in tableau for dashboard? If not kindly suggest some alternatives on how to make these temp table available in dashboard.
I am struggling to solve this issue for past few days so hope to hear some suggestions from you guys soon..thank you!
Local temporary tables are session-scoped (it means they are only visible in the very same session where they have been generated).
You can try with Global Temporary Tables (SQL Server uses ## in front of their names) or normal tables if you want them to be visible in other sessions...
Both Local and Global Temporary tables will disappear when the session where they have been generated is closed.
Temporary tables(including global temporary tables) will be deleted automatically when no more connections are accessing them. Being said that, there are a couple of ways to achieve what you are trying to do in Tableau.
1. Initial SQL with Temp Table
Tableau has an 'Intial SQL' option that you can select when defining the connection. These statements will be executed every time Tableau make a connection to the server. please note that temporary tables are created in tempdb; so you have to change the database to tempdb. You also have to use fully qualified table name in your SQL. Please pay special attention to the highlighted areas.
2. Stored Procedure
If you have enough access rights, you can create your query as a stored procedure and call it from Tableau. Stored Procedures will be displayed as a separate section under your tables.

Resources