Can't view or edit tempdb in Azure SQL Database - sql

I have a database on Azure using the SQL Database (PaaS) offering.
I can't see or access the tempdb nor can I create it.
If I try to create the database I get the following error:
Msg 1801, Level 16, State 3, Line 10
Database 'tempdb' already exists. Choose a different database name.
Does anyone know what's going on here?

TempDB on Azure SQL Database is created and managed by Azure platform and the TempDB capacity has a limit in size based on the Azure SQL Database tier.
Hope this helps.

I am going to up tick Alberto since he is right about the service handling this system database.
I guess my main question is why are you using [tempdb]?
Before there was a push to the cloud, lazy SQL developers would create tables in [tempdb]. These tables should have been placed into a user defined staging database or schema.
Let's see if local/global temporary tables and user defined tables in [tempdb] are allowed.
-- local temp table
select 'Fee Fie Foo Fumb' as rhymes into #a
go
-- show the data
select * from #a
go
-- show my local tables
select * from tempdb.sys.tables
go
The expected results are shown below. Local and global temp tables are supported.
If we try the following create statement within Azure SQL database, the service is smart enough to know that you can not use [tempdb] directly.
Now, back to my first question.
Why are you trying to use and/or modify [tempdb]??

In rebuttal to Alberto, global temporary tables are now supported in Azure. The database being referenced by the session is a Basic tier (b0) level.

Related

How do you drop a permanent table that has multiple prefixes on a remote server when RPC is disabled

