Select into temp table - sql

how to perform temp table in oracle from below script?
I tried usingselect * into #temp but it does not work. Please assist since i am new in oracle.
select * into temp from
(SELECT
CASE WHEN Aaddress = '16' THEN 'A'
ELSE 'OTHERS'
END AS PRODUCT
FROM NAME
WHERE name.INACTIVE_CODE IN ('1', '2'))

Oracle uses create table as:
create table temp as
SELECT (CASE WHEN Aaddress = '16' THEN 'A' ELSE 'OTHERS' END) AS PRODUCT
FROM NAME
WHERE name.INACTIVE_CODE IN ('1', '2');
Note if either Aaddress or INACTIVE_CODE are numbers, then the constants used for the comparisons should not have single quotes. Don't compare numbers to strings.
In SQL Server, #temp is a temporary table, but temp is not. In Oracle, you need to explicitly declare a temporary table:
create global temporary table temp as

Temporary tables in Oracle are created in advance, so that the definition is known before you use them.
So you could do
create global temporary table temp on commit preserve rows as select ... from ...
but this is not a recommendation to do this every time you run the query. More typical usage is specify the definition once:
create global temporary table temp (
col1 ...
col2 );
and then use INSERT to populate the table as required. By default, ie, as per my latter 'create' statement above, the moment you commit, the rows are lost. If you want to retain the rows after a commit, you add the 'on commit preserve rows' as per my first example. The reason you would have to do this in a create-table-as-select scenario is that otherwise your table would be created, populated with rows, and then immediately emptied as the command completes.

Related

Need help to optimize my stored procedure

