SQL: temp table "invalid object name" after "USE" statement - sql

I do not fully understand the "USE" statement in Transact-SQL and how it affects the scope of temp tables. I have a user-defined table type in one database but not another, and I've found I need to "USE" that database in order to define a table of that type. Earlier in the query, I define a temporary table. After the "USE" statement, SSMS does not recognize the temp table as a valid object name, however I can still query from it without error.
The skeleton of my SQL query is as follows:
USE MYDATABASE1
[... a bunch of code I did not write...]
SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE
USE MYDATABASE2
DECLARE #MYTABLE MyUserDefinedTableType -- this table type only exists in MYDATABASE2
INSERT INTO #MYTABLE(Col1, Col2)
SELECT Col1, Col2 FROM (SELECT * FROM MYDATABASE2.dbo.SOME_TABLE_VALUED_FUNCTION(param1, param2)) T
SELECT A.*, B.Col2
FROM #TEMP_TABLE A
CROSS APPLY DATABASE2.dbo.SOME_OTHER_TABLE_VALUED_FUNCTION(#MYTABLE, A.SomeColumn) B
In the last SELECT statement, SSMS has red squiggly lines under "A.*" and "#TEMP_TABLE", however there is no error running the query.
So my question is: am I doing something "wrong" even though my query still works? Assuming the initial "USE MYDATABASE1" is necessary, what is the correct way to switch databases while still having #TEMP_TABLE available as a valid object name? (Note that moving the definition of #TEMP_TABLE to after "USE MYDATABASE2" would just shift the problem to #SOME_EARLIER_TEMP_TABLE.)

In SQL USE basically tells the query which database is the "default" database.
Temp tables can play tricks on intellisense - unless they're explicitly defined using the CREATE TABLE #MyTempTable route, intellisense doesn't really know what to do with them a lot of the time. Don't worry though - temp tables are scoped to the query.
Although I do feel it's worth pointing out: while UDTs are database specific, you can create an assembly to use across databases

Related

Drop tables using table names from a SELECT statement, in SQL (Impala)?

How do I drop a few tables (e.g. 1 - 3) using the output of a SELECT statement for the table names? This is probably standard SQL, but specifically I'm using Apache Impala SQL accessed via Apache Zeppelin.
So I have a table called tables_to_drop with a single column called "table_name". This will have one to a few entries in it, each with the name of another temporary table that was generated as the result of other processes. As part of my cleanup I need to drop these temporary tables whose names are listed in the "tables_to_drop" table.
Conceptually I was thinking of an SQL command like:
DROP TABLE (SELECT table_name FROM tables_to_drop);
or:
WITH subquery1 AS (SELECT table_name FROM tables_to_drop) DROP TABLE * FROM subquery1;
Neither of these work (syntax errors). Any ideas please?
even in standard sql this is not possible to do it the way you showed.
in standard sql usually you can use dynamic sql which impala doesn't support.
however you can write an impala script and run it in impala shell but it's going to be complicated for such task, I would prepare the drop statement using select and run it manually if this is one-time thing:
select concat('DROP TABLE IF EXISTS ',table_name) dropstatements
from tables_to_drop

VBA Access Table reference in SQL query

I have been running into trouble executing SQL code in VBA Access when I refer to certain Table names.
For example,
INSERT INTO TempTable (ClientName) SELECT DISTINCT 1_1_xlsx.ClientName FROM 1_1_xlsx'<--does not work
The code works fine when I changed the Table name from 1_1_xlsx to Stuff.
INSERT INTO TempTable (ClientName) SELECT DISTINCT Stuff.ClientName FROM Stuff '<--works
I have no idea why the first query results in a syntax error and the second code is runs fine even when they refer to the same thing. I suspect it should be the naming conventions but I could not find any concrete answers.
Also, are there any ways that I could use 1_1_xlsx as my table name? Or am I just writing my query wrong?
try this:
INSERT INTO TempTable (ClientName) SELECT DISTINCT [1_1_xlsx].ClientName FROM [1_1_xlsx]
In many SQL based databases you can't have a table name or field name that starts with a number.
I suspect this is the underlying reason for your problem. Although Access will allow it, I have seen it cause problems in the past.
The problem is the number at the beginning of the table name. That is bad -- because it confuses the parser.
This is a bad table name, but SQL allows you to define table aliases. And, in this case, you don't even need to repeat the table name. So, here are two simple solutions:
INSERT INTO TempTable (ClientName)
SELECT DISTINCT ClientName
FROM 1_1_xlsx;
Or:
INSERT INTO TempTable (ClientName)
SELECT DISTINCT t.ClientName
FROM 1_1_xlsx as t
There is no reason to use the complete table name as an alias. That just makes the query harder to write and to read.

Using table variables in Oracle Stored Procedure

I have lots of experience with T-SQL (MS SQL Server).
There it is quite common to first select some set of records into a
table variable or say temp table t, and then work with this t
throughout the whole SP body using it just like a regular table
(for JOINS, sub-queries, etc.).
Now I am trying the same thing in Oracle but it's a pain.
I get errors all the way and it keeps saying
that it does not recognize my table (i.e. my table variable).
Error(28,7): PL/SQL: SQL Statement ignored
Error(30,28): PL/SQL: ORA-00942: table or view does not exist
I start thinking what at all is possible to do with this
table variable and what not (in the SP body) ?
I have this declaration:
TYPE V_CAMPAIGN_TYPE IS TABLE OF V_CAMPAIGN%ROWTYPE;
tc V_CAMPAIGN_TYPE;
What on Earth can I do with this tc now in my SP?!
This is what I am trying to do in the body of the SP.
UPDATE ( SELECT t1.STATUS_ID, t2.CAMPAIGN_ID
FROM V_CAMPAIGN t1
INNER JOIN tc t2 ON t1.CAMPAIGN_ID = t2.CAMPAIGN_ID
) z
SET z.STATUS_ID = 4;
V_CAMPAIGN is a DB view, tc is my table variable
Presumably you are trying to update a subset of the V_CAMPAIGN records.
While in SQLServer it may be useful to define a 'temporary' table containing the subset and then operate on that it isn't necessary in Oracle.
Simply update the table with the where clause you would have used to define the temp table.
E.g.
UPDATE v_campaign z
SET z.status_id = 4
WHERE z.column_name = 'a value'
AND z.status <> 4
I assume that the technique you are familiar with is to minimise the effect of read locks that are taken while selecting the data.
Oracle uses a different locking strategy so the technique is mostly unnecessary.
Echoing a comment above - tell us what you want to achieve in Oracle and you will get suggestions for the best way forward.

SQL Server : Table instead of very complex view

Normally a full table from a view is created by:
SELECT *
INTO dbo.table
FROM view
But I have a very complex view (which worked in SQL Server 2005), but in SQL Server 2008 Express, I get the error message:
Internal error: An expression services limit has been reached. Please
look for potentially complex expressions in your query, and try to
simplify them.
By eliminating the header <CREATE VIEW viewname AS> I managed to do a normal query.
So I want to copy this query into a new table with all columns of the query.
The query (or the view) consists of 3 tables with a lot of joins and so on.
My question is, how is it possible to get my problem solved?
SELECT *
INTO dbo.table
FROM <here is my complex query, beginning with select>
does not work.
Do it in two steps :
First create your table with the appropriate column names and type.
Use then an INSERT INTO .... SELECT statement like this :
INSERT INTO yourNewTable
(column1,
column2,
...
)
SELECT (your complex query)
Explicitely listing the columns is not mandatory if the result of your query directly match the structure of your target table. Nonetheless it is still advised for maintenability reasons.

Create Microsoft SQL Temp Tables (without declaring columns – like Informix)?

I recently changed positions, and came from an Informix database environment, where I could use SQL statements to select one or more columns ... and direct the output to a temporary table. In Informix, for temp tables, I neither had to declare the column names, nor the column lengths (only the name of a temp table) - I could simply write:
select [columnname1, columnname2, columnname3 ..] from
[database.tablename] where... etc. into temp tablename1 with no log;
Note that in Informix, the temp table stores the column names by default... as well as the data types [by virtue of the data-type being stored in the temp table]. So, if the above statement was executed, then a developer could merely write:
select columname1, columnname2, etc. from tablename1
In my experience, I found this method was very useful - for numerous reasons ('slicing/dicing' the data, using various data sources, etc.)... as well as tremendously fast and efficient.
However, now I am using Microsoft SQL Server, I have not found a way (yet) do the same. In SQL Server, I must declare each column, along with its length:
Create table #tablename1 ( column1 numeric(13,0) );
insert into #tablename1(column1) select [column] from
[database.tablename] where …
[Then use the info, as needed]:
select * from #tablename1 [ and do something...]
Drop table #tablename1
Does anyone know of how I could do this and/or set-up this capability in Microsoft SQL Server? I looked at anonymous tables (i.e. Table-Value constructors: http://technet.microsoft.com/en-us/library/dd776382.aspx)... but the guidance stated that declaring the columns was still necessary.
Thanks ahead of time
- jrd
The syntax is :
select [columnname1], [columnname2], [columnname3] into tablename1 from [database].[schema].[tablename] where...
prefix tablename1 with # if you want the table to be temporary
It should be noted that, while you can use the syntax below:
SELECT col1, col2...
INTO #tempTable1
FROM TABLEA
You should also give your calculated columns names as well.
Such that you get:
SELECT col1, col2...,AVG(col9) AS avgCol9
INTO #tempTable1
FROM TABLEA
Its very simple in sql server as well all you have to do is
SELECT Column1, Column2, Column3,...... INTO #Temp
FROM Table_Name
This statement will Create a Temp Table on fly copying Data and DataType all over to the Temp Table. # sign makes this table a temporary table , you can also Create a Table by using the same syntax but with out the # sign, something like this
SELECT Column1, Column2, Column3,...... INTO New_Table_Name
FROM Table_Name