How do you drop a permanent table that has multiple prefixes on a remote server when rpc is disabled in SSMS v18 and above?
This is needed as part of a stored procedure.
First attempt:
drop table if exists [remote_server_name].[remote_db_name].dbo.[test123]
Error message:
The object name 'remote_server_name.remote_db_name.dbo.test123' contains more than the maximum number of prefixes. The maximum is 2.
After googling the issue then tried the below;
Second attempt:
EXECUTE [remote_server_name].[remote_db_name].[dbo].[sp_executesql] N'DROP TABLE [dbo].[test123]'
Error message:
Server 'remote_server_name' is not configured for RPC.
Third attempt:
drop table [remote_server_name].[remote_db_name].dbo.[test123]
Error message:
The object name 'remote_server_name.remote_db_name.dbo.test123' contains more than the maximum number of prefixes. The maximum is 2.
Unfortunately the premise of your entire question is wrong as you cannot use DROP TABLE with non-local databases. While this fact isn't explicitly stated in the documentation but can be inferred from the fact that the syntax for DROP TABLE specifically only supports these three variants:
DROP TABLE [ IF EXISTS ] database_name.schema_name.table_name;
DROP TABLE [ IF EXISTS ] schema_name.table_name;
DROP TABLE [ IF EXISTS ] table_name;
None of the above allow a SQL Server name to be used.
Curiously, the documentation does explicitly say that you cannot use 4-part names in Azure SQL (which to some people might imply that on-prem (non-Azure SQL) does support 4-part names, however the fact is neither edition of SQL Server support 4-part names, and therefore DROP TABLE cannot be used to drop remote tables:
https://learn.microsoft.com/en-us/sql/t-sql/statements/drop-table-transact-sql?view=sql-server-ver15
Azure SQL Database supports the three-part name format database_name.[schema_name].object_name when the database_name is the current database or the database_name is tempdb and the object_name starts with #. Azure SQL Database does not support four-part names.
However, provided that you're using a Linked Server with RPC enabled then you can use EXEC AT. This approach does not work with other types of remote servers, such as OPENROWSET nor when "RPC: False" in Server Options.
EXEC ( 'DROP TABLE dbName.schema.tableName;' ) AT [LinkedServerName];
Otherwise, you cannot directly drop tables in a remote server from within a PROCEDURE.
A hack-ish approach might work whereby you use xp_cmdshell (which is also disabled by default) to run sqlcmd.exe (nee osql.exe) against an arbitrary SQL Server instance - though obviously you need to be ultra-careful with this approach (you'll also need Trusted Security (SSPI) working otherwise you'll need to hard-code a DDL-privileged user's password somewhere, which should be avoided in production systems).

Accessing data from another database in stored procedure

Following is my schema detail:
DB_A : schema_1, schema_2, schema_3
DB_B : schema_3
some procedures in schema_3 access resources(table, view, sp) from schema_1 and schema_2.
All procedures in schema_3 are same on both the dbs. How do I access schema_1 from schema_3 for both the dbs.
Now I can hard code DB_A in my procedures but when I move code to client machine, it will create a problem since DB_A may not be same(one of the reason being client is miser and having QA, Dev and Prod on same machine).
Second option is getting DB_A name as a parameter, but it will make all the schema_3 SPs dynamic (as I did not get any method to access something like #DBName.schema_name.ResourceName).
Third option is creating linked servers, which again do not solve my problem because of same reason as first.
Any idea how to proceed, where I do not want my procedures to be dynamic just because 80% of them are straight.
Edit Start:
So I can restate it as I have multiple databases with a database having resources (table/view/schema) which needs to be shared and then having other databases (one or more) which have stored procedures which computes on data from shared database and self database.
Shared database name is not going to be constant on all the environments and I want to change them(environment specific). I have come out with a solution where I will be creating synonym for all the shared resources and all procedures will be using them, that way they are all referring to shared resources from first database.
For each installation I need to modify synonyms definition to reflect correct share database name. Is there any SYNONYM For Database Name, that way I will have way less synonyms to handle.
Well the best choice I found is as follows.
Create Synonym (independent database DB_B) for individual objects (in shared database DB_A) with same name in same schema. That way your existing procedures need not change, and will work as required. Synonym gives a good reference on this. I will soon be creating an app to ease creating synonyms for these kind of situations.
CREATE SYNONYM DB_B.schema_1.proc_1 FOR DB_A.schema_1.proc_1
You can run your procedure in DB_A and create a view from DB_A to DB_B:
create view dbo.vw_B_Schema_3
as
select *
from DB_B.dbo.Schema_3
You'd have to create three versions of the view (dev, QA, prod.) But the view will be the only difference: procedure definitions can remain identical.
If DB_A and DB_B are on same server, only sure you that the login have permission in two database.
Now, use [database].[schema].[object], when you use object of others database
eg: I have two database, ("helpdesk", "intranet")
from heldesk to intranet
create view dbo.users
as
select login, name, lastname
from intranet.dbo.user // [database].[schema].[object] user is a table in dbo schema from intranet database.
where status = 1
;

MSSQL Import/Export/Copy IDENTITY_INSERT problems

Using MS SQL Server Management Studio 2008.
I have a db (say ip 10.16.17.10 and called db1) and a second one (say ip 10.16.17.25 called db2).
I am trying to copy one table (and its contents) from db1 into db2.
I have the database on both (but empty in db2).
The problem is no matter how I copy/export/import, no matter what options I set in MS SQL Server Management Studio 2008 when I click 'table'->'Design' (on db2) it ALWAYS says 'Identity Spefication: NO' even tho the db1 table has it on.
From db1 I go to 'Tasks'->'export'->'source/db' and 'destination/db'->'Edit Mapping'->'Enable identity Insert' and click it on.
But no joy. ALWAYS exports without it.
I try similar thing from IMPORT on db2. Similar thing if I use COPY.
I have read MANY of the STACKOVERFLOW articles on this, they all suggest setting IDENTITY_INSERT setting to ON but when I do run below:
SET IDENTITY_INSERT [dbo].[mytable] ON
The table either doesn't exist yet or has already copied WITHOUT the identity setting on so see the error:
does not have the identity property. Cannot perform SET operation.
I have tried setting it as a property (under database properties) for db2 but when I copy/import/export never works.
Would appreciate any help here as lots of StackOverflow articles so far all seem to be having an easier time than me.
I am planning on doing this for another 50 or so tables in this database so am hoping to find a way which doesnt involve running scripts for each table.
thanks
The process of using the Export Data Wizard to copy the data from one table to another will NOT replicate all aspects of the schema (like identity and auto-increment). If you want to replicate the schema, script out your table into a create statement, change the name to db2, and create it. Then you should be able to run the export/import wizard with the identity insert option on and insert into your new table that replicates the schema of your old table.
Ended up sorting this out using MS SQL Management Studio.
Thanks to #kevin for the help regarding Import Data and Export Data. Schemas are NOT transferred across however they are the best means to transport the data once schema is up.
Found best way to MASS import/export db table schemas using below (Saved SQL create scripts to file):
Tasks->Generate Scripts->All Tables To File->with Identity on
Ran 200kb SQL file on db2 for schema.
Then ran Import Data from db1 to db2.
Done, all Identity_Inserts maintained.
thanks for help
According to the Error message I think your table does not have an IDENTITY column. Make sure that [dbo].[mytable] does have an IDENTITY column before you executing SET IDENTITY_INSERT.
SET IDENTITY_INSERT [dbo].[mytable] ON
DEMO1 (Trying to set identity ON when there is NO identity column)
--Error
'Table 'T' does not have the identity property. Cannot perform SET operation.: SET IDENTITY_INSERT T ON'
DEMO2 (Trying to set identity ON when there is identity column)
--No Errors
Follow following Steps :
From db1 I go to 'Tasks'->'export'->'source/db' and 'destination/db'->'Edit Mapping'->'Enable identity Insert' and Edit SQL - > You will able to see query structure of Table.
IN the query for eg. ID int NOT NULL, do the next step ID int NOT NULL IDENTITY(1,1)
Then proceed.
I bet it will work.

When is the temporary database used?

I've been told that RDBMS ( SQL Server in this case ) make use of the temporary database to perform its internal job, for instance when a SELECT count( column ) FROM foo query is performed.
What kind of queries / statements trigger the use of the temporary database?
background:
We are currently about to change the collation on our application database, but we have been told there might be problems if that database make use of the temporary database, because they will have different collation. The rationale is the temporary database is already being used by other applications.
So we want to identify what kind of queries may trigger temp db usage and see if they'll have any problem.
I've found this about when is the db used:
http://msdn.microsoft.com/en-us/library/ms190768.aspx

How tempDB works?

I am trying to understand the tempDB and following are the doubts popping in my mind.
What is the lifetime of data in tempDB? Say a query is doing some Order By and uses tempDB for performing that. After this query finishes, someone else also executes a query which utilizes the tempDB. Will the second query find records written by first query in the tempDB or will they be deleted?
Are there any visible tables created inside the tempDB by the Sql Engine? How can I know which temporary table is created because of this query? Is there any naming convention followed by the Sql engine for naming these temporary tables?
I am new to tempDB so please pardon me for asking such silly (if at all) questions :-)
It will be very nice if someone can point me to a good resource which can help me learn about tempDB.
Temp table is stored in tempdb until the connection is dropped (or in the case of a global temp tables when the last connection using it is dropped). You can also (and it is a good practice to do so) manually drop the table when you are finished using it with a drop table statement.
No, others cannot see your temp tables if they are local temp tables (They can see and use global temp tables) Multiple people can run commands which use the same temp table name but they will not be overlapping in a local temp table and so you can have a table named #test and so can 10,000 other users, but each one has its own structure and data.
You don't want to generally look up temp tables in tempdb. It is possible to check for existence, but that is the only time I have ever referenced tempdb directly. Simply use your temp table name. Example below of checking for existence
IF OBJECT_ID('TempDB.dbo.#DuplicateAssignments') IS NOT NULL
BEGIN
DROP TABLE #DuplicateAssignments
END
You name temp tables by prefacing the name with # (for local tables the ones you would use 999.9% of the time) and ## for global temp tables, then the rest of the name you want.
There's a few MSDN articles that are probably the best source of information on the tempDB database in SQL Server.
tempdb Database
The tempdb system database is a global
resource that is available to all
users connected to the instance of SQL
Server and is used to hold the
following:
Temporary user objects that are explicitly created, such as: global or
local temporary tables, temporary
stored procedures, table variables, or
cursors.
Internal objects that are created by the SQL Server Database Engine, for
example, work tables to store
intermediate results for spools or
sorting.
Row versions that are generated by data modification transactions in a
database that uses read-committed
using row versioning isolation or
snapshot isolation transactions.
Row versions that are generated by data modification transactions for
features, such as: online index
operations, Multiple Active Result
Sets (MARS), and AFTER triggers.
Operations within tempdb are minimally
logged. This enables transactions to
be rolled back. tempdb is re-created
every time SQL Server is started so
that the system always starts with a
clean copy of the database. Temporary
tables and stored procedures are
dropped automatically on disconnect,
and no connections are active when the
system is shut down. Therefore, there
is never anything in tempdb to be
saved from one session of SQL Server
to another. Backup and restore
operations are not allowed on tempdb.
There's also tempdb and Index Creation, this blog post along with Working with tempdb in SQL Server 2005 which states:
The SQL Server system database, tempdb, has undergone a number of changes in SQL Server 2005. There are new tempdb usages and internal optimizations in SQL Server 2005; tempdb architecture is mostly unchanged since SQL Server 2000.
The tempdb system database is very similar to a user database. The main difference is that data in tempdb does not persist after SQL Server shuts down.
The temporary tables created in TempDB are dropped when the query is completed.
I'm not sure on this (I would have to try it), but I think theoretically ALL tables created in TempDB are visible, although only the user that created the table has permission to access it.