I need help optimizing my stored procedure. This is for our fact table, and currently the stored procedure truncates the table, and then loads the data back in. I want to get rid of truncating and instead append new rows or delete rows by a last_update column which currently does not exist. There also is a last_update table with one column, which changes at every stored procedure run, but I'd rather the last_update be a column in the table itself, rather than a separate column.
I've created a trigger that should update the last_updated column with the current date when the stored procedure runs, but I would also like to get rid of truncating and instead append/delete rows as well. The way the stored procedure is currently structured is making it difficult for me to figure out how best to do it.
The stored procedure begins by adding data into 2 temp tables, then adds the data from the two temp tables into a 3rd temp table, then truncates the current FACT TABLE and then the 3rd temp table finally inserts into the FACT table.
--CLEAR LAST UPDATE TABLE
TRUNCATE TABLE ADM.LastUpdate;
--SET NEW LAST UPDATE TIME
INSERT INTO ADM.LastUpdate(TABLE_NAME, UPDATE_TIME)
VALUES('FactBP', CONVERT(VARCHAR, GETDATE(), 100)+' (CST)');
--CHECK TO SEE IF TEMP TABLES EXISTS THEN DROP
IF OBJECT_ID('tempdb.dbo.#TEMP_CARTON', 'U') IS NOT NULL
DROP TABLE #TEMP_CARTON;
IF OBJECT_ID('tempdb.dbo.#TEMP_ORDER', 'U') IS NOT NULL
DROP TABLE #TEMP_ORDER;
--CREATE TEMP TABLES
SELECT *
INTO #TEMP_CARTON
FROM [dbo].[FACT_CARTON_V];
SELECT *
INTO #TEMP_ORDER
FROM [dbo].[FACT_ORDER_V];
--CHECK TO SEE IF DATA EXISTS IN #TEMP_CARTON AND #TEMP_ORDER
IF EXISTS(SELECT * FROM #TEMP_CARTON)
AND EXISTS(SELECT * FROM #TEMP_ORDER)
--CODE HERE joins the data from #TEMP_CARTON and #TEMP ORDER and puts it into a 3rd temp table #TEMP_FACT.
--CLEAR ALL DATA FROM FACTBP
TRUNCATE TABLE dbo.FactBP;
--INSERT DATA FROM TEMP TABLE TO FACTBP
INSERT INTO dbo.FactBP
SELECT
[SOURCE]
,[DC_ORDER_NUMBER]
,[CUSTOMER_PURCHASE_ORDER_ID]
,[BILL_TO]
,[CUSTOMER_MASTER_RECORD_TYPE]
,[SHIP_TO]
,[CUSTOMER_NAME]
,[SALES_ORDER]
,[ORDER_CARRIER]
,[CARRIER_SERVICE_ID]
,[CREATE_DATE]
,[CREATE_TIME]
,[ALLOCATION_DATE]
,[REQUESTED_SHIP_DATE]
,[ADJ_REQ_SHIP]
,[CANCEL_DATE]
,[DISPATCH_DATE]
,[RELEASED_DATE]
,[RELEASED_TIME]
,[PRIORITY_ORDER]
,[SHIPPING_LOAD_NUMBER]
,[ORDER_HDR_STATUS]
,[ORDER_STATUS]
,[DELIVERY_NUMBER]
,[DCMS_ORDER_TYPE]
,[ORDER_TYPE]
,[MATERIAL]
,[QUALITY]
,[MERCHANDISE_SIZE_1]
,[SPECIAL_PROCESS_CODE_1]
,[SPECIAL_PROCESS_CODE_2]
,[SPECIAL_PROCESS_CODE_3]
,[DIVISION]
,[DIVISION_DESC]
,[ORDER_QTY]
,[ORDER_SELECTED_QTY]
,[CARTON_PARCEL_ID]
,[CARTON_ID]
,[SHIP_DATE]
,[SHIP_TIME]
,[PACKED_DATE]
,[PACKED_TIME]
,[ADJ_PACKED_DATE]
,[FULL_CASE_PULL_STATUS]
,[CARRIER_ID]
,[TRAILER_ID]
,[WAVE_NUMBER]
,[DISPATCH_RELEASE_PRIORITY]
,[CARTON_TOTE_COUNT]
,[PICK_PACK_METHOD]
,[RELEASED_QTY]
,[SHIP_QTY]
,[MERCHANDISE_STYLE]
,[PICK_WAREHOUSE]
,[PICK_AREA]
,[PICK_ZONE]
,[PICK_AISLE]
,EST_DEL_DATE
FROM #TEMP_FACT;
Currently, since I've added the last_updated column into my FACT TABLE and created a trigger, I don't actually pass any value via the stored procedure for it, so I get an error
An object or column name is missing or empty.
I am not sure as to where I'm supposed to pass any value for the LAST_UPDATED column.
Here is the trigger I've created for updating the last_updated column:
CREATE TRIGGER last_updated
ON dbo.factbp
AFTER UPDATE
AS
UPDATE dbo.factbp
SET last_updated = GETDATE()
FROM Inserted i
WHERE dbo.factbp.id = i.id
The first thing I would try is to create primary keys on the two temp tables #TEMP_CARTON and #TEMP_ORDER and use the intersect command to get the rows that are common to both tables:
select * from #TEMP_CARTON
intersect
SELECT * FROM #TEMP_ORDER
Figured out the answer. I just had to put "null" for the last_updated value during Insert, and then the Trigger took care of adding the timestamp on its own.

Insert Column with same value

I am running a query on the table "performance" and I want to insert a column with the same value for all the rows without using alter, update etc.
I wrote a case statement and it works but is there a more refined way?
here is a short query:
SELECT id, name, class,
CASE
WHEN id IS NOT NULL THEN 'Actuals'
ELSE 'Forecast'
END AS type
FROM performance
Basically I need all the values to be labeled "Actuals".
There are many other datasets for which I will use different labels and then append all of them
Just to be clear - don't need to update the table performance itself
use common table expression for your case.
It will add new column in your existing data and you may use this for your further process.
For your point it is not adding nor inserting anything in your existing db structure.
with CTE as (
SELECT id, name, class,
CASE WHEN id IS NOT NULL THEN 'Actuals' ELSE 'Forecast' END AS type
FROM table_performance
)
select * from CTE ----- It give you all the columns from [table] and add another column as you needed.
OR
You may create a view for same, if this condition is fixed.

Find columns with NULL values in Teradata

I would like to find the columns in a table that has a null value in it.
Is there a system table that have that information?
To find columns where "null" values are allowed try...
select *
from dbc.columns
where databasename = 'your_db_name'
and tablename = 'your_table_name'
and Nullable = 'Y'
then to identify the specific rows w/ null values, take the "ColumnName" from the previous result set and run queries to identify results... perhaps throw them in a volatile table if you want to take further action on them (update,delete).
-- for example you found out that column "foo" is nullable...
create volatile table isnull_foo_col
as
(
sel *
from your_table_name
where foo is null
) with data
on commit preserve rows;
If you have statistics collected on the column you can use the views found here for Teradata 12.0.03+ and Teradata 13.0.02+ to determine the number of records in the table that have NULL values.
In Teradata 14, if you use the SHOW STATISTICS with the VALUES clause you will get similar information generated by the views listed at the link above.
You can use the DBC.Columns data dictionary view to determine what columns in a particular table are nullable.

Having a same temp table name with 2 different IF statements

I have resolved this problem because I have overlooked something that is already part of my code and this situation is not needed.
In SQL Server 2008, I have two IF statements
If value = ''
begin
select * into #temptable from table 1
end
Else If value <> ''
begin
select * into #temptable from table 2
end
but when I try to execute it gives me because of the second
temptable:
There is already an object named '#temptable' in the database.
I don't want to use another temp table name as I would have to change the after code a lot. Is there a way to bypass this?
I would recommend making some changes so that your code is a little more maintainable. One problem with the way you have it set up here is with the SELECT * syntax you're using. If you later decide to make a change to the schema of table1 or table2, you could have non-obvious consequences. In production code, it's better to spell these things out so that it's clear exactly which columns you're using and where.
Also, are you really using all of the columns from table 1 and table 2 in the code that follows? You might be taking a performance hit loading more data than you need. I'd go through the code that uses #temptable and figure out which columns it's actually using. Then start by creating your temp table:
CREATE TABLE #temptable(col1 int, col2 int, col3 int, col4 int)
Include all of the possible columns that could be used, even if some of them might be null in certain cases. Presumably, the code that follows already understands that. Then you can set up your IF statements:
IF value = ''
BEGIN
INSERT INTO #temptable(col1, col2, col3)
SELECT x,y,z
FROM table1
END
ELSE
INSERT INTO #temptable(col1, col4)
SELECT alpha,beta
FROM table2
END
Your SELECT statement, as written, is creating the temp table and INSERTING into it all in one statement. Create the temp table separately with a CREATE TABLE statement, then INSERT INTO in your two IF statements.
Using SELECT INTO creates the table on the fly, as you know. Even if your query only referenced #temptable once, if you were to run it more than once (without dropping the table after the first run), you would get the same error (although if it were inside a stored procedure, it would probably only exist in the scope of the stored procedure).
However, you can't even compile this query. Using the Parse command (Ctrl+F5) on the following query, for example, fails even though the same table is used as the source table.
select * into #temptable from SourceTable
select * into #temptable from SourceTable
If the structure of tables 1 and 2 were the same, you could do something like the following.
select * into #temptable from
(select * from Table1 where #value = ''
union
select * from Table2 where #value <> '') as T
If, however, the tables have different structures, then I'm not sure what you can do, other than what agt and D. Lambert recommended.

Is there an automated way to create a temp table in SQL Server

I have a rather complex SELECT statement in a stored procedure that I am updating to insert the rows from the select into a temp table. To define the temp table, I need to know the data type of each every item selected.
Is there a easy way (a script maybe) that I can use to determine the data types and the temp table structure instead of going to each table's definition in the select to find out what it is?
PS: I can't use a Common table expression as I need to use this temp table several times within the proc
SELECT
blah
INTO
#temp
FROM
wibble
blah and wibble are not secret syntax. Please replace these with your own SQL :)
SELECT * INTO #temp FROM TABLE1
All columns in TABLE 1 gets into your temp